亚洲春色中文字幕久久久-三上亚,91精品国产亚一区二区三区,久久久九色综合亚洲成色777,涩涩视频下载,国产午夜亚洲精品午夜鲁丝片,国产精品A一区二区三区腾讯导航,影音先锋色情AV在线看片,蜜臀国产在线视频,极品少妇高潮啪啪无码吴梦梦 ,精品人妻无码一区二区三区手机版

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1795|回復: 20
打印 上一主題 下一主題
收起左側

九齊NY8A051H單片機程序,大佬幫忙看看,燈效進行不下去

[復制鏈接]
跳轉到指定樓層
樓主
ID:1077269 發表于 2025-8-2 11:11 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
這是我寫的一個按鍵切換3顆LED燈的燈光效果代碼,想要實現的效果是,按下開關,實現燈效:
(1)3顆LED燈全亮;
(2)3顆LED燈全亮2秒,全滅2秒,循環;
(3)只有1號燈亮2秒,接著,只有2號燈亮2秒,最后只有3號燈亮2秒,循環;
(4)3顆LED燈全滅,進入睡眠;
全局效果:當有LED燈點亮時,開始倒計時30分鐘,期間沒有按下開關,LED燈全滅,IC進入睡眠,等待開關喚醒。

目前我的代碼只能在兩個燈效之間切換,無法做的4個燈效切換,而且延時30分鐘效果不知道怎么進行,求大佬幫忙完善一下!!!

按鍵切換3燈燈效.docx

12.75 KB, 下載次數: 0

代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1089588 發表于 2025-8-4 14:14 | 只看該作者
有開總中斷嗎,你的delay要2000
回復

使用道具 舉報

板凳
ID:1157445 發表于 2025-8-4 15:51 | 只看該作者
按鍵部分的問題:1、按下以后Mod會一直加,最好是識別到彈起再加一;2、Mod等于4就置零需要寫在Mod++后面,且最好是大于等于4;3、switch增加default。
回復

使用道具 舉報

地板
ID:1073939 發表于 2025-8-8 13:33 | 只看該作者
代碼結構有問題。你這種軟件延時在代碼更改工作模式后還是會繼續延時,不會立即按新模式進行。要以狀態機的方式組織代碼。
回復

使用道具 舉報

5#
ID:1077269 發表于 2025-8-12 12:00 | 只看該作者
a825563619 發表于 2025-8-4 14:14
有開總中斷嗎,你的delay要2000

delay時間長了,watchdog 重置了,燈一直頻閃,現在不知道怎么操作,剛接觸這款單片機,大佬能不能幫我改一下?
回復

使用道具 舉報

6#
ID:1077269 發表于 2025-8-12 12:03 | 只看該作者
檸檬脆片 發表于 2025-8-4 15:51
按鍵部分的問題:1、按下以后Mod會一直加,最好是識別到彈起再加一;2、Mod等于4就置零需要寫在Mod++后面, ...

按鍵部分我是沿用官方示例代碼的,應該不會出錯,我現在嘗試一下default語句
回復

使用道具 舉報

7#
ID:1077269 發表于 2025-8-12 12:05 | 只看該作者
ydatou 發表于 2025-8-8 13:33
代碼結構有問題。你這種軟件延時在代碼更改工作模式后還是會繼續延時,不會立即按新模式進行。要以狀態機的 ...

不太明白是什么意思,我剛接觸單片機,網上都說九齊的容易學,大佬能不能幫我改一下?
回復

使用道具 舉報

8#
ID:1073939 發表于 2025-8-16 14:56 | 只看該作者
setsu 發表于 2025-8-12 12:05
不太明白是什么意思,我剛接觸單片機,網上都說九齊的容易學,大佬能不能幫我改一下?

暫時用你的軟延時改了下。代碼中不要有長時間(大于10毫秒)延時,中斷中延時不要超過10us。
回復

使用道具 舉報

9#
ID:1077269 發表于 2025-8-16 15:30 | 只看該作者
ydatou 發表于 2025-8-16 14:56
暫時用你的軟延時改了下。代碼中不要有長時間(大于10毫秒)延時,中斷中延時不要超過10us。

