找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4193|回复: 15
收起左侧

STM32驱动WS2812呼吸灯、频谱,变色变速旋转源程序

  [复制链接]
ID:651494 发表于 2022-9-5 16:43 | 显示全部楼层 |阅读模式
网上看到些WS281例程,终究看不下去,动手写了个来玩,希望能吊打全网你能随便百度到的相关例程,源码工程奉上:
特点:
1,硬件:STM32C8T6小板,WS2812 16leds灯环,资源易得;
2,软件:PWM+DMA+TIME3处理脉冲数据(比SPI选择的端口多,随便修改很多口可用)
               TIME4处理显示花式,不使用delay,不影响主循环其余进程
               呼吸(算法有趣)
               频谱(加上音乐AD到的 幅度数据即可动态跟随)
               变色变速旋转(给你一个定时器基准节拍,可以无限扩展各种时间,各种变量的控制,灵活使用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, 下载次数: 327)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:271166 发表于 2022-9-6 09:29 | 显示全部楼层
看一看,研究下。
回复

使用道具 举报

ID:371387 发表于 2022-9-7 11:25 | 显示全部楼层
不写注释,真是一个不好的习惯
回复

使用道具 举报

ID:262 发表于 2022-9-7 23:39 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:958310 发表于 2022-11-8 14:22 | 显示全部楼层
很牛的WS281驱动例程
回复

使用道具 举报

ID:697462 发表于 2023-2-23 20:38 | 显示全部楼层
原理图能继续分享一下吗?
回复

使用道具 举报

ID:731155 发表于 2023-2-24 09:33 | 显示全部楼层
效果很赞,感谢分享,收藏备用
回复

使用道具 举报

ID:698161 发表于 2023-3-27 14:19 | 显示全部楼层
沙发,收藏备用
回复

使用道具 举报

ID:587318 发表于 2023-9-13 06:06 | 显示全部楼层
下载来看看,确实很牛···还带变速的,谢谢楼主分享,学习学习
回复

使用道具 举报

ID:276663 发表于 2023-11-10 09:45 | 显示全部楼层
幅度的动态跟随,请大佬详解
回复

使用道具 举报

ID:398094 发表于 2023-11-22 09:28 | 显示全部楼层
不写注释,真是一个不好的习惯
回复

使用道具 举报

ID:1043068 发表于 2023-12-19 17:54 | 显示全部楼层
就冲你这句吊打一切,无论能不能点亮,都要给你点赞
回复

使用道具 举报

ID:1106184 发表于 2023-12-25 11:20 | 显示全部楼层
博主,求求了,原理图可以分享一下吗
回复

使用道具 举报

ID:651494 发表于 2023-12-26 15:43 | 显示全部楼层
啦啦啦ajih 发表于 2023-12-25 11:20
博主,求求了,原理图可以分享一下吗

某一个宝买块16 RGB的灯环,然后买块最小系统STM32F103C8T6板,再买个ST LINK下载小板,总共应该50元左右吧,把灯环输入接电源+5V,GND,灯环数据输入焊点DATA接最小系统板的PB8脚,然后编译程序下载到单片机,再上电就可以看效果了,电路图,你买这些小板老板都会给你图纸的
回复

使用道具 举报

ID:1093034 发表于 2024-2-29 11:47 | 显示全部楼层
怎么玩啊,兄弟盟
回复

使用道具 举报

ID:208271 发表于 2024-3-1 14:21 | 显示全部楼层
感谢楼主!用C8T6测试过,程序完全可用,有三种模式,2812接PB8口,定时器自动切换模式,灯的数量不限,直接改参数即可。只是注释确实太少,勉强看懂一点,再看看。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表