1.WS2812介绍
一个集控制电路与发光电路于一体的智能外控 LED 光源。 其外型与一个 SMD5050 侧发光 LED 灯珠相同, 每个元件即为一个像素点。 像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路, 电源稳压电路, 内置恒流电路, 高精度 RC 振荡器, 输出驱动采用 PWM 技术, 有效保证了像素点内光的颜色高一致性。
- IC控制电路与LED点光源共用一个电源;
- 控制电路与RGB芯片集成在一个5mm直径的圆头四脚直插封装的灯珠中, 构成一个完整的外控像素点;
- 内置信号整形电路, 任何一个像素点收到信号后经过波形整形再输出, 保证线路波形畸变不会累加;
- 内置上电复位和掉电复位电路;
- 每个像素点的三基色颜色可实现256级亮度显示, 完成16777216种颜色的全真色彩显示;
- 扫描频率 2kHz/s;
- 串行级联接口, 能通过一根信号线完成数据的接收与解码;
- 任意两点传传输距离在不超过 2 米时无需增加任何电路;
- 当刷新速率 30 帧/秒时, 级联数不小于 2048 点;
- 数据发送速度可达 800Kbps;
2.WS2812通讯协议
数据协议采用单线归零码的通讯方式, 像素点在上电复位以后, DIN端接受从控制器传输过来的数据, 首先送过来的24bit数据被第一个像素点提取后, 送到像素点内部的数据锁存器, 剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点, 每经过一个像素点的传输, 信号减少24bit。 像素点采用自动整形转发技术, 使得该像素点的级联个数不受信号传送的限制, 仅仅受限信号传输速度要求
从图中可以看出,数字“1”使用长脉宽来编码(占空比为68%),“0”使用短脉宽来编码(占空比为32%)。数据线低电平保持时间大于50us时,为复位信号。复位后,每个LED读取“Din”线上开始的24bit(绿:红:蓝为8:8:8)数据到驱动芯片内部缓存。除了开始的24bit数据,后面的数据都通过“Dout”脚传递到下一个LED,即每经过一个像素点的传输,信号减少24bit。内部缓存数据在下一个复位脉冲后被写入PWM控制器。一个bit为1.25us,一个LED有3*8bits=24bits,传输完 需要24*1.25us=30us。
数据传输方式:
3.使用STM32CubeMX配置工程
- 首先根据选择的芯片(本文使用的是STM32L051C8T6),配置好外设时钟
- 选择外部时钟源
- 配置时钟主频为32M
- 定时器PWM配置,本文使用的是TIM2_CH1通道
- TIM2参数配置:向上计数模式,重载值为41(实际周期为1/T2LCK-(41+1)),不分频,Pulse值决定脉冲宽度,比如我现在ARR值为41,则脉冲宽=Pulse/(41+1),设置占空比26可满足1码的时间要求,设置占空比13可满足0码的时间要求。
- DMA配置注意是内存到外设及数据的宽度
4.工程编译
注意这里在代码中具体用到的时PA5引脚(TIM2的CH1)也可在STM32CubeMX配置时是PA0引脚;
添加WS2812驱动,文件为坛友分享的(驱动文件出处https://blog.youkuaiyun.com/xiaoyuanwuhui/article/details/99639068)
最后在main文件中添加#include "bsp_ws281x.h"头文件,函数中调用代码即可驱动WS2812灯珠了。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
WS281x_CloseAll();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
ws281x_rainbow(250);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
5.参考资料:
WS2812灯珠(三)-- STM32 PWM+DMA方式驱动
6.源代码下载:https://download.youkuaiyun.com/download/cheng_nnan/12325103