DMA Timer 產生 PWM 多出乙個波形問題

2021-10-08 02:32:55 字數 1432 閱讀 6951

我在除錯ws2812的時候,發現燈光的資料一直和預想的不符合,簡化了程式邏輯依然看不出有什麼問題,最後通過邏輯分析儀發現,pwm多出了乙個波形,明顯的,這導致所有的資料錯了一位。

事實上這不是硬體上的bug,猜測原因:因為每一次dma請求是timer的溢位中斷產生的,所以在dma請求前,就已經有乙個pwm產生了,那麼從時序看上,就多出乙個pwm波形,但這並不是dma產生的。

uint16_t test_arr[48]

=;hal_tim_pwm_start_dma

(&htim1,tim_channel_1,

(uint32_t *

)test_arr,(48

));

在上面的程式中,按道理應該產生48個波形,但是我卻觀察到了49個,而且第乙個波形是第二個陣列的值決定的。也就是說,他似乎搬運的陣列為:

uint16_t test_arr[48]

=;

一開始我用的是資料填充函式出現是資料錯位問題,所以我用了以上這種原始陣列的方式,排除我資料填充函式的邏輯錯誤,後來才發現,當dma傳輸結束以後,會繼續新的傳輸,然後產生乙個中斷,當dma完成中斷被呼叫時候,dma已經搬運到第二個值了,所以此時,定時器的占空比就為第二個值。

如果需要定時器不要產生乙個波形,那麼只需要根據情況,在dma完成中斷以後,通過把占空比設定為0或者0xff,讓其下次的波形為高電平或者是低電平即可。

在測試過程中,還發現乙個奇怪的問題,以下程式仍然可以產生多乙個pwm波形:

volatile

int cnt =0;

void

hal_tim_pwm_pulsefinishedcallback

(tim_handletypedef *htim)

hal_tim_pwm_stop_dma

(&htim1,tim_channel_1)

;__hal_tim_set_compare

(&htim1,tim_channel_1,0)

;}void

hal_tim_pwm_pulsefinishedhalfcpltcallback

(tim_handletypedef *htim)

這段程式多了乙個cnt++計數,我做了一些測試,發現這個bug產生的條件比較苛刻,必須同時滿足:

程式還包含一些其他測試語句,刪除以後發現這個 bug 消失了,或許是陣列越界問題?

經過進一步的測試,原始檔存在兩個192 x 2 位元組的大陣列:

uint16_t pulse[

192]=;

uint16_t data[

192]

;

其中,刪除掉 pulse[192]陣列即可(不刪除pulse而換作刪除 data 則不行) = =!

PWM產生方法

通常的思路 1.分立原件搭建 2.專用晶元搭建 3.使用mcu產生 方法1,入門門檻高,電路複雜,發生故障的點多,增加生產和維護的難度。方法2,使用上欠缺靈活,什麼時候開,什麼時候不開,開多大,需要配合外部電路。方法3,使用mcu,能做延時,能產生各種各樣週期與占空比的波形,唯一劣勢是需要一定的開發...

PWM的原理和PWM波的產生

脈衝寬度調製 pulse width modulation,pwm 簡單來說就是通過調節方波占空比達到代替其他波形的效果。因為是數碼訊號,不易受干擾。如圖,正弦波是輸入訊號,三角波是載波訊號,在兩者的交點之間輸出高電平,因為三角波週期一定,所以輸出的就是週期一定,占空比改變的pwm波,電路的實現需要...

通用定時器產生PWM

這裡給出乙個公式 tout arr 1 psc 1 tclk 其中 tclk tim3 的輸入時鐘頻率 單位為 mhz 注意這裡的單位,正常情況下由systeminit 函式配置掛載在apb1的通用定時器2 7皆為72mhz。tout tim3 溢位時間 單位為 us 根據上一節 定時器中斷 和本節...