能發出來看看嗎?
回復

使用道具 舉報

10#
ID:1073939 發表于 2025-8-16 15:58 | 只看該作者
setsu 發表于 2025-8-12 12:05
不太明白是什么意思,我剛接觸單片機,網上都說九齊的容易學,大佬能不能幫我改一下?

用你的軟延時做了個狀態機。
以后編程要注意幾點:
1.中斷中延時不要超過10uS,不要做復雜運算。
2.不要使用超過20mS的延時,如有超過,請用狀態機實現。
3.多使用標志。
4.其中10ms延時要用定時器實現。
  1. #include <ny8.h>
  2. #include "ny8_constant.h"
  3. #include "stdint.h"
  4. #define UPDATE_REG(x) __asm__("MOVR _" #x ",F")
  5. #define unchar unsigned char
  6. #define unint unsigned int

  7. unchar myvar; // 九齊單片機位定義,將一個char拆成8個bit變量
  8. __sbit key = PORTB : 0;
  9. __sbit light1 = PORTB : 1;
  10. __sbit light2 = PORTB : 2;
  11. __sbit light3 = PORTB : 4;
  12. #define light_get() (((PORTB >> 1) & 7) ? 1 : 0)
  13. #define light_set(x)             \
  14.         do                           \
  15.         {                            \
  16.                 PORTB &= 0xf1;           \
  17.                 PORTB |= ((x) & 7) << 1; \
  18.         } while (0)(PORTB |= 0x1 << x)

  19. unint Mod = 3;
  20. unint ModCnt = 0; // 計時,每10mS加1

  21. unchar keyFlag = 0;
  22. unchar keyCnt = 0; // 計時,每10mS加1

  23. unint sleepCnt = 0; // 計時,每10mS加1

  24. void delay(unint z) // 延時函數ms
  25. {
  26.         unint x, y;
  27.         for (x = z; x > 0; x--)
  28.                 for (y = 100; y > 0; y--)
  29.                         ;
  30. }
  31. void keyProc(void) // 按鍵處理函數,每10mS調用一次
  32. {
  33.         unchar i = key ? 1 : 0;
  34.         if (++keyCnt == 0)
  35.                 keyCnt--;
  36.         if (i == 0) // 按鍵按下
  37.         {
  38.                 if (keyFlag)
  39.                         keyCnt = 0;         // 按鍵按下計時開始
  40.                 if (keyCnt == 2) // 消抖
  41.                 {
  42.                         ModCnt = 0;
  43.                         if (++Mod == 4)
  44.                                 Mod = 0;
  45.                 }
  46.                 sleepCnt = 0;
  47.         }
  48.         else
  49.         {
  50.                 if (keyFlag == 0)
  51.                 {
  52.                         // 松手檢測,如有松手要處理的代碼寫在這里
  53.                         sleepCnt = 0;
  54.                 }
  55.         }
  56.         keyFlag = i;
  57. }
  58. void ModProc(void)
  59. {
  60.         switch (Mod)
  61.         {
  62.         case 3: // 燈全滅
  63.                 if (ModCnt == 0)
  64.                         light_set(0);
  65.                 SLEEP(); // LED燈全滅,IC進入睡眠
  66.                 break;
  67.         case 0: // 燈全亮
  68.                 if (ModCnt == 0)
  69.                         light_set(7);
  70.                 break;
  71.         case 1: // 燈1亮 2秒,接著燈2亮 2秒,燈3亮 2秒
  72.                 if (ModCnt == 0 || ModCnt >= 600)
  73.                 {
  74.                         ModCnt = 0;
  75.                         light_set(1);
  76.                 }
  77.                 else if (ModCnt == 200)
  78.                         light_set(2);
  79.                 else if (ModCnt == 400)
  80.                         light_set(4);
  81.                 break;
  82.         case 2: // 燈全亮2秒,全滅兩秒
  83.                 if (ModCnt == 0 || ModCnt >= 400)
  84.                         light_set(7);
  85.                 else if (ModCnt == 200)
  86.                         light_set(0);
  87.                 break;
  88.         default:
  89.                 Mod = 3;
  90.                 ModCnt = -1;
  91.                 break;
  92.         }

  93.         if (++sleepCnt >= 30 * 60 * 100) // 30分鐘
  94.         {
  95.                 light_set(0);
  96.                 SLEEP(); // 點亮30分鐘期間沒有按下開關(按下會使sleepCnt清零),IC進入睡眠
  97.         }
  98. }

  99. void isr(void) __interrupt(0)
  100. {
  101.         // if(INTFbits.INTIF)
  102.         //{
  103.         //        //INTF = (unsigned char)~(C_INT_EXT);
  104.         //}

  105.         if (INTFbits.PBIF)
  106.         {
  107.                 INTFbits.PBIF = 0;
  108.                 sleepCnt = 0;
  109.         }
  110. }

  111. void lnit_Timer() // 中斷初始化
  112. {
  113.         DISI();                                // 禁用中斷
  114.         INTE = C_INT_PBKey; // 啟用PB按鍵中斷
  115.         ENI();                                // 啟用中斷
  116. }

  117. void lnit_Mod()
  118. {
  119.         BPHCON = (unsigned char)~(C_PB0_PHB); // 開啟B0口上來電阻
  120.         BWUCON = C_PB0_Wakeup;                                  // 啟用PB0輸入喚醒功能
  121.         IOSTB = C_PB0_Input;
  122.         PORTB = 0x00;
  123. }

  124. void main(void)
  125. {
  126.         lnit_Mod();
  127.         lnit_Timer();
  128.         Mod = 0;
  129.         key = 1;
  130.         while (1)
  131.         {
  132.                 CLRWDT();
  133.                 delay(1); // 10mS,最好用定時器代替延時函數。
  134.                 keyProc();
  135.                 ModProc();
  136.         }
  137.         // while (1)
  138.         // {
  139.         //         if (gb10ms_flag) // 定時器中斷使 gb10ms_flag=1
  140.         //         {
  141.         //                 gb10ms_flag = 0;
  142.         //                 CLRWDT();
  143.         //                 keyProc();
  144.         //                 ModProc()
  145.         //         }
  146.         // }
  147. }
