WS2812B驱动
#include "stm32f10x.h"
#include "TIM2.h"
#include "DMA1.h"
//#define WS2812B_LED_QUANTITY 32 //灯珠数量
#define WS2812B_LED_QUANTITY 12 //灯珠数量
//定义数组 类型符 数组名[常量]
uint32_t WS2812B_Buf[WS2812B_LED_QUANTITY]; //0xGGRRBB 正常的数据口输入,然后配置就行,绿红蓝总共24位,只有32
uint16_t WS2812B_Bit[24*WS2812B_LED_QUANTITY+1];//灯珠数量*24bit+1 颜色位数+复位信号 根据数据手册可知还要加复位信号0(正常的0),因此需要写入 num24+reset(reset=?自己调) 位。
uint8_t WS2812B_Flag;
void WS2812B_IRQHandler(void);
void WS2812B_Init(void)
{
DMA1_SetIRQHandler(WS2812B_IRQHandler);//把WS2812B_IRQHandler赋给DMA1_Handler
DMA1_Init((uint32_t) (&WS2812B_Bit));//灯位量的地址存放到DMA 这时DMA就是灯珠的量 强制类型转换 不足的高位补0
TIM2_Init();//定时器
} //用TIM2开PWM 送给DMA
void WS2812B_ClearBuf(void)//把LED的RGB数组值清零,全部输出0码,变成黑色,即不发光
{
uint8_t i;
for(i=0;i<WS2812B_LED_QUANTITY;i++)
{
WS2812B_Buf[i]=0x000000;//24位的二进制数 6位的16进制数
}
}
void WS2812B_SetBuf(uint32_t Color) //设置显示相同的颜色
{
uint8_t i;
for(i=0;i<WS2812B_LED_QUANTITY;i++)
{
WS2812B_Buf[i]=Color;//BUF是颜色,设置成同一个颜色,初始统一设置成不发光
}
}
void WS2812B_UpdateBuf(void) //30和60对应不同的高电平时间也对应了时序的0码和1码 占空比控制亮灭 CCR和AAR+1共同决定的
{
uint8_t i,j;
for(j=0;j<WS2812B_LED_QUANTITY;j++) //遍历每个LED
{
for(i=0;i<24;i++) //遍历每个LED的颜色数据的每一位 10000000 00000000 00000000
{
if(WS2812B_Buf[j]&(0x800000>>i)){WS2812B_Bit[j*24+i+1]=60;}//0x800000为二进制的1加23个0,>>:右移
else{WS2812B_Bit[j*24+i+1]=30;} //每一位,取值范围是0到23,所以再加1
}
}
DMA1_Start(24*WS2812B_LED_QUANTITY+1);
TIM2_Cmd(ENABLE);
while(WS2812B_Flag==0);
WS2812B_Flag=0;
}
void WS2812B_IRQHandler(void) //定时器2 开PWM 直接就是根据时序占空比设置控制灯条
{
TIM2_SetCompare1(0);//pwm设置
TIM2_Cmd(DISABLE);//关闭定时器
WS2812B_Flag=1;
}
这段代码用于控制WS2812B LED灯条,通过STM32微控制器的定时器和DMA(直接存储器访问)来实现数据传输。WS2812B是一种常见的RGB LED灯条,每个灯珠可以独立控制红、绿、蓝三种颜色的亮度。以下是这段代码的作用及含义:
代码作用
-
定义和初始化:
WS2812B_Buf
:一个数组,用于存储每个LED的颜色数据,每个LED的颜色由24位组成(8位绿、8位红、8位蓝)。WS2812B_Bit
:一个数组,用于存储传输给WS2812B的位数据,包含所有LED的24位数据和一个复位信号位。总长度为24*WS2812B_LED_QUANTITY + 1
。WS2812B_Flag
:一个标志位,用于指示数据更新完成。
-