之前一篇文章写了使用IO控制WS2812b操作原理,但是由于IO的输出比较慢,所以现在改用了硬件SPI控制WS2812b灯条
把SPI的mosi线接到ws2812b的数据线,SPI的速率可达十几Mbit/s,如此高的传输速率,我们可以使用一个(uint8_t)类型的数据代表一个码1或者码0;
也就是说,本来控制一个灯珠的数据由3个Byte(24位)变成了24Byte,每个bit转换成一个Byte;
具体看时钟如何配置的。
SPI配置:
在上一篇文章可以看到控制一个码的周期在1.25us±300ns之间,现在把时钟配成9Mbit/s,这个的话每个码的周期大概就在889ns,和LED的周期略有误差;
从规格书上可以看到码1和码0的占空比是大致分配一下1个byte的8个bit;
我这里分配的是
码1:0xF8;
码0:0xE0;
可以根据自己的具体情况取修改码0和码1的分配,下面是驱动ws2812b的代码:
ws2812b.h
#ifndef __WS2812B_H__
#define __WS2812B_H__
#include // 编码 0 : 11100000 #define CODE_0 0xE0 // 编码 1 : 11111000 #define CODE_1 0xF8 /*ws2812b灯珠数量*/ #define WS2812B_AMOUNT 8 typedef struct { uint8_t R; uint8_t G; uint8_t B; } tWs2812bCache_TypeDef; extern tWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT]; void WS2812b_Set(uint16_t Ws2b812b_NUM, uint8_t r,uint8_t g,uint8_t b); void WS2812B_Task(void); #endif ws2812b.c #include 'ws2812b.h' #include 'spi.h' //灯条显存SPI数据缓存 uint8_t gWs2812bDat_SPI[WS2812B_AMOUNT * 24] = {0}; //灯条显存 tWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT] = { //R G B 0X0F, 0X0F, 0X0F, //0 0X0F, 0X0F, 0X0F, //1 0X0F, 0X0F, 0X0F, //2 0X0F, 0X0F, 0X0F, //3 0X0F, 0X0F, 0X0F, //4 0X0F, 0X0F, 0X0F, //5 0X0F, 0X0F, 0X0F, //6 0X0F, 0X0F, 0X0F, //7 }; void WS2812b_Set(uint16_t Ws2b812b_NUM, uint8_t r,uint8_t g,uint8_t b) { uint8_t *pR = &gWs2812bDat_SPI[(Ws2b812b_NUM) * 24 + 8]; uint8_t *pG = &gWs2812bDat_SPI[(Ws2b812b_NUM) * 24]; uint8_t *pB = &gWs2812bDat_SPI[(Ws2b812b_NUM) * 24 + 16]; for(uint8_t i = 0; i < 8; i++) { if(g & 0x80) { *pG = CODE_1; } else { *pG = CODE_0; } if(r & 0x80) { *pR = CODE_1; } else { *pR = CODE_0; } if(b & 0x80) { *pB = CODE_1; } else { *pB = CODE_0; } r <<= 1; g <<= 1; b <<= 1; pR++; pG++; pB++; } } void WS2812B_Task(void) { uint8_t dat = 0; //将gWs2812bDat数据解析成SPI数据 for(uint8_t iLED = 0; iLED < WS2812B_AMOUNT; iLED++) { WS2812b_Set(iLED, gWs2812bDat[iLED].R, gWs2812bDat[iLED].G, gWs2812bDat[iLED].B); } //总线输出数据 HAL_SPI_Transmit(&hspi1, gWs2812bDat_SPI, sizeof(gWs2812bDat_SPI), 100); //使总线输出低电平 HAL_SPI_Transmit(&hspi1, &dat, 1, 100); //帧信号:一个大于50us的低电平 HAL_Delay(1); } 直接在main()里面调用WS2812B_Task()就可以驱动灯条,另外直接修改数组gWs2812bDat就可改变灯条的颜色。
上一篇:STM32CubeMX+w25qxx
下一篇:STM32+LWIP+FTP客户端下载文件
推荐阅读最新更新时间:2026-03-23 10:48
- LDK120M12R 1.2V低压降稳压器典型应用(可调版)电路
- EVB-UTC2000-DFP、EVK-UTC2000 评估套件基于 UTC2000 USB 3.0/2.0 Type-A,即插即用 Type-C DFP
- LTC3219 演示板、250mA 通用九通道 LED 驱动器
- DC919A-D,LTC2204 CMOS 输出演示板,直流输入,40Msps 16 位 ADC,DC
- AD8618ARZ-REEL 二阶低通滤波器运算放大器的典型应用电路
- 使用 NXP Semiconductors 的 PCA9511A 的参考设计
- LT3091MPDE 恒流恒压实验室电源的典型应用
- ADR392B 4.096 Vout 微功率、低噪声精密电压基准的典型应用
- LT3470HDDB 5V 降压转换器的典型应用电路
- 使用 Diodes Incorporated 的 AZ7042ZTR-E1 的参考设计
- 本周机器人行业大事件TOP5
- G20周刊|埃斯顿与北自所达成战略合作、海康机器人发布光伏组件汇流带视觉检测解决方案
- 14家工业智能企业入选《上海市智能机器人标杆企业与应用场景推荐目录》
- 大声量 | 2023机器视觉技术与应用峰会议程新鲜出炉!
- 海康机器人视觉检测方案守护光伏组件生产质量
- MIT用3D打印技术,研发出一种可控性机器人,依靠磁力即可控制其动作
- 日本推出协作机器人NEXTAGE,可依客户需求利用3D打印订制所需的手臂
- Cloud Volumes ONTAP for AWS在中国正式发布
- 贸泽开售Maxim DS28E39和DS28E84 DeepCover 认证器
- Navitas创新的GaNFast技术助力新能源汽车高速发展

stm32驱动屏IC rm68042
电机驱动教程
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号