復制代碼



評分

參與人數 1黑幣 +100 收起 理由
admin + 100 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

11#
ID:1073939 發表于 2025-8-16 16:32 | 只看該作者
代碼中有處錯誤:sleepCnt最大值為65535,而30分鐘為180000次10ms。
還要加一個變量。

  1.         if (++ModCntL >= 100)//秒
  2.         {
  3.                 ModCntL = 0;
  4.                 if (++sleepCnt >= 30 * 60) // 30分鐘
  5.                 {
  6.                         light_set(0);
  7.                         SLEEP(); // 點亮30分鐘期間沒有按下開關(按下會使sleepCnt清零),IC進入睡眠
  8.                 }
  9.         }
復制代碼
回復

使用道具 舉報

12#
ID:1077269 發表于 2025-8-18 11:12 | 只看該作者
ydatou 發表于 2025-8-16 15:58
用你的軟延時做了個狀態機。
以后編程要注意幾點:
1.中斷中延時不要超過10uS,不要做復雜運算。

#define light_set(x)             \
        do                           \
        {                            \
                PORTB &= 0xf1;           \
                PORTB |= ((x) & 7) << 1; \
        } while (0)(PORTB |= 0x1 << x)
大佬,這個位置編譯報錯,是不是九齊用不了do while語句啊?
回復

使用道具 舉報

13#
ID:1077269 發表于 2025-8-18 11:19 | 只看該作者
ydatou 發表于 2025-8-16 15:58
用你的軟延時做了個狀態機。
以后編程要注意幾點:
1.中斷中延時不要超過10uS,不要做復雜運算。

  case 1: // 燈1亮 2秒,接著燈2亮 2秒,燈3亮 2秒
                if (ModCnt == 0 || ModCnt >= 600)
                {
                        ModCnt = 0;
                        light_set(1);
                }
                else if (ModCnt == 200)
                        light_set(2);
                else if (ModCnt == 400)
                        light_set(4);
                break;
