有人使用STM32定時器的PWM功能,遇到點小疑問,這里一起看看。
他先將STM32某定時器計數周期設為0xff,單向遞增計數模式,OC比較值設為0x7F。在某時刻將新的計數周期0x7F與比較值0x3F加載到影子寄存器。當正在進行的一個周期結束后,經示波器測量確實可以看到其下一個周期發生變化,但其周期明顯與預設值對應不上!再次經過一個周期,定時器才會按照預設值穩定輸出。
以上是咨詢者不算很清晰的描述【其實咨詢TIMER問題最好配上時序圖】,但可以了解到他要做的事情就是在ARR=0xff,ccr=0x7F的PWM輸出狀態下,于某時刻賦予ARR和CCR新值以改變輸出波形。
事情不算復雜,疑點就是為什么需要2個周期延時后才能有基于新配置的穩定輸出。【他這里說的2個周期顯然不清楚到底指的前后哪個周期值】
這個問題主要涉及到定時器寄存器的預裝功能。有些時候我們需要保證輸出波形完整性、連續性,開啟ARR及CCR的預裝功能就比較合適,使用CubeMx配置時做些勾選即可。開啟預裝后,修改ARR及CCR的值,生效時間點最長可能延后1個舊計數周期。不過這里要注意,我們修改ARR及CCR的值若不是特別需求,建議在一個計數周期內完成修改,不要一個值在更新事件之前完成賦值,另一個則發生在該更新事件之后。
我也將上面提醒告知咨詢者,他反饋問題依然沒能解決,準確說是疑惑依然沒能解除。他這里的確只是提出疑惑,并未提出具體需求。另外,他還將問題的復現過程做了如下補充:
第一步:
1 - 關閉預裝載(ARR/CCR)
2 - 設定ARR=CCR=0xFF
3 - 開啟輸出比較功能(連接到示波器查看波形)
第二步:
1 - 設置示波器觸發(延遲一段時間拉高某個IO引腳以觸發示波器采集)
2 - 立即清空CNT
3 - 使能預裝載
4 - 設定ARR=0X7F,CCR=0X3F
現象:本周期結束后其計數周期確實會相應改變,但改變之后的前兩個周期明顯與設定值不符,即經過2個周期后才可穩定輸出。
復現過程表述得比較清晰了,他也再次明確了疑惑點。同時還強調說網上很多人碰到類似問題或疑惑。他在STM32L4系列和STM32H7系列上都遇到了同樣問題。既然這樣,現在我們使用STM32L4系列的TIM1來進行驗證,參照他的操作步驟來組織代碼,看看來龍去脈。
我是這樣測試驗證的。
在關閉ARR/CCR的預裝前提下給二者分別賦值0xff和0x7f,啟動CH1的PWM輸出并使能該通道的輸出比較中斷。在第一個脈沖的比較中斷里按照咨詢者的做法修改ARR/CCR值。為了便于觀察效果,我也開啟了更新中斷,通過更新中斷記錄脈沖個數,輸出幾個脈沖后就將定時器及輸出都關閉掉。【選擇PWM模式1,極性為高有效】
編寫代碼、編譯除錯后,運行得到如下結果:【黃色波形結尾的4個脈沖是基于新參數的輸出。綠色波形的上升沿指示修改數據的時間點,這里輔助顯示下,重點在黃色波形。】
上面輸出波形應該說跟客戶反饋的是一致的。我們來一起看看。
在第一個脈沖的比較中斷處,也是第一個脈沖的正中央【紅色箭頭所指位置】處做參數修改。修改步驟按照咨詢者提供的來實現。
即按照上面的3小步操作【第1小步是咨詢者設置示波器的動作,不用理它】。
這里是開啟預裝功能后才修改ARR/CCR值,這兩個新值目前只能暫居預裝寄存器,實際起作用的ARR/CCR值仍是之前的0xff和0x7f。而且,還在此處對計數器做了清零,即從此刻起PWM輸出脈沖重頭來。這樣從上圖紅色箭頭到藍色箭頭之間的波形依然是基于ARR=0xff,CCR=0x7f參數運行的。定時器于藍色箭頭所指位置處發生更新事件,新數據【0x7f,0x3f】生效起作用。
顯然從修改時刻算起到數據生效 剛好延時1個舊周期,結合到這里,恰好是新周期的2倍。修改數據后整整花了2個周期的時間才生效就是這么來的。
如果在上面操作步驟的基礎上拿掉對計數器清零操作,其它不變,輸出結果又不一樣了。見下面截圖:
同樣,紅色箭頭所指位置為修改數據的時刻。由于此時沒有對計數器清零,計數器按部就班計數,PWM輸出按預定配置輸出,繼續運行半個舊周期后計數器溢出產生更新事件于藍色箭頭所指位置。藍色箭頭所指位置以后PWM輸出按新參數運行。不難看出,這次新數據的生效從修改時刻算起僅延時半個舊周期,相當于后續的1個新周期。
這里強調下,我這里測試時選擇的剛好是舊周期的中間點,所以延時生效為半個舊周期。具體應用時的延時跟我們修改參數所選的時間點有關,一般來講,它最長不會超過1個舊周期,最短極限為0。
當然,如果說我們不關心修改數據前后波形的完整性,直接關閉預裝功能也行,或者手動產生更新事件也可以。總之,我們根據實際應用需求來定。
聊到這里,關于咨詢者的疑惑基本解釋得差不多了。
或許眼尖的人看到上面第一種操作輸出的PWM波形里面有個非常細窄的尖脈沖,它是怎么回事呢?示波器問題?非也!【見下圖橢圓形框住的細長線】
此處尖脈沖產生的原因是------
當發生比較中斷時我們才去做修改參數動作,在做計數器清零操作前,計數器的值已經大于設置的CCR值【0x7f】,按照當前PWM輸出模式及極性選擇,輸出則變為低電平了。但是,在中斷里我們很快又將計數器值做了個清零,此時計數器值又小于CCR值【0x7f】了。同樣,按照當前PWM配置,輸出又變回高電平,最終就產生了這么個一下一上的尖脈沖。【注:這里涉及PWM輸出原理,需要的自行補課。】
-
STM32
+關注
關注
2270文章
10915瀏覽量
356765 -
控制
+關注
關注
4文章
1013瀏覽量
122706 -
定時器
+關注
關注
23文章
3254瀏覽量
115076
發布評論請先 登錄
相關推薦
評論