西安建设公司网站,网络游戏大型,社区教育网站建设项目计划书,免费空间说说点赞通过DMA方式输出PWM模拟LED数据信号
优点#xff1a;不消耗CPU资源 缺点#xff1a;占用内存较大
STM32CUBEMX配置
定时器配置
定时器通道#xff1a;TIM3 CH2 分频#xff1a;0 重装值#xff1a;79#xff0c;芯片主频64Mhz#xff0c;因此PWM输出频率#xff1a…通过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可以省空间
添加初始化代码
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_CH2LL_DMA_DIRECTION_MEMORY_TO_PERIPH); //传输方向/* Set DMA transfer size */LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_1,384); //DMA传输长度根据灯的数量定38416*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电平代码
#define TL 20 //写0电平占空比 20/(791) 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/(791)时间大概为0.31us满足需求 计算1码的长度也就是占空比占空比 55/(791)时间大概为0.86us满足需求 当要更改灯光颜色的时候修改LED_LEVEL_buff就行了效率很高缺点是需要占用较大的内存空间由于CPU主频很低重装值不会超过79因此数组用8位就够了32位纯属浪费空间所以DMA内存长度一定要和数组匹配否则会出现波形混乱。