現在報錯提示是第二個else之前出現語法錯誤,不知道哪里出錯了。。。
回復

使用道具 舉報

14#
ID:1077269 發表于 2025-8-18 16:24 | 只看該作者
ydatou 發表于 2025-8-16 15:58
用你的軟延時做了個狀態機。
以后編程要注意幾點:
1.中斷中延時不要超過10uS,不要做復雜運算。

目前我把一些編譯報錯都給改了,現在就剩一個“內存地址重迭 0x10~0x12”,沒找到哪里導致的
回復

使用道具 舉報

15#
ID:1077269 發表于 2025-8-19 00:17 | 只看該作者
setsu 發表于 2025-8-18 16:24
目前我把一些編譯報錯都給改了,現在就剩一個“內存地址重迭 0x10~0x12”,沒找到哪里導致的

這是這顆IC的規格書0x10~0x12重迭,可是這不是通用寄存器嗎?

NY8A051H_v2.0_SC.pdf

1.89 MB, 下載次數: 0

回復

使用道具 舉報

16#
ID:1073939 發表于 2025-8-19 08:39 | 只看該作者
setsu 發表于 2025-8-18 11:12
#define light_set(x)             \
        do                           \
        {              ...

改成這樣
  1. #define light_set(x)             \
  2.         do                           \
  3.         {                            \
  4.                 PORTB &= 0xf1;           \
  5.                 PORTB |= ((x) & 7) << 1; \
  6.         } while (0)
復制代碼
回復

使用道具 舉報

17#
ID:1073939 發表于 2025-8-19 08:42 | 只看該作者
setsu 發表于 2025-8-18 11:19
case 1: // 燈1亮 2秒,接著燈2亮 2秒,燈3亮 2秒
                if (ModCnt == 0 || ModCnt >= 600 ...

應該是上一個錯誤所致。light_set(x) 的定義改了就好
回復

使用道具 舉報

18#
ID:1073939 發表于 2025-8-19 08:47 | 只看該作者
setsu 發表于 2025-8-18 16:24
目前我把一些編譯報錯都給改了,現在就剩一個“內存地址重迭 0x10~0x12”,沒找到哪里導致的

把代碼中的臨時變量改成全局變量試試。這款芯片象微芯的,對C語言支持不夠。
回復

使用道具 舉報

19#
ID:1073939 發表于 2025-8-19 08:50 | 只看該作者
setsu 發表于 2025-8-19 00:17
這是這顆IC的規格書0x10~0x12重迭,可是這不是通用寄存器嗎?

組織下全局變量順序,16bit變量在前面,8bit變量安排在后面。
  1. unchar myvar; // 九齊單片機位定義,將一個char拆成8個bit變量
  2. __sbit key = PORTB : 0;
  3. __sbit light1 = PORTB : 1;
  4. __sbit light2 = PORTB : 2;
  5. __sbit light3 = PORTB : 4;
  6. #define light_get() (((PORTB >> 1) & 7) ? 1 : 0)
  7. #define light_set(x)             \
  8.         do                           \
  9.         {                            \
  10.                 PORTB &= 0xf1;           \
  11.                 PORTB |= ((x) & 7) << 1; \
  12.         } while (0)(PORTB |= 0x1 << x)

  13. unint Mod = 3;
  14. unint ModCnt = 0; // 計時,每10mS加1

  15. unchar keyFlag = 0;
  16. unchar keyCnt = 0; // 計時,每10mS加1

  17. unint sleepCnt = 0; // 計時,每10mS加1
復制代碼
回復

使用道具 舉報

20#
ID:1077269 發表于 2025-8-22 01:15 | 只看該作者
ydatou 發表于 2025-8-19 08:50
組織下全局變量順序,16bit變量在前面,8bit變量安排在后面。

不行啊,一直提示內存地址重迭0x10~0x12,這是什么原因導致的?
回復

使用道具 舉報

21#
ID:1073939 發表于 2025-8-22 14:29 | 只看該作者
你這問題應該是九齊mcu特有的,要去找九齊的fae咨詢。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表