STM32用PWM +DMA驱动 WS2811原理解析
WS2811的时序波形如下图:
注意:这里是低速模式(400KHz)的时间要求,我们用的是800KHz,需要把时间除以2.
我们的RGB方案是将RGB数据通过DMA发送到timer的CCR寄存器,动态改变timer输出的PWM占空比,来驱动RGB。这里DMA发送给timer的数据,是我们经过转换的RGB所需的时序数据。
这个方案的重点是理解怎么转化这个RGB需要的时序数据!
【在设定好自动重装载寄存器ARR = 35后,动态改变比较寄存器TIMx_CCRx的值,来达到改变输出的占空比的目的】
先把相关关键代码贴出来!
1.定时器配置,重点是 【计数器自动重载寄存器 (TIMERx_CAR)】=34+1
1 timer_initpara.prescaler = 2; //时钟预分频数 84M/(34+1)/(2+1) = 0.8mHz = 800KHz 2 timer_initpara.alignedmode = TIMER_COUNTER_EDGE; //向上&向下都是边沿对齐 3 timer_initpara.counterdirection = TIMER_COUNTER_UP; 4 timer_initpara.period = 34; /* 自动重装载寄存器周期的值(计数值) */ 5 timer_initpara.clockdivision = TIMER_CKDIV_DIV1; 6 timer_initpara.repetitioncounter = 0; 7 timer_init(TIMER3, &timer_initpara);
2.RGB的逻辑数据
1 // BLUE data 2 for ( j = 0; j < 8; j++ ) 3 { 4 if ( ( color[ led ][ 2 ] << j ) & 0x80 ) // data sent MSB first, j = 0 is MSB j = 7 is LSB 5 { 6 if(memaddr<500) 7 { 8 LED_BYTE_Buffer[ memaddr ] = 17; // compare value for logical 1 9 } 10 } 11 else 12 { 13 if(memaddr<500) 14 { 15 LED_BYTE_Buffer[ memaddr ] = 9; // compare value for logical 0 16 } 17 } 18 memaddr++; 19 }
好了,现在可以进行解析这段美妙的代码逻辑了。
我们知道WS2811是有自己的1 code & 0 code的时序要求的,就拿0 code来分析。
我们想要发给WS2811一个0,就需要发一个占空比如下的波形:
WS2811所需的时钟周期是1/800KHz = 1.25us
T0H = 0.5us/2 ± 0.15us = 0.25 ± 0.15us
带入数据计算:
(35-27)/35 * 1.25 us = 0.32 us;满足T0H的时间要求。
同理 T0L = 2.0us/2 ± 0.15us = (35-9)/35*1.25us = 0.93 us;满足T0L的要求
当读懂这段代码时真的是豁然开朗并惊为天人,这种应用真是太帅了!
本文来自博客园,作者:xjxcxjx,转载请注明原文链接:https://www.cnblogs.com/xjxcxjx/p/15637859.html,谢绝CSDN转载!