久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機ws2812程序無法用按鍵控制?

[復制鏈接]
跳轉到指定樓層
樓主
ID:190152 發表于 2024-1-2 12:22 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
這個是用別人的程序修改的,現在遇到幾個問題。外部中斷接的開機按鍵需要按幾次才能開機。按鍵左和按鍵右無法控制切換流水燈模式

單片機源程序如下:
  1. #include<STC8Hxxx.h>
  2. #include"intrins.h"

  3. sbit WS2812 = P3^2;
  4. sbit Power= P1^0;//ws2812電源開關
  5. sbit key_left= P2^0;//按鍵左
  6. sbit key_right= P2^1;//按鍵右
  7. sbit key_ok= P2^2;//按鍵確認
  8. sbit key_Return= P2^3;//按鍵返回



  9. #define numLEDs 64  //燈的個數

  10. unsigned char buf_R[numLEDs] = {0};//顏色緩存
  11. unsigned char buf_G[numLEDs] = {0};
  12. unsigned char buf_B[numLEDs] = {0};
  13. unsigned char Timer0_cnt=0;//記錄定時器0中斷次數
  14. unsigned char list=1;//播放列表

  15. void RGB_Set_Up();  //送0碼
  16. void RGB_Set_Down(); //送1碼
  17. void Timer0_Init();//按鍵掃描定時器0初始化
  18. void key_service();//按鍵服務程序
  19. //void playlist(unsigned char list);



  20. //真對 STC8系列 IO口初始化 準雙向
  21. void IO_init(void)
  22. {

  23.   P0M0 = 0X00;
  24.   P0M1 = 0X00;

  25.   P1M0 = 0X01;
  26.   P1M1 = 0X00;

  27.   P2M0 = 0X00;
  28.   P2M1 = 0X00;

  29.   P3M0 = 0X00;
  30.   P3M1 = 0X00;

  31.   P4M0 = 0X00;
  32.   P4M1 = 0X00;

  33.   P5M0 = 0X00;
  34.   P5M1 = 0X00;
  35. }


  36. void HAL_Delay(unsigned long t)
  37. {
  38.                   unsigned int x,y;
  39.                   for(x=114;x>0;x--)
  40.           for(y=t;y>0;y--);
  41. }

  42.    //復位延時
  43. void Delay50us()                //@22.1184MHz
  44. {
  45.         unsigned char i, j;

  46.         _nop_();
  47.         _nop_();
  48.         i = 2;
  49.         j = 15;
  50.         do
  51.         {
  52.                 while (--j);
  53.         } while (--i);
  54. }
  55. //1碼,高電平850ns 低電平400ns 誤差正負150ns
  56. void RGB_Set_Up()
  57. {
  58.                 WS2812 = 1;
  59.           //經過邏輯分析儀調試的的延時
  60.                 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
  61.           _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
  62.                 WS2812 = 0;
  63. }
  64. //1碼,高電平400ns 低電平850ns 誤差正負150ns
  65. void RGB_Set_Down()
  66. {
  67.    WS2812 = 1;
  68.           //經過邏輯分析儀調試的的延時
  69.                 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  
  70.                 WS2812 = 0;
  71. }

  72. //發送24位數據
  73. void Send_2812_24bits(unsigned char G8,unsigned char R8,unsigned char B8)
  74. {
  75.                    unsigned int n = 0;
  76.                    //發送G8位
  77.                   for(n=0;n<8;n++)
  78.                   {
  79.                       G8<<=n;
  80.                           if(G8&0x80 == 0x80)
  81.                           {
  82.                              RGB_Set_Up();
  83.                           }
  84.                           else
  85.                           {
  86.                             RGB_Set_Down();
  87.                           }
  88.                   }
  89.                   //發送R8位
  90.                   for(n=0;n<8;n++)
  91.                   {
  92.                       R8<<=n;
  93.                           if(R8&0x80 == 0x80)
  94.                           {
  95.                              RGB_Set_Up();
  96.                           }
  97.                           else
  98.                           {
  99.                             RGB_Set_Down();
  100.                           }
  101.                   }
  102.                         //發送B8位
  103.                     for(n=0;n<8;n++)
  104.                   {
  105.                       B8<<=n;
  106.                           if(B8&0x80 == 0x80)
  107.                           {
  108.                              RGB_Set_Up();
  109.                           }
  110.                           else
  111.                           {
  112.                             RGB_Set_Down();
  113.                            }
  114.                   }
  115.                   
  116.                   
  117.          
  118. }                 
  119. //復位碼
  120. void RGB_Rst()
  121. {
  122.             WS2812 = 0;
  123.           Delay50us();
  124. }

  125. //顏色交換24位不拆分發

  126. void SetPixelColor(unsigned char num,unsigned long c)
  127. {
  128.            unsigned char i;
  129.        for(i=0;i<numLEDs;i++)
  130.            {
  131.               buf_R[num] = (unsigned char)(c>>16);
  132.                           buf_G[num] = (unsigned char)(c>>8);
  133.                           buf_B[num] = (unsigned char)(c);
  134.            }

  135.                  for(i=0;i<numLEDs;i++)
  136.                 {
  137.                         Send_2812_24bits(buf_G[i],buf_R[i],buf_B[i]);
  138.                 }

  139. }

  140. //復位
  141. void PixelUpdate()
  142. {
  143.         RGB_Rst();
  144. }


  145. // Fill the dots one after the other with a color
  146. //用一種顏色填充這些圓點
  147. void colorWipe(unsigned long c, unsigned int wait)
  148. {
  149.   unsigned char i=0;
  150.   for( i=0; i<numLEDs; i++)
  151.         {
  152.     SetPixelColor(i, c);
  153.     PixelUpdate();
  154.     HAL_Delay(wait*5);
  155.   }

  156. }
  157. void Watercolor(unsigned long c, unsigned int wait)
  158. {
  159.   unsigned char i=0;
  160.   for( i=0; i<numLEDs; i++)
  161.         {
  162.     SetPixelColor(i, c);
  163.          PixelUpdate();
  164.     HAL_Delay(wait*5);
  165.         SetPixelColor(i, 0);
  166.    PixelUpdate();
  167.     HAL_Delay(wait);
  168.   }

  169. }

  170. //顏色
  171. unsigned long Color(unsigned char r, unsigned char g, unsigned char b)
  172. {
  173.   return ((unsigned long)r << 16) | ((unsigned long)g <<  8) | b;
  174. }

  175. //顏色算法
  176. unsigned long Wheel(unsigned char WheelPos)
  177. {
  178.   WheelPos = 255 - WheelPos;
  179.   if(WheelPos < 85)
  180.         {
  181.     return Color(255 - WheelPos * 3, 0, WheelPos * 3);
  182.   }
  183.   if(WheelPos < 170) {
  184.     WheelPos -= 85;
  185.     return Color(0, WheelPos * 3, 255 - WheelPos * 3);
  186.   }
  187.   WheelPos -= 170;
  188.   return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  189. }

  190. //彩虹
  191. void rainbow(unsigned int wait)
  192. {
  193.   unsigned int i, j;

  194.   for(j=0; j<256; j++)
  195.         {
  196.             for(i=0; i<numLEDs; i++)
  197.                 {
  198.                                       SetPixelColor(i, Wheel((i+j) & 255));
  199.                             }
  200.                 PixelUpdate();
  201.                             HAL_Delay(wait);
  202.                   }
  203. }

  204. //稍微不同的是,這使得彩虹均勻分布
  205. void rainbowCycle(unsigned int wait)
  206. {
  207.   unsigned int i, j;

  208.   for(j=0;j<256*5;j++)
  209.         { // 5 cycles of all colors on wheel  車輪上所有顏色的5個循環
  210.     for(i=0;i<numLEDs;i++)
  211.          {
  212.      SetPixelColor(i, Wheel(((i * 256 / numLEDs) + j) & 255));
  213.     }
  214.           PixelUpdate();
  215.     HAL_Delay (wait);
  216.   }
  217. }


  218. //Theatre-style crawling lights with rainbow effect
  219. //帶有彩虹效果的戲劇式爬行燈
  220. void theaterChaseRainbow(unsigned int wait)
  221. {
  222.         int j,q;
  223.         unsigned int i;
  224.   for (j=0; j < 256; j++)
  225.         {     // cycle all 256 colors in the wheel 在輪子上循環所有256色
  226.     for (q=0; q < 3; q++)
  227.                 {
  228.       for (i=0; i < numLEDs; i=i+3)
  229.                         {
  230.         SetPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel off 把每一個第三個像素
  231.       }
  232.       PixelUpdate();

  233.       HAL_Delay(wait);

  234.       for (i=0; i < numLEDs; i=i+3)
  235.                         {
  236.         SetPixelColor(i+q, 0);        //turn every third pixel off  把每一個第三個像素關掉
  237.       }
  238.     }
  239.   }
  240. }

  241. void colorWipe_1()//顏色刷1
  242.         {
  243.                                     colorWipe(0xff0000,1);        //紅色
  244.                                          HAL_Delay(10000);
  245.                                    colorWipe(0xff00,1);         //綠色
  246.                                         HAL_Delay(10000);
  247.                                    colorWipe(0xff,1);//藍色
  248.                                         HAL_Delay(10000);
  249.                                    colorWipe(0xffff00,1);        //黃色
  250.                                          HAL_Delay(10000);
  251.                                    colorWipe(0xffff,1);        //青色
  252.                                          HAL_Delay(10000);
  253.                                    colorWipe(0xff00ff,1);        //紫色
  254.                                          HAL_Delay(10000);
  255.                                    colorWipe(0xffffff,1);        //白色
  256.                                          HAL_Delay(10000);
  257.                                    colorWipe(0x00,1);        //off
  258.                                          HAL_Delay(10000);
  259.         }

  260. void colorWipe_2()//顏色刷2
  261.         {
  262.                             Watercolor(0xff0000, 100);//紅色
  263.                                          HAL_Delay(1000);
  264.                                         Watercolor(0xff00, 100);//綠色
  265.                                          HAL_Delay(1000);
  266.                                         Watercolor(0xff, 100);//藍色
  267.                                          HAL_Delay(1000);
  268.                                         Watercolor(0xffff00, 100);        //黃色
  269.                                          HAL_Delay(1000);
  270.                                         Watercolor(0xffff, 100);//青色
  271.                                          HAL_Delay(1000);
  272.                                         Watercolor(0xff00ff, 100);        //紫色
  273.                                          HAL_Delay(1000);
  274.                                         Watercolor(0xffffff, 100);        //白色
  275.                                          HAL_Delay(1000);        
  276.                                         colorWipe(0x00,1);        //off
  277.                                          HAL_Delay(10000);
  278.         }

  279. void colorWipe_3()//顏色刷3
  280.         {
  281.                                          colorWipe(0xff0000,100);        //紅色
  282.                                          HAL_Delay(1000);
  283.                                         colorWipe(0x00,100);        //0ff
  284.                                          HAL_Delay(1000);
  285.                                         colorWipe(0xff00,100);         //綠色
  286.                                          HAL_Delay(1000);
  287.                                         colorWipe(0x00,100);        //0ff
  288.                                          HAL_Delay(1000);
  289.                                         colorWipe(0xff,100);//藍色
  290.                                          HAL_Delay(1000);
  291.                                     colorWipe(0x00,100);        //0ff
  292.                                          HAL_Delay(1000);
  293.                                     colorWipe(0xffff00,100);        //黃色
  294.                                          HAL_Delay(1000);
  295.                                         colorWipe(0x00,100);        //0ff
  296.                                          HAL_Delay(1000);
  297.                                         colorWipe(0xffff,100);        //青色
  298.                                          HAL_Delay(1000);
  299.                                         colorWipe(0x00,100);        //0ff
  300.                                          HAL_Delay(1000);
  301.                                         colorWipe(0xff00ff,100);        //紫色
  302.                                          HAL_Delay(1000);
  303.                                          colorWipe(0x00,100);        //0ff
  304.                                          HAL_Delay(1000);
  305.                                            colorWipe(0xffffff,100);        //白色
  306.                                          HAL_Delay(1000);
  307.                                         colorWipe(0x00,100);        //0ff
  308.                                           HAL_Delay(1000);
  309.         }


  310. void main()
  311. {               
  312.                 IO_init();        //io口初始化
  313.                 IT1 = 1; //設置INT1的中斷類型 (1:僅下降沿 0:上升沿和下降沿)
  314.                 EX1 = 1;//使能INT1中斷
  315.                 INTCLKO|=0x10;//開啟外部中斷2
  316.             EA = 1;                //開啟總中斷
  317.                 Timer0_Init();//按鍵掃描定時器0初始化
  318.                 while(1)
  319.                 {        
  320.                 key_service();//按鍵服務程序  
  321.                 switch(list)
  322.                                 {
  323.                                 case 1: colorWipe_1(); break;//顏色刷1
  324.                                 case 2: colorWipe_2(); break;//顏色刷2
  325.                                 case 3: colorWipe_3(); break;//顏色刷3
  326.                                 case 4: rainbow(10); break;//彩虹
  327.                                 case 5: rainbowCycle(10); break;//彩虹2
  328.                                 case 6:        theaterChaseRainbow(10); break;//彩虹升級
  329.                                 default:break;
  330.                                 }                 
  331.                
  332.            
  333.                 }
  334. }

  335. //-----------------------------------------
  336. //按鍵定時器初始化程序
  337. void Timer0_Init(void)                //20毫秒@22.1184MHz
  338. {
  339.         AUXR &= 0x7F;                        //定時器時鐘12T模式
  340.         TMOD &= 0xF0;                        //設置定時器模式
  341.         TMOD |= 0x01;                        //設置定時器模式16位模式
  342.         TL0 = 0x00;                                //設置定時初始值
  343.         TH0 = 0x70;                                //設置定時初始值
  344.         TF0 = 0;                                //清除TF0標志
  345.         //ET0 = 1;                //定時器0中斷開啟
  346.         TR0 = 1;                                //定時器0開始計時
  347. }

  348. void Delay10ms()                //@22.1184MHz 按鍵消抖10ms延時
  349. {
  350.         unsigned char i, j, k;

  351.         i = 2;
  352.         j = 32;
  353.         k = 60;
  354.         do
  355.         {
  356.                 do
  357.                 {
  358.                         while (--k);
  359.                 } while (--j);
  360.         } while (--i);
  361. }


  362. //按鍵掃描服務程序
  363. void key_service()//按鍵服務程序
  364.         {
  365.         if(TF0==1)
  366.                 {
  367.                          TF0 = 0;                                //清除TF0標志
  368.                         TL0 = 0x9A;                                //設置定時初始值
  369.                         TH0 = 0xA9;                                //設置定時初始值

  370.                         if(key_Return==0)//返回鍵掃描
  371.                                 {
  372.                                  Delay10ms();                //按鍵消抖延時@22.1184MHz
  373.                                  if(key_Return==1)
  374.                                          {
  375.                                                 RGB_Rst();//復位
  376.                                                 colorWipe(0xffffff,100);        //白色
  377.                                                  PCON=0x02;//進入掉電模式
  378.                                                  _nop_();
  379.                                                     _nop_();
  380.                                         }
  381.                                         while(!key_Return);//等待按鍵松開
  382.                                 }

  383.                         if(key_ok == 0)//OK鍵掃描
  384.                                  {
  385.                                         Delay10ms();                //按鍵消抖延時@22.1184MHz
  386.                                         if(key_ok==0)
  387.                                                 {
  388.                                                         RGB_Rst();//復位
  389.                                                         colorWipe(0xffff00,100);        //黃色
  390.                                                         PCON=0x02;//進入掉電模式
  391.                                                          _nop_();
  392.                                                             _nop_();
  393.                                                 }
  394.                                 while(!key_ok);//等待按鍵松開
  395.                                 }

  396.                         if( key_left == 0)//按鍵左鍵掃描
  397.                                  {
  398.                                         Delay10ms();                //按鍵消抖延時@22.1184MHz
  399.                                         if(key_left==0)
  400.                                                 {
  401.                                                 RGB_Rst();//復位
  402.                                                 list--;
  403.                                                 }
  404.                                 while(!key_left);//等待按鍵松開
  405.                                 }
  406.                         if(key_right == 0)//按鍵右鍵掃描
  407.                                  {
  408.                                         Delay10ms();                //按鍵消抖延時@22.1184MHz
  409.                                         if(key_right==0)
  410.                                                 {
  411.                                                 RGB_Rst();//復位
  412.                                                 list++;
  413.                                                 }
  414.                                 while(!key_right);//等待按鍵松開
  415.                                 }
  416.                                        
  417.                 }
  418.         }


  419. //中斷服務程序
  420. void exint0() interrupt 2       //INT1中斷入口
  421. {
  422.         colorWipe(0x00,100);        //0ff
  423.         Power = 0;        //關閉ws2812電源
  424.     P3M0 = 0x00; P3M1 = 0x04;//P3.2高阻輸入
  425.         PCON=0x02;//進入掉電模式
  426.         _nop_();
  427.     _nop_();
  428. }


  429. //-----------------------------------------
  430. //中斷服務程序
  431. void exint1() interrupt 10      //INT2中斷入口
  432. {
  433.     EA = 0;                //關閉總中斷
  434.         PCON=0x00;//取消掉電模式
  435.         P3M0 = 0x00; P3M1 = 0x00;//P3.2準雙向輸入
  436.         Power = 1;        //開啟ws2812電源
  437.           EA = 1;                //開啟總中斷
  438.         _nop_();
  439.     _nop_();
  440. }

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

使用道具 舉報

沙發
ID:161164 發表于 2024-1-2 16:05 | 只看該作者
按鍵左和按鍵右無法控制切換流水燈模式是因為其他地方用了大量長時間delay
全部時間都耗在顏色刷函數里
阻塞了按鍵掃描函數
放棄delay(10000)吧
給你一個思路
  1. #include <reg52.h>
  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 to 65535
  4. sbit Led = P1^0;
  5. void Delay1ms(void)        //@11.0592MHz
  6. {
  7.         unsigned char data i, j;

  8.         i = 2;
  9.         j = 199;
  10.         do
  11.         {
  12.                 while (--j);
  13.         } while (--i);
  14. }
  15. u16 Delay = 0;
  16. void main()
  17. {
  18.         P1 = 0xFE;
  19.     while (1)
  20.     {
  21.                 if(++Delay>=500)
  22.                 {
  23.                         Delay = 0;
  24.                         Led = !Led;
  25.                 }
  26.                 Delay1ms();
  27.     }
  28. }
復制代碼
回復

使用道具 舉報

板凳
ID:190152 發表于 2024-1-2 21:20 | 只看該作者
lkc8210 發表于 2024-1-2 16:05
按鍵左和按鍵右無法控制切換流水燈模式是因為其他地方用了大量長時間delay
全部時間都耗在顏色刷函數里
...

感謝熱情指導,有空去掉延時函數試試。我試過用定時器中斷10ms掃描按鍵但是流水的會閃爍。或者用兩個定時器中斷一個負責刷新一個負責按鍵。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: www免费视频 | 国产一级影片 | 国产a级黄色录像 | 亚洲高清在线 | 日韩精品成人一区二区三区视频 | 丁香久久 | 精品网 | 国产69精品久久99不卡免费版 | 久久久精品视频一区二区三区 | 国产高清精品一区二区三区 | 精品一区二区免费视频 | 人妖无码 | 国产黄色av网站 | 日韩一区二区三区在线观看 | 99欧美精品 | 九九色综合 | 国产精品国产三级国产aⅴ中文 | 超碰在线人人干 | 中文字幕成人免费视频 | 真人毛片 | 毛片99 | 亚洲综合视频一区 | 欧美成年视频 | 在线91 | 在线一区 | 男女羞羞视频免费 | 天天亚洲 | 色橹橹欧美在线观看视频高清 | 国产日韩欧美中文 | 欧美在线精品一区 | 看片一区| 亚洲资源站 | 一本一道久久a久久精品综合 | 欧美福利在线 | 日韩在线91 | 亚洲天堂精品久久 | 九九亚洲 | 国产一在线 | 久久久久久久久久久国产 | 国产欧美精品一区二区色综合 | 国内精品久久久久久 |