STM32定時器中的更新操作與更新事件

我們知道【如果不知道先假設知道】,STM32定時器中的四個帶影子特性的寄存器組,每組寄存器分別由 影子寄存器【即實際控制寄存器】和預裝寄存器組成。其中,影子寄存器是真正起作用的控制寄存器,用戶訪問不到它。而預裝寄存器是用戶訪問的爲實際影子寄存器準備數據或指令的寄存器。它們分別是:

TIMx_PSC 分頻寄存器 TIMx_ARR 自動重裝載寄存器

TIMx_CCR捕捉寄存器 TIMx_RCR 重複計數寄存器[高級定時器有】

‍其中,ARR、CCR寄存器帶預裝載使能控制位:

TIMx_ARR 帶預裝載使能控制位 ARPE@TIMx_CR1

TIMx_CCR 帶預裝載使能控制位 OCxPE@TIMx_CCMR

當相應預裝使能位置1時,即開啓預裝功能時,此時影子寄存器的數據更新必須且只能通過更新事件實現從預裝寄存器到影子寄存器的數據拷貝。

當相應預裝使能位置0時,即關閉預裝功能時,用戶修改預裝寄存器的數據後會立即被拷貝進影子寄存器【實際寄存器】。也就是說,此時我們用戶操作預裝寄存器就相當於訪問實際影子寄存器。

‍另外的PSC、RCR‍寄存器是不帶預裝使能控制位的,也就是說,二者的影子寄存器的預裝功能始終開啓,對於PSC/RCR影子寄存器的數據更新就只能通過更新事件唯一途徑實現從預裝寄存器到影子寄存器的數據拷貝更新。

cc3a0390f7f54811b68cc655172e15ed.pnguploading.4e448015.gif轉存失敗重新上傳取消

那麼有哪些操作可以產生更新事件呢?或者有哪些更新事件源呢?

這裏把更新操作跟更新事件區別開來,以便於概念上的理解。

更新操作是一種動作,是更新事件的源頭,即事件源;

更新事件是基於更新操作所導致的後續影響或結果。

可能的更新操作【事件源】有3類:

1、核心計數器的溢出【上溢或下溢】

2、軟件復位操作【對UG@TIMX_EGR置位】

3、工作在復位模式下的定時器收到觸發信號【即復位觸發信號】

【特別提醒,對於高級定時器必須發生RCR+1次溢出動作後纔可以產生更新事件。對於通用或基本定時器,每溢出一次就可以產生更新事件。】

那麼更新操作何時可以升級爲更新事件呢?這裏涉及到一個控制寄存器的控制位,UDIS@TIMx_CR1.

當該控制位UDIS@TIMx_CR1爲0時,更新操作升級爲更新事件,更新事件會產生如下影響或效果:

1、‍實現從預裝寄存器的數據到影子寄存器的內容拷貝,即完成影子寄存器的內容更新;

2、實現計數器【預分頻計數器、核心計數器、重複計數器】的重新初始化;

3、置位狀態寄存器的更新中斷請求【UIF@TIMx_SR】位,並可以觸發定時器更新中斷或觸發DMA請求;

當‍該控制位UDIS@TIMx_CR1爲1時,更新操作不能升級爲更新事件,其相應的結果或影響:

僅限於計數器的重新初始化,影子寄存器不做內容更新;

無更新標誌的置位,不觸發中斷或DMA請求

那麼發生更新操作時計數器的重新初始化具體是指什麼呢?

1、分頻計數器重裝爲0,然後重新開始計數;

2、重複計數器重裝爲RCR寄存器裏的值,然後重新遞減計數;

3、核心計數器的初始化由計數模式來定,如果是向上計數或中心對齊計數模式,CNT歸0;如果是向下計數器模式,CNT重裝爲ARR,然後重新向下計數;

發生更新事件時,影子寄存器的更新與計數器的重裝有先後順序嗎?

有!影子寄存器【ARR/CCR….】的更新操作在前,計數器的重裝操作在後!

因爲這樣可以保障計數器的重裝值使用更新過的數據。該個細節要特別注意!

最後,不妨做個基於更新事件的案例分享:

問題描述:TIMER初始化階段,經常有人反饋,不管定時器週期的長短,只要一使能更新中斷,就立即進中斷服務程序?令人不解,往往給開發帶來些困擾,原因可能是什麼?如何解決?

我們知道,定時器應用的初始化時,往往需要對有關時基寄存器進行些基本的數據賦值。比方對ARR/PSC/RCR這些寄存器賦予初始值。結合前面的介紹,這些寄存器都是些帶預裝功能的寄存器,我們用戶操作的寄存器都是預裝寄存器,還不是實際起作用的影子寄存器。

對於ARR寄存器倒還好,因爲芯片復位後默認狀態下,ARR寄存器的預裝功能是關閉的【CCR寄存器的預裝載功能默認條件下也是關閉的】,那麼我們用戶給ARR賦值就相當於給其實際影子寄存器賦值了。

PSC/RCR寄存器是不帶預裝控制位的,前面也說了,它們兩個的影子寄存器的更新必須藉助於更新事件。所以,在定時器的時基參數的初始化代碼裏,爲了讓用戶寫進預寄存器的數據生效,就用到了上面提到過的軟件復位操作,即對UG@TIMx_EGR進行置位而產生更新事件,從而完成影子寄存器的數據更新。

在STM32標準庫裏的TIM_TimeBaseInit( )函數裏都有如下代碼:

TIMx->EGR =TIM_PSCReloadMode_Immediate;

在Cube庫裏的HAL_TIM_Base_Init( )函數裏的函數有如下代碼:

TIMx->EGR = TIM_EGR_UG;

‍結合前面的介紹,這兩行代碼使用的軟件更新操作產發了更新事件,但它不僅僅實現了影子寄存器的數據更新,同時呢,還置位了狀態寄存器的更新中斷請求標誌位UIF@TIMx_SR。那麼,如果在這之後,我們使能定時器更新中斷的話,進入更新中斷服務程序就再自然不過了。爲了規避這個問題,我們在時基參數初始化完成之後、使能定時器更新中斷之前,可以先做更新中斷標誌的清除操作。

基於這個案例,我們可以對定時器的影子特性以及不同影子寄存器的預裝特性差異有進一步的瞭解。總的來講,STM32定時器的寄存器預裝載特性也是其一特色,定時器的更新事件也是個非常重要的事件,更新事件本身及相關中斷或DMA功能也是STM32開發應用中常用的工具。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章