STM32 G431RB 中實現對WS2812燈帶的控制(PWM + DMA)


項目中需要對WS2812燈帶進行控制,項目中的燈帶是21顆等,需求要求對所有的LED等設置顏色的時候是統一的顏色,

如果需要設置不同的顏色,也可以參考代碼進行修改。

實現方式是 PWM + DMA的方式,一次將21顆燈的顏色值都設定好。

參考的是這篇英文文章來實現的。 Interface WS2812 with STM32(https://controllerstech.com/interface-ws2812-with-stm32/)

我的代碼實放在Github上了。 https://github.com/magicduan/demo_pwm_dma

我的板子是G431RB,處理上稍微有些不同,詳細的原理等就不在這里說明了,這里整理一下按照這個參考例子開發出的問題。

  • Direction需要設置為 "Memory To Peripheral",也就是將Memory的內容搬運到PWM寄存器中。開始設置的時候沒有注意,時間浪費了。
  • Mode 設置為"Normal", 有的例子文章說要設置為"Circular". "Normal"與"Circular"的區別是,"Normal" Mode下DMA搬運完數據后就不再自動繼續搬了,“Circular” Mode會自動的循環搬運數據
  • 英文文章中Data Width 是Peripheral :Half Word, Memory:Half Word. 選Half Word的原因是PWM的Counter Period是16 bit的。我之前是參考英文文章做的,這樣處理沒有什么問題,就是PWM 的Buffer的需要用uint16_t保存Duty Value。而我的Counter Period是(75-1),也就是最大值是75,使用uint8_t就可以,這樣能節省一半的內存。  由於其他代碼的需要我這邊的代碼的實際處理是 Presaler = 15-1, Counter Period = 5-1. 

              

 

  • 由於我Memory的Data Width是Byte,這里就碰見了字節對齊問題
  • Buffer聲明的時候需要邊界對齊
  • #define DMA_TYPE  uint8_t
    __attribute__((aligned(4))) volatile  DMA_TYPE pwm_buffer[BUFFER_LEN];

     

  • 今天碰見一個巨大的坑,STM32 CubeIDE生成代碼的時候有Bug,在main函數中DMA初始化順序與TIM的初始化順序的問題,STM32 CubeIDE有時候生成的是反的,反了DMA執行就會被卡在,執行不成功。花了很長時間比較代碼才找出來。具體的原因參考這篇CSD的文章(STM32 DMA傳輸的Bug)
  • 正常順序:
  •   MX_DMA_Init();
      MX_TIM1_Init();

    錯誤順序:

  • MX_TIM1_Init();  
    MX_DMA_Init();

     

 


免責聲明!

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



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