找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

帖子
查看: 1090|回復(fù): 2
收起左側(cè)

單片機(jī)ws2812程序無(wú)法用按鍵控制?

[復(fù)制鏈接]
ID:190152 發(fā)表于 2024-1-2 12:22 | 顯示全部樓層 |閱讀模式
這個(gè)是用別人的程序修改的,現(xiàn)在遇到幾個(gè)問(wèn)題。外部中斷接的開(kāi)機(jī)按鍵需要按幾次才能開(kāi)機(jī)。按鍵左和按鍵右無(wú)法控制切換流水燈模式

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

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



  9. #define numLEDs 64  //燈的個(gè)數(shù)

  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;//記錄定時(shí)器0中斷次數(shù)
  14. unsigned char list=1;//播放列表

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



  20. //真對(duì) STC8系列 IO口初始化 準(zhǔn)雙向
  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.    //復(fù)位延時(shí)
  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 誤差正負(fù)150ns
  56. void RGB_Set_Up()
  57. {
  58.                 WS2812 = 1;
  59.           //經(jīng)過(guò)邏輯分析儀調(diào)試的的延時(shí)
  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 誤差正負(fù)150ns
  65. void RGB_Set_Down()
  66. {
  67.    WS2812 = 1;
  68.           //經(jīng)過(guò)邏輯分析儀調(diào)試的的延時(shí)
  69.                 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  
  70.                 WS2812 = 0;
  71. }

  72. //發(fā)送24位數(shù)據(jù)
  73. void Send_2812_24bits(unsigned char G8,unsigned char R8,unsigned char B8)
  74. {
  75.                    unsigned int n = 0;
  76.                    //發(fā)送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.                   //發(fā)送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.                         //發(fā)送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. //復(fù)位碼
  120. void RGB_Rst()
  121. {
  122.             WS2812 = 0;
  123.           Delay50us();
  124. }

  125. //顏色交換24位不拆分發(fā)

  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. //復(fù)位
  141. void PixelUpdate()
  142. {
  143.         RGB_Rst();
  144. }


  145. // Fill the dots one after the other with a color
  146. //用一種顏色填充這些圓點(diǎn)
  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  車(chē)輪上所有顏色的5個(gè)循環(huán)
  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 在輪子上循環(huán)所有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 把每一個(gè)第三個(gè)像素
  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  把每一個(gè)第三個(gè)像素關(guān)掉
  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);//藍(lán)色
  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);//藍(lán)色
  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);//藍(lán)色
  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; //設(shè)置INT1的中斷類(lèi)型 (1:僅下降沿 0:上升沿和下降沿)
  314.                 EX1 = 1;//使能INT1中斷
  315.                 INTCLKO|=0x10;//開(kāi)啟外部中斷2
  316.             EA = 1;                //開(kāi)啟總中斷
  317.                 Timer0_Init();//按鍵掃描定時(shí)器0初始化
  318.                 while(1)
  319.                 {        
  320.                 key_service();//按鍵服務(wù)程序  
  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;//彩虹升級(jí)
  329.                                 default:break;
  330.                                 }                 
  331.                
  332.            
  333.                 }
  334. }

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

  348. void Delay10ms()                //@22.1184MHz 按鍵消抖10ms延時(shí)
  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. //按鍵掃描服務(wù)程序
  363. void key_service()//按鍵服務(wù)程序
  364.         {
  365.         if(TF0==1)
  366.                 {
  367.                          TF0 = 0;                                //清除TF0標(biāo)志
  368.                         TL0 = 0x9A;                                //設(shè)置定時(shí)初始值
  369.                         TH0 = 0xA9;                                //設(shè)置定時(shí)初始值

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

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

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


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


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

復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2024-1-2 16:05 | 顯示全部樓層
按鍵左和按鍵右無(wú)法控制切換流水燈模式是因?yàn)槠渌胤接昧舜罅块L(zhǎng)時(shí)間delay
全部時(shí)間都耗在顏色刷函數(shù)里
阻塞了按鍵掃描函數(shù)
放棄delay(10000)吧
給你一個(gè)思路
  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. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:190152 發(fā)表于 2024-1-2 21:20 | 顯示全部樓層
lkc8210 發(fā)表于 2024-1-2 16:05
按鍵左和按鍵右無(wú)法控制切換流水燈模式是因?yàn)槠渌胤接昧舜罅块L(zhǎng)時(shí)間delay
全部時(shí)間都耗在顏色刷函數(shù)里
...

感謝熱情指導(dǎo),有空去掉延時(shí)函數(shù)試試。我試過(guò)用定時(shí)器中斷10ms掃描按鍵但是流水的會(huì)閃爍�;蛘哂脙蓚€(gè)定時(shí)器中斷一個(gè)負(fù)責(zé)刷新一個(gè)負(fù)責(zé)按鍵。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表