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的要求

 

 

 當讀懂這段代碼時真的是豁然開朗並驚為天人,這種應用真是太帥了!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM