标题:
STM32驱动WS2812呼吸灯、频谱,变色变速旋转源程序
[打印本页]
作者:
feeling1791
时间:
2022-9-5 16:43
标题:
STM32驱动WS2812呼吸灯、频谱,变色变速旋转源程序
网上看到些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, 下载次数: 376)
2022-9-7 02:25 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
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
原理图能继续分享一下吗?
作者:
hei51com
时间:
2023-2-24 09:33
效果很赞,感谢分享,收藏备用
作者:
Jshenliu
时间:
2023-3-27 14:19
沙发,收藏备用
作者:
wuhaijie
时间:
2023-9-13 06:06
下载来看看,确实很牛···还带变速的,谢谢楼主分享,学习学习
作者:
IdeaMing
时间:
2023-11-10 09:45
幅度的动态跟随,请大佬详解
作者:
maijinzhi
时间:
2023-11-22 09:28
不写注释,真是一个不好的习惯
作者:
山海靓仔
时间:
2023-12-19 17:54
就冲你这句吊打一切,无论能不能点亮,都要给你点赞
作者:
啦啦啦ajih
时间:
2023-12-25 11:20
博主,求求了,原理图可以分享一下吗
作者:
feeling1791
时间:
2023-12-26 15:43
啦啦啦ajih 发表于 2023-12-25 11:20
博主,求求了,原理图可以分享一下吗
某一个宝买块16 RGB的灯环,然后买块最小系统STM32F103C8T6板,再买个ST LINK下载小板,总共应该50元左右吧,把灯环输入接电源+5V,GND,灯环数据输入焊点DATA接最小系统板的PB8脚,然后编译程序下载到单片机,再上电就可以看效果了,电路图,你买这些小板老板都会给你图纸的
作者:
点不亮灯大师
时间:
2024-2-29 11:47
怎么玩啊,兄弟盟
作者:
wifingtta
时间:
2024-3-1 14:21
感谢楼主!用C8T6测试过,程序完全可用,有三种模式,2812接PB8口,定时器自动切换模式,灯的数量不限,直接改参数即可。只是注释确实太少,勉强看懂一点,再看看。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1