標題: STM32驅動WS2812呼吸燈、頻譜,變色變速旋轉源程序 [打印本頁]

          作者: feeling1791    時間: 2022-9-5 16:43
          標題: STM32驅動WS2812呼吸燈、頻譜,變色變速旋轉源程序
          網上看到些WS281例程,終究看不下去,動手寫了個來玩,希望能吊打全網你能隨便百度到的相關例程,源碼工程奉上:
          特點:
          1,硬件:STM32C8T6小板,WS2812 16leds燈環(huán),資源易得;
          2,軟件:PWM+DMA+TIME3處理脈沖數(shù)據(比SPI選擇的端口多,隨便修改很多口可用)
                         TIME4處理顯示花式,不使用delay,不影響主循環(huán)其余進程
                         呼吸(算法有趣)
                         頻譜(加上音樂AD到的 幅度數(shù)據即可動態(tài)跟隨)
                         變色變速旋轉(給你一個定時器基準節(jié)拍,可以無限擴展各種時間,各種變量的控制,靈活使用timer)
                         代碼簡潔易懂(對齊和括號強迫癥)
          *如果喜歡,請回帖 ,開玩笑啦  :)

          單片機源程序如下:
          1. #include "ws281x.h"
          2. #include "delay.h"
          3. #include "timer.h"


          4. u16 pixelBuffer[PIXEL_NUM + RESET_NUM][24] = {0};

          5. void ws281x_show(void)
          6. {               
          7.      DMA_SetCurrDataCounter(DMA1_Channel5,(PIXEL_NUM + RESET_NUM)* 24 );
          8.                                        
          9.             DMA_Cmd(DMA1_Channel5, ENABLE);
          10.      TIM_Cmd(TIM4, ENABLE);
          11.                                 

          12.             while(DMA_GetFlagStatus(DMA1_FLAG_TC5) !=SET);
          13.      DMA_Cmd(DMA1_Channel5, DISABLE );
          14.      DMA_ClearFlag(DMA1_FLAG_TC5);
          15.      TIM_Cmd(TIM4, DISABLE);                                                        
          16. }

          17. void ws281x_closeAll(void)
          18. {
          19.      uint16_t i;
          20.      uint8_t j;  
          21.      for(i = 0; i < PIXEL_NUM; i++)
          22.      {
          23.          for(j = 0; j < 24; j++)
          24.          {
          25.               pixelBuffer[i][j] = WS_LOW;
          26.          }
          27.      }
          28.                                         ws281x_show();
          29. }

          30. uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue)
          31. {
          32.      return ((green << 16) | (red << 8) | blue);
          33. }


          34. void ws281x_setPixelColor(uint16_t n ,uint32_t GRBcolor)
          35. {
          36.      uint8_t i;
          37.                                         if(n < PIXEL_NUM)
          38.      {
          39.           for(i = 0; i < 24; i++)
          40.           {                                                                        
          41.                                                                                      pixelBuffer[n][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
          42.           }
          43.      }               
          44. }



          45. /**********************************************************************************************************/
          46. // level
          47. //  8               08   09
          48. //  7            07         10
          49. //  6          06             11
          50. //  5         05               12
          51. //  4         04               13
          52. //  3          03             14
          53. //  2            02         15
          54. //  1               01  16
          55. //  0 off            
          56. void ws281x_setPixelColor_ringleds(uint16_t n ,uint32_t GRBcolor)            //PIXEL_NUM:12/16/2*n Ring leds
          57. {
          58.        uint8_t i,k,p;
          59.                                                         
          60.                                                         for(i = 0; i < 24; i++)
          61.                                                  {                        
          62.                                                                                                         for(k = 0;(k < n) && (n <= (PIXEL_NUM / 2));k++)
          63.                                                                                                         {
          64.                                                                                                              pixelBuffer[k][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
          65.                                                                                                              pixelBuffer[(PIXEL_NUM - 1) - k][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;                                                                                                
          66.                                                                                                         }
          67.                                                                                                         for(p = n;(p < ( PIXEL_NUM - n)) && (n <= (PIXEL_NUM / 2)) ;p++)
          68.                                                                                                         {
          69.                                                                                                              pixelBuffer[p][i]  =   WS_LOW;                                                                                                                                                                                                                                 
          70.                                                                                                         }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
          71.                                                         }
          72. }


          73. //  fill the dots one by one with a color on left and right sides at the same time
          74. void ws281x_colorWipe_lr( uint32_t c, uint8_t num)
          75. {
          76.     uint16_t i;
          77.                                 if(num > PIXEL_NUM / 2)
          78.                                 {
          79.                                      num = PIXEL_NUM / 2;
          80.                                 }
          81.     for(i = 0; i < (num + 1); i++)         //
          82.                   {                                                
          83.                                                                 ws281x_setPixelColor_ringleds(i ,c);
          84.                       ws281x_show();
          85.         //delay_ms(wait);          //>        0.05ms                                will should be using timer               
          86.     }
          87. }


          88. //Freq rising or falling lights
          89. void ws281x_colorWipe_freq(uint8_t type)
          90. {        
          91.                                                                                                                
          92.                  switch(type)
          93.                                                                                 {
          94.                                                                                        case 1:
          95.                         ws281x_colorWipe_lr(ws281x_color(50, 0, 0), ws281x_freq_num); // red
          96.                                                                                                                                                                                                 break;
          97.                                                                                               case 2:
          98.                         ws281x_colorWipe_lr(ws281x_color(0, 50, 0), ws281x_freq_num); // green
          99.                                                                                                                                                                                                 break;                                                                                                                                                               
          100.                                                                                                                                         case 3:
          101.                         ws281x_colorWipe_lr(ws281x_color(0, 0, 50), ws281x_freq_num); // Blue
          102.                                                                                                                                                                                                 break;               
          103.                                                                                                                                         case 4:
          104.                         ws281x_colorWipe_lr(ws281x_color(50, 50, 50), ws281x_freq_num); // white
          105.                                                                                                                                                                                                 break;               
          106.                                                                                                                                                                                        
          107.                                                                                                                                 default:
          108.                         ws281x_colorWipe_lr(ws281x_color(50, 0, 0), ws281x_freq_num); // red
          109.                                                                                                                                                                                                 break;                                       
          110.                                                                                 }                                                                                   
          111. }




          112. /***************************************************************************************************/
          113. uint32_t ws281x_colorTran(uint8_t tran,uint8_t color_mode)  //The colour is a transition r/g/b back to r/g/b(color_mode:Red1,Green2,Blue3). space 3
          114. {
          115.      tran = 255 - tran;
          116.      if(tran < 85)
          117.                                         {
          118.                                              switch(color_mode)
          119.                                                                                 {
          120.                                                                                        case 1:
          121.                         return ws281x_color(tran * 3, 0, 0);
          122.                                                                                               case 2:
          123.                         return ws281x_color(0, tran * 3, 0);                                                                                                                                                                                
          124.                                                                                                                                         case 3:
          125.                         return ws281x_color(0, 0, tran * 3);                                                               
          126.                                                                                                                                 default:
          127.                                                                                                                                         return ws281x_color(tran * 3, 0, 0);                                                
          128.                                                                                 }
          129.      }
          130.                                        
          131.      if(tran < 170)
          132.                                         {
          133.           tran -= 85;
          134.                                                                                 switch(color_mode)
          135.                                                                                 {
          136.                                                                                        case 1:
          137.                         return ws281x_color(255, 0, 0);
          138.                                                                                               case 2:
          139.                         return ws281x_color(0,255, 0);                                                                                                                                                                                
          140.                                                                                                                                         case 3:
          141.                         return ws281x_color(0, 0, 255);                                                               
          142.                                                                                                                                 default:
          143.                                                                                                                                         return ws281x_color(255, 0, 0);                                                
          144.                                                                                 }
          145.      }
          146.      tran -= 170;
          147.                                         switch(color_mode)
          148.                                         {
          149.                                                                                                 case 1:
          150.                                                                                                                                                         return ws281x_color(255 - tran * 3, 0, 0);
          151.                                                                                                 case 2:
          152.                                                                                                                                                         return ws281x_color(0, 255 - tran * 3, 0);                                                                                                                                                                                
          153.                                                                                                 case 3:
          154.                                                                                                                                                         return ws281x_color(0, 0, 255 - tran * 3);                                                               
          155.                                                                                         default:
          156.                                                                                                                                                         return ws281x_color(255 - tran * 3, 0, 0);                                                                                                                                                
          157.                                         }
          158. }


          159. void ws281x_colorblnCtrl(uint8_t color_mode)   // ws281x_bln_num use timer,mode:red1/green2/blue3
          160. {
          161.      uint16_t i;

          162.                                                                                         if( !(ws281x_bln_num == ws281x_bln_oldnum))
          163.                                                                                         {
          164.                                                                                                                         for(i = 0; i < PIXEL_NUM; i++)
          165.                                                                                                                         {
          166.                                                                                                                                                         ws281x_setPixelColor(i ,ws281x_colorTran(ws281x_bln_num,color_mode));
          167.                                                                                                                         }
          168.                                                                                                                         ws281x_show();
          169.                                                                                                                         ws281x_bln_oldnum = ws281x_bln_num;
          170.                                                                                         }
          171.                                 
          172. }
          173. /***************************************************************************************************/

          174. void ws281x_setPixelColor_wheel_leds(uint16_t n ,uint32_t GRBcolor)            //n:0~15 whirling leds
          175. {
          176.        uint8_t i,k;
          177.                                                         
          178.                                                         for(i = 0; i < 24; i++)
          179.                                                  {        
          180.                   for(k = 0;k < PIXEL_NUM;k++)
          181.                                                                                                                                                 {                                                                                                                                                                                                        
          182.                                                                                                                                                                                                         pixelBuffer[k][i]  =   WS_LOW;                                                                                                                                                                                         
          183.                                                                                                                                                 }                                                            

          184.                                                                                                              pixelBuffer[n][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
          185.                                                                                                                                                 if( n < PIXEL_NUM/2)
          186.                                                                                                                                                 {
          187.                                                                                                                                                      pixelBuffer[n + (PIXEL_NUM/2)][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;        
          188.                                                                                                                                                 }
          189.                                                                                                                                                 else
          190.                                                                                                                                                 {
          191.                                                                                                                                                      pixelBuffer[n - (PIXEL_NUM/2)][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;        
          192.                                                                                                                                                 }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
          193.                                                         }
          194.                                                         ws281x_show();        
          195. }

          196. void ws281x_display(void)
          197. {
          198.                                      if(ws281x_led_display_mode == 1)
          199.                                                                         {
          200.                                                                         ws281x_colorblnCtrl(ws281x_bln_mode);
          201.                                                                         }
          202.                                                                         
          203.                                                                         if(ws281x_led_display_mode == 2)
          204.                                                                         {
          205.                                                                         ws281x_colorWipe_freq(ws281x_freq_color_type);
          206.                                                                         }
          207.                                                                         if(ws281x_led_display_mode == 3)
          208.                                                                         {
          209.                                                                                                         ws281x_setPixelColor_wheel_leds(ws281x_whirl_index,
          210.                                                                                                                                                                                                                                                                                                                                                                         ws281x_color(color_R[ws281x_whirl_colortran_index],
          211.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 color_G[ws281x_whirl_colortran_index],
          212.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 color_B[ws281x_whirl_colortran_index])) ;        
          213.                                                                         }     
          214. }







          215. /*
          216. void ws281x_setPixelColor_11x44leds(uint16_t n ,uint32_t GRBcolor)            //PIXEL_NUM:11x44 leds  n:0~10
          217. {
          218.        uint8_t i,k,p,q;
          219.                                                         
          220.                                                         for(i = 0; i < 24; i++)
          221.                                                  {                        
          222.                                                                                                         for(k = 0;k < 44;k++)
          223.                                                                                                         {
          224.                                                                                                               for(q = 0 ;q < (n +1);q++)
          225.                                                                                                                                                         {
          226.                                                                                                                                                       pixelBuffer[q + k*11][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;                                                                                                                                                                                
          227.                                                                                                                                                  }
          228.                                                                                                                                                         for(p = 1;p < (10-n);p++)
          229.                                                                                                                                                  {
          230.                                                                                                                                                                                          pixelBuffer[(n + p) + k*11][i]  =   WS_LOW;                                                                                                                                                                                                                                 
          231.                                                                                                                                                  }                                                                                                                                                                                                        
          232.                                                                                                         }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
          233.                                                         }
          234. }
          235. */
          復制代碼

          效果視頻
          https://v.qq.com/x/page/u3354xdptxh.html

          原理圖: 無
          仿真: 無
          Keil代碼下載: 程序.7z (180.19 KB, 下載次數(shù): 376)

          作者: dragon20100708    時間: 2022-9-6 09:29
          看一看,研究下。
          作者: 053053    時間: 2022-9-7 11:25
          不寫注釋,真是一個不好的習慣
          作者: heicad    時間: 2022-9-7 23:39
          好資料,51黑有你更精彩!!!
          作者: bigbigcong    時間: 2022-11-8 14:22
          很牛的WS281驅動例程
          作者: 461447043    時間: 2023-2-23 20:38
          原理圖能繼續(xù)分享一下嗎?

          作者: hei51com    時間: 2023-2-24 09:33
          效果很贊,感謝分享,收藏備用
          作者: Jshenliu    時間: 2023-3-27 14:19
          沙發(fā),收藏備用
          作者: wuhaijie    時間: 2023-9-13 06:06
          下載來看看,確實很!ぁぁみ帶變速的,謝謝樓主分享,學習學習
          作者: IdeaMing    時間: 2023-11-10 09:45
          幅度的動態(tài)跟隨,請大佬詳解
          作者: maijinzhi    時間: 2023-11-22 09:28
          不寫注釋,真是一個不好的習慣
          作者: 山海靚仔    時間: 2023-12-19 17:54
          就沖你這句吊打一切,無論能不能點亮,都要給你點贊
          作者: 啦啦啦ajih    時間: 2023-12-25 11:20
          博主,求求了,原理圖可以分享一下嗎

          作者: feeling1791    時間: 2023-12-26 15:43
          啦啦啦ajih 發(fā)表于 2023-12-25 11:20
          博主,求求了,原理圖可以分享一下嗎

          某一個寶買塊16 RGB的燈環(huán),然后買塊最小系統(tǒng)STM32F103C8T6板,再買個ST LINK下載小板,總共應該50元左右吧,把燈環(huán)輸入接電源+5V,GND,燈環(huán)數(shù)據輸入焊點DATA接最小系統(tǒng)板的PB8腳,然后編譯程序下載到單片機,再上電就可以看效果了,電路圖,你買這些小板老板都會給你圖紙的
          作者: 點不亮燈大師    時間: 2024-2-29 11:47
          怎么玩啊,兄弟盟

          作者: wifingtta    時間: 2024-3-1 14:21
          感謝樓主!用C8T6測試過,程序完全可用,有三種模式,2812接PB8口,定時器自動切換模式,燈的數(shù)量不限,直接改參數(shù)即可。只是注釋確實太少,勉強看懂一點,再看看。




          歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1