STM32G0 定时器PWM DMA输出驱动WS2812配置 LL库

通过DMA方式输出PWM模拟LED数据信号

优点:不消耗CPU资源

缺点:占用内存较大

STM32CUBEMX配置

定时器配置

定时器通道:TIM3 CH2

分频:0

重装值:79,芯片主频64Mhz,因此PWM输出频率:64Mhz/79 ≈ 800Khz,满足芯片要求。

auto-reload preload 要关闭

output compare preload 要打开

DMA配置

外设一定要选择TIM3_UP,不要选TIM_CHx

方向是内存到外设,和ADC是反的

模式选择Circular,也可以选择Normal,每次要写的时候才发送,这里为了方便选Circular。
重要:数据宽度,外设选择half word,内存选择byte,可以省空间

添加初始化代码

c 复制代码
void Activate_TIM3_DMA(void)
{
	/* Set DMA transfer addresses of source and destination */
	LL_DMA_ConfigAddresses(DMA1,
	LL_DMA_CHANNEL_1,			//DMA通道,需与cubeMX设置的一致
	(uint32_t)&LED_LEVEL_buff,  //DMA要传输的数组
	(uint32_t)&TIM3->CCR2,		//DMA传输的寄存器地址,TIM3_CH2
	LL_DMA_DIRECTION_MEMORY_TO_PERIPH);		//传输方向
  
  /* Set DMA transfer size */
	LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_1,384);	//DMA传输长度,根据灯的数量定,384=16*24
	
   /* 开启定时器和DMA */
	LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_1);
	LL_TIM_CC_EnableChannel(TIM3, LL_TIM_CHANNEL_CH2);
	LL_TIM_EnableAllOutputs(TIM3);
	LL_TIM_EnableCounter(TIM3);
	LL_TIM_EnableDMAReq_UPDATE(TIM3);
}

添加LED电平代码

c 复制代码
#define TL    20 		//写0电平占空比= 20/(79+1) 79为定时器重装值
#define TH    55 		//写1电平时间

/*LED数据传输电平数组*/ /*多余的4个数组是RESET信号,需大于80us*/
vu8 LED_LEVEL_buff[16][24] = {
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led0*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led1*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led2*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led3*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led4*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led5*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led6*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led7*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led8*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led9*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led10*/
TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,   TL, TL, TL, TL, TL, TL, TL, TL,/*led11*/
0};

这里一共12个灯,每个灯需24bit,定义16组数据是因为WS2812发送完所有数据后需要80us的低电平信号,剩下4组数据为80us的低电平信号。

已知每个信号宽度为1.25us,算下来为800Khz,这个非常重要,因此TIM重装值必须为79。

计算0码的长度,也就是占空比,占空比= 20/(79+1),时间大概为0.31us,满足需求

计算1码的长度,也就是占空比,占空比= 55/(79+1),时间大概为0.86us,满足需求

当要更改灯光颜色的时候,修改LED_LEVEL_buff就行了,效率很高,缺点是需要占用较大的内存空间,由于CPU主频很低,重装值不会超过79,因此数组用8位就够了,32位纯属浪费空间,所以DMA内存长度一定要和数组匹配,否则会出现波形混乱。

相关推荐
H_oRIZoN_3 分钟前
Linux入门DAY40(51 单片机入门:GPIO、中断、定时器、PWM、蜂鸣器完整梳理)
单片机·嵌入式硬件
LCG元42 分钟前
STM32F103 复位来源诊断实战:RCC_CSR 标志位判优、BKP 复位计数持久化与六种复位源注入实测
stm32·单片机·嵌入式硬件
HUI-4742 小时前
EG1177|SOP‑7 内置 100V‑NMOS 异步降压,20‑90V 高压恒压恒流小功率电源优选
嵌入式硬件·硬件工程
Doraemomo3 小时前
IMX6ULL裸机开发——I2C通信协议
arm开发·嵌入式硬件·imx6ull
国产HT1621B3 小时前
显示省不了电,休眠才见真章:1621 低功耗实操
驱动开发·单片机·嵌入式硬件·led驱动·lcd驱动
zhangzhangkeji4 小时前
stm32 5-2 : 中断,代码篇,对射式红外计数器,旋转编码器。 本 M3中等密度的中断向量列表
stm32
尼喃4 小时前
Type-C快充取电芯片工作流程:从适配器识别到电压输出
嵌入式硬件
昌原的儿子LEO5 小时前
ARM 汇编核心知识点总结
嵌入式硬件·学习
老当益壮梁奶奶5 小时前
ARM 汇编学习笔记(二)启动代码、指令、函数调用与 C 混合编程
c语言·arm开发·单片机·嵌入式硬件·51单片机
学习FPGA的电气小兴兴5 小时前
基于FPGA的CORDIC向量模式实现arctan运算,Verilog HDL实现
嵌入式硬件·fpga开发·数字信号处理·verilog·fpga·cordic·arctan