网上看到些WS281例程,终究看不下去,动手写了个来玩,希望能吊打全网你能随便百度到的相关例程,源码工程奉上:
特点:
1,硬件:STM32C8T6小板,WS2812 16leds灯环,资源易得;
2,软件:PWM+DMA+TIME3处理脉冲数据(比SPI选择的端口多,随便修改很多口可用)
TIME4处理显示花式,不使用delay,不影响主循环其余进程
呼吸(算法有趣)
频谱(加上音乐AD到的 幅度数据即可动态跟随)
变色变速旋转(给你一个定时器基准节拍,可以无限扩展各种时间,各种变量的控制,灵活使用timer)
代码简洁易懂(对齐和括号强迫症)
*如果喜欢,请回帖 ,开玩笑啦 :)
单片机源程序如下:
- #include "ws281x.h"
- #include "delay.h"
- #include "timer.h"
- u16 pixelBuffer[PIXEL_NUM + RESET_NUM][24] = {0};
- void ws281x_show(void)
- {
- DMA_SetCurrDataCounter(DMA1_Channel5,(PIXEL_NUM + RESET_NUM)* 24 );
-
- DMA_Cmd(DMA1_Channel5, ENABLE);
- TIM_Cmd(TIM4, ENABLE);
-
- while(DMA_GetFlagStatus(DMA1_FLAG_TC5) !=SET);
- DMA_Cmd(DMA1_Channel5, DISABLE );
- DMA_ClearFlag(DMA1_FLAG_TC5);
- TIM_Cmd(TIM4, DISABLE);
- }
- void ws281x_closeAll(void)
- {
- uint16_t i;
- uint8_t j;
- for(i = 0; i < PIXEL_NUM; i++)
- {
- for(j = 0; j < 24; j++)
- {
- pixelBuffer[i][j] = WS_LOW;
- }
- }
- ws281x_show();
- }
- uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue)
- {
- return ((green << 16) | (red << 8) | blue);
- }
- void ws281x_setPixelColor(uint16_t n ,uint32_t GRBcolor)
- {
- uint8_t i;
- if(n < PIXEL_NUM)
- {
- for(i = 0; i < 24; i++)
- {
- pixelBuffer[n][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- }
- }
- }
- /**********************************************************************************************************/
- // level
- // 8 08 09
- // 7 07 10
- // 6 06 11
- // 5 05 12
- // 4 04 13
- // 3 03 14
- // 2 02 15
- // 1 01 16
- // 0 off
- void ws281x_setPixelColor_ringleds(uint16_t n ,uint32_t GRBcolor) //PIXEL_NUM:12/16/2*n Ring leds
- {
- uint8_t i,k,p;
-
- for(i = 0; i < 24; i++)
- {
- for(k = 0;(k < n) && (n <= (PIXEL_NUM / 2));k++)
- {
- pixelBuffer[k][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- pixelBuffer[(PIXEL_NUM - 1) - k][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- }
- for(p = n;(p < ( PIXEL_NUM - n)) && (n <= (PIXEL_NUM / 2)) ;p++)
- {
- pixelBuffer[p][i] = WS_LOW;
- }
- }
- }
- // fill the dots one by one with a color on left and right sides at the same time
- void ws281x_colorWipe_lr( uint32_t c, uint8_t num)
- {
- uint16_t i;
- if(num > PIXEL_NUM / 2)
- {
- num = PIXEL_NUM / 2;
- }
- for(i = 0; i < (num + 1); i++) //
- {
- ws281x_setPixelColor_ringleds(i ,c);
- ws281x_show();
- //delay_ms(wait); //> 0.05ms will should be using timer
- }
- }
- //Freq rising or falling lights
- void ws281x_colorWipe_freq(uint8_t type)
- {
-
- switch(type)
- {
- case 1:
- ws281x_colorWipe_lr(ws281x_color(50, 0, 0), ws281x_freq_num); // red
- break;
- case 2:
- ws281x_colorWipe_lr(ws281x_color(0, 50, 0), ws281x_freq_num); // green
- break;
- case 3:
- ws281x_colorWipe_lr(ws281x_color(0, 0, 50), ws281x_freq_num); // Blue
- break;
- case 4:
- ws281x_colorWipe_lr(ws281x_color(50, 50, 50), ws281x_freq_num); // white
- break;
-
- default:
- ws281x_colorWipe_lr(ws281x_color(50, 0, 0), ws281x_freq_num); // red
- break;
- }
- }
- /***************************************************************************************************/
- 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
- {
- tran = 255 - tran;
- if(tran < 85)
- {
- switch(color_mode)
- {
- case 1:
- return ws281x_color(tran * 3, 0, 0);
- case 2:
- return ws281x_color(0, tran * 3, 0);
- case 3:
- return ws281x_color(0, 0, tran * 3);
- default:
- return ws281x_color(tran * 3, 0, 0);
- }
- }
-
- if(tran < 170)
- {
- tran -= 85;
- switch(color_mode)
- {
- case 1:
- return ws281x_color(255, 0, 0);
- case 2:
- return ws281x_color(0,255, 0);
- case 3:
- return ws281x_color(0, 0, 255);
- default:
- return ws281x_color(255, 0, 0);
- }
- }
- tran -= 170;
- switch(color_mode)
- {
- case 1:
- return ws281x_color(255 - tran * 3, 0, 0);
- case 2:
- return ws281x_color(0, 255 - tran * 3, 0);
- case 3:
- return ws281x_color(0, 0, 255 - tran * 3);
- default:
- return ws281x_color(255 - tran * 3, 0, 0);
- }
- }
- void ws281x_colorblnCtrl(uint8_t color_mode) // ws281x_bln_num use timer,mode:red1/green2/blue3
- {
- uint16_t i;
- if( !(ws281x_bln_num == ws281x_bln_oldnum))
- {
- for(i = 0; i < PIXEL_NUM; i++)
- {
- ws281x_setPixelColor(i ,ws281x_colorTran(ws281x_bln_num,color_mode));
- }
- ws281x_show();
- ws281x_bln_oldnum = ws281x_bln_num;
- }
-
- }
- /***************************************************************************************************/
- void ws281x_setPixelColor_wheel_leds(uint16_t n ,uint32_t GRBcolor) //n:0~15 whirling leds
- {
- uint8_t i,k;
-
- for(i = 0; i < 24; i++)
- {
- for(k = 0;k < PIXEL_NUM;k++)
- {
- pixelBuffer[k][i] = WS_LOW;
- }
- pixelBuffer[n][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- if( n < PIXEL_NUM/2)
- {
- pixelBuffer[n + (PIXEL_NUM/2)][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- }
- else
- {
- pixelBuffer[n - (PIXEL_NUM/2)][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- }
- }
- ws281x_show();
- }
- void ws281x_display(void)
- {
- if(ws281x_led_display_mode == 1)
- {
- ws281x_colorblnCtrl(ws281x_bln_mode);
- }
-
- if(ws281x_led_display_mode == 2)
- {
- ws281x_colorWipe_freq(ws281x_freq_color_type);
- }
- if(ws281x_led_display_mode == 3)
- {
- ws281x_setPixelColor_wheel_leds(ws281x_whirl_index,
- ws281x_color(color_R[ws281x_whirl_colortran_index],
- color_G[ws281x_whirl_colortran_index],
- color_B[ws281x_whirl_colortran_index])) ;
- }
- }
- /*
- void ws281x_setPixelColor_11x44leds(uint16_t n ,uint32_t GRBcolor) //PIXEL_NUM:11x44 leds n:0~10
- {
- uint8_t i,k,p,q;
-
- for(i = 0; i < 24; i++)
- {
- for(k = 0;k < 44;k++)
- {
- for(q = 0 ;q < (n +1);q++)
- {
- pixelBuffer[q + k*11][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
- }
- for(p = 1;p < (10-n);p++)
- {
- pixelBuffer[(n + p) + k*11][i] = WS_LOW;
- }
- }
- }
- }
- */
复制代码
效果视频
https://v.qq.com/x/page/u3354xdptxh.html
原理图: 无
仿真: 无
Keil代码下载:
程序.7z
(180.19 KB, 下载次数: 374)
|