stm32定時器/定時器中斷/PWM輸出/輸入捕獲


STM32F4 的通用定時器包含一個 16 位或 32 位自動重載計數器(CNT),該計數器由可編程預分頻器(PSC) 驅動。 STM32F4 的通用定時器可以被用於:測量輸入信號的脈沖長度(輸入
捕獲)或者產生輸出波形(輸出比較和 PWM)等。 使用定時器預分頻器和 RCC 時鍾控制器預分頻器,脈沖長度和波形周期可以在幾個微秒到幾個毫秒間調整。 STM32F4 的每個通用定時器都
是完全獨立的,沒有互相共享的任何資源。

STM3 的通用 TIMx (TIM2~TIM5 TIM9~TIM14)定時器功能包括:

1)16 /32 (TIM2 TIM5)向上、向下、向上/向下自動裝載計數器(TIMx_CNT),注意: TIM9~TIM14 只支持向上(遞增)計數方式。
2)16 位可編程(可以實時修改)預分頻器(TIMx_PSC),計數器時鍾頻率的分頻系數為 165535 之間的任意數值。
34 個獨立通道(TIMx_CH1~4TIM9~TIM14 最多 2 個通道),這些通道可以用來作為:
A.輸入捕獲
B.輸出比較
CPWM 生成(邊緣或中間對齊模式) ,注意: TIM9~TIM14 不支持中間對齊模式
D.單脈沖模式輸出
4)可使用外部信號(TIMx_ETR)控制定時器和定時器互連(可以用 1 個定時器控制另外一個定時器)的同步電路。
5)如下事件發生時產生中斷/DMATIM9~TIM14 不支持 DMA):
A.更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)
B.觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)
C.輸入捕獲
D.輸出比較
E.支持針對定位的增量(正交)編碼器和霍爾傳感器電路(TIM9~TIM14 不支持)
F.觸發輸入作為外部時鍾或者按周期的電流管理(TIM9~TIM14 不支持)

 

下面我們介紹一下與我們這章的實驗密切相關的幾個通用定時器的寄存器(以下均以 TIM2~TIM5 的寄存器介紹, TIM9~TIM14 的略有區別,具體請看《STM32F4xx 中文參考手冊》 對應章節)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 這里,定時器的時鍾來源有 4 個:
1) 內部時鍾(CK_INT
2) 外部時鍾模式 1:外部輸入腳(TIx
3) 外部時鍾模式 2:外部觸發輸入(ETR),僅適用於 TIM2TIM3TIM4
4) 內部觸發輸入(ITRx):使用 A 定時器作為 B 定時器的預分頻器(A B 提供時鍾)。
這些時鍾,具體選擇哪個可以通過 TIMx_SMCR 寄存器的相關位來設置。這里的 CK_INT時鍾是從 APB1 倍頻的來的,除非 APB1 的時鍾分頻數設置為 1(一般都不會是 1),否則通用
定時器 TIMx 的時鍾是 APB1 時鍾的 2 倍,當 APB1 的時鍾不分頻的時候,通用定時器 TIMx的時鍾就等於 APB1 的時鍾。這里還要注意的就是高級定時器以及 TIM9~TIM11 的時鍾不是來
APB1,而是來自 APB2 的。

這里順帶介紹一下 TIMx_CNT 寄存器,該寄存器是定時器的計數器,該寄存器存儲了當前定時器的計數值。

接着我們介紹自動重裝載寄存器(TIMx_ARR),該寄存器在物理上實際對應着 2 個寄存器。一個是程序員可以直接操作的,另外一個是程序員看不到的,這個看不到的寄存器在
STM32F4xx 中文參考手冊》里面被叫做影子寄存器。事實上真正起作用的是影子寄存器。 根據 TIMx_CR1 寄存器中 APRE 位的設置: APRE=0 時,預裝載寄存器的內容可以隨時傳送到影
子寄存器,此時 2 者是連通的;而 APRE=1 時,在每一次更新事件(UEV)時,才把預裝載寄存器(ARR) 的內容傳送到影子寄存器。

 

 

 最后,我們要介紹的寄存器是:狀態寄存器(TIMx_SR)。該寄存器用來標記當前與定時器相關的各種事件/中斷是否發生。該寄存器的各位描述如圖 13.1.5 所示:

 

 ***************************************************************定時器中斷

1TIM3 時鍾使能。
這里我們通過 APB1ENR 的第 1 位來設置 TIM3 的時鍾,因為 Stm32_Clock_Init 函數里面把APB1的分頻設置為4了,所以我們的TIM3時鍾就是APB1時鍾的2倍,等於系統時鍾(84M)。
2) 設置 TIM3_ARR TIM3_PSC 的值。
通過這兩個寄存器,我們來設置自動重裝的值,以及分頻系數。這兩個參數加上時鍾頻率就決定了定時器的溢出時間。
3) 設置 TIM3_DIER 允許更新中斷。因為我們要使用 TIM3 的更新中斷,所以設置 DIER UIE 位為 1,使能更新中斷。
4) 允許 TIM3 工作。
光配置好定時器還不行,沒有開啟定時器,照樣不能用。我們在配置完后要開啟定時器,通過 TIM3_CR1 CEN 位來設置。
5TIM3 中斷分組設置。
在定時器配置完了之后,因為要產生中斷,必不可少的要設置 NVIC 相關寄存器,以使能TIM3 中斷。
6) 編寫中斷服務函數。
在最后,還是要編寫定時器中斷服務函數,通過該函數來處理定時器產生的相關中斷。在中斷產生后,通過狀態寄存器的值來判斷此次產生的中斷屬於什么類型。然后執行相關的操作,
我們這里使用的是更新(溢出)中斷,所以在狀態寄存器 SR 的最低位。在處理完中斷之后應該向 TIM3_SR 的最低位寫 0,來清除該中斷標志。
通過以上幾個步驟,我們就可以達到我們的目的了,使用通用定時器的更新中斷,來控制DS1 的亮滅。

************************************************************定時器PWM

STM32F4 的定時器除了 TIM6 7。其他的定時器都可以用來產生 PWM 輸出。其中高級定時器 TIM1 TIM8 可以同時產生多達 7 路的 PWM 輸出。而通用定時器也能同時產生多達 4
路的 PWM 輸出!這里我們僅使用 TIM14 CH1 產生一路 PWM 輸出。

要使 STM32F4 的通用定時器 TIMx 產生 PWM 輸出,除了上一章介紹的寄存器外,我們還會用到 3 個寄存器,來控制 PWM 的。這三個寄存器分別是:捕獲/比較模式寄存器
TIMx_CCMR1/2)、捕獲/比較使能寄存器(TIMx_CCER)、捕獲/比較寄存器(TIMx_CCR1~4)。
接下來我們簡單介紹一下這三個寄存器。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 如果是通用定時器,則配置以上三個寄存器就夠了,但是如果是高級定時器,則還需要配置:剎車和死區寄存器(TIMx_BDTR),該寄存器各位描述如圖 14.1.5 所示:

 

 

 

 

 

 1) 開啟 TIM14 時鍾,配置 PF9 選擇復用功能 AF9TIM14) 輸出。要使用 TIM14,我們必須先開啟 TIM14 的時鍾(通過 APB1ENR 設置),這點相信大家看了
這么多代碼,應該明白了。這里我們還要配置 PF9 為復用(AF9) 輸出, 才可以實現 TIM14_CH1PWM 經過 PF9 輸出。
2)設置 TIM14 ARR PSC
在開啟了 TIM14 的時鍾之后,我們要設置 ARR PSC 兩個寄存器的值來控制輸出 PWM的周期。當 PWM 周期太慢(低於 50Hz)的時候,我們就會明顯感覺到閃爍了。因此, PWM
周期在這里不宜設置的太小。
3) 設置 TIM14_CH1 PWM 模式。
接下來,我們要設置 TIM14_CH1 PWM 模式(默認是凍結的),因為我們的 DS0 是低電平亮,而我們希望當 CCR1 的值小的時候, DS0 就暗, CCR1 值大的時候, DS0 就亮,所以我
們要通過配置 TIM14_CCMR1 的相關位來控制 TIM14_CH1 的模式。
4) 使能 TIM14 CH1 輸出,使能 TIM14
在完成以上設置了之后,我們需要開啟 TIM14 的通道 1 輸出以及 TIM14。前者通過TIM14_CCER1 來設置,是單個通道的開關,而后者則通過 TIM14_CR1 來設置,是整個 TIM14
的總開關。只有設置了這兩個寄存器,這樣我們才能在 TIM14 的通道 1 上看到 PWM 波輸出。
5) 修改 TIM14_CCR1 來控制占空比。
最后,在經過以上設置之后, PWM 其實已經開始輸出了,只是其占空比和頻率都是固定的,而我們通過修改 TIM14_CCR1 則可以控制 CH1 的輸出占空比。繼而控制 DS0 的亮度。
通過以上 5 個步驟,我們就可以控制 TIM14 CH1 輸出 PWM 波了。 這里特別提醒一下大家,高級定時器雖然和通用定時器類似,但是高級定時器要想輸出 PWM,必須還要設置一
MOE (TIMx_BDTR 的第 15 ),以使能主輸出,否則不會輸出 PWM!!

 *******************************************輸入捕獲

測量的高電平時間。測量方法如下:首先設置定時器通道 x 為上升沿捕獲,這樣, t1 時刻,就會捕獲到當前的 CNT 值,然后立即清零 CNT,並設置通道 x
為下降沿捕獲,這樣到 t2 時刻,又會發生捕獲事件,得到此時的 CNT 值,記為 CCRx2。 這樣,根據定時器的計數頻率,我們就可以算出 t1~t2 的時間,從而得到高電平脈寬。
t1~t2 之間,可能產生 N 次定時器溢出,這就要求我們對定時器溢出,做處理,防止高電平太長,導致數據不准確。如圖15.1.1所示, t1~t2之間, CNT計數的次數等於: N*ARR+CCRx2
有了這個計數次數,再乘以 CNT 的計數周期,即可得到 t2-t1 的時間長度,即高電平持續時間。輸入捕獲的原理,我們就介紹到這。

STM32F4 的定時器,除了 TIM6 TIM7,其他定時器都有輸入捕獲功能。 STM32F4 的輸入捕獲,簡單的說就是通過檢測 TIMx_CHx 上的邊沿信號,在邊沿信號發生跳變(比如上升沿
/下降沿)的時候,將當前定時器的值( TIMx_CNT)存放到對應的通道的捕獲/比較寄存器(TIMx_CCRx)里面,完成一次捕獲。同時還可以配置捕獲時是否觸發中斷/DMA 等。

TIMx_CCMR1 明顯是針對 2 個通道的配置,低八位[70]用於捕獲/比較通道 1 的控制,而高八位[158]則用於捕獲/比較通道 2 的控制,因為 TIMx 還有 CCMR2 這個寄存器,所以可以知道
CCMR2 是用來控制通道 3 和通道 4(詳見《STM32F4xx 中文參考手冊》 435 頁, 15.4.8 節)。

其中 CC1S[1:0],這兩個位用於 CCR1 的通道配置, 這里我們設置 IC1S[1:0]=01,也就是配置 IC1 映射在 TI1 上(關於 IC1TI1 不明白的,可以看《STM32F4xx 中文參考手冊》 393 頁的
119-通用定時器框圖),即 CC1 對應 TIMx_CH1。輸入捕獲 1 預分頻器 IC1PSC[1:0],這個比較好理解。我們是 1 次邊沿就觸發 1 次捕獲,所以選擇 00 就是了。

輸入捕獲 1 濾波器 IC1F[3:0],這個用來設置輸入采樣頻率和數字濾波器長度。其中,fck_int是定時器的輸入頻率(TIMxCLK),一般為 84Mhz/168Mhz(看該定時器在那個總線上),而fdts
則是根據TIMx_CR1CKD[1:0]的設置來確定的,如果CKD[1:0]設置為00,那么 fdts= fck_int

N 值就是濾波長度,舉個簡單的例子:假設 IC1F[3:0]=0011,並設置 IC1 映射到通道 1 上,且為上升沿觸發,那么在捕獲到上升沿的時候,再以 fck_int的頻率,連續采樣到 8 次通道 1 的電
平,如果都是高電平,則說明卻是一個有效的觸發,就會觸發輸入捕獲中斷(如果開啟了的話)。
這樣可以濾除那些高電平脈寬低於 8 個采樣周期的脈沖信號,從而達到濾波的效果。這里,我們不做濾波處理,所以設置 IC1F[3:0]=0000,只要采集到上升沿,就觸發捕獲。

所以,要使能輸入捕獲,必須設置 CC1E=1,而 CC1P 則根據自己的需要來配置。
接下來我們再看看 DMA/中斷使能寄存器: TIMx_DIER,該寄存器的各位描述見圖 13.1.2(在第 13 章),本章,我們需要用到中斷來處理捕獲數據,所以必須開啟通道 1 的捕獲比較中
斷,即 CC1IE 設置為 1
控制寄存器: TIMx_CR1,我們只用到了它的最低位,也就是用來使能定時器的,這里前面兩章都有介紹,請大家參考前面的章節。
最后再來看看捕獲/比較寄存器 1TIMx_CCR1,該寄存器用來存儲捕獲發生時, TIMx_CNT的值,我們從 TIMx_CCR1 就可以讀出通道 1 捕獲發生時刻的 TIMx_CNT 值,通過兩次捕獲(一
次上升沿捕獲,一次下降沿捕獲)的差值,就可以計算出高電平脈沖的寬度(注意,對於脈寬太長的情況,還要計算定時器溢出的次數)。

1)開啟 TIM5 時鍾,配置 PA0 為復用功能(AF2),並開啟下拉電阻。
要使用 TIM5,我們必須先開啟 TIM5 的時鍾(通過 APB1ENR 設置)。 因為我們要捕獲 TIM5_CH1 上面的高電平脈寬,所以先配置 PA0 為帶下拉的復用功能,同時, 為了讓 PA0 的復
用功能選擇連接到 TIM5,所以設置 PA0 的復用功能為 AF2,即連接到 TIM5 上面。
2)設置 TIM5 ARR PSC
在開啟了 TIM5 的時鍾之后,我們要設置 ARR PSC 兩個寄存器的值來設置輸入捕獲的自動重裝載值和計數頻率。
3)設置 TIM5 CCMR1
TIM5_CCMR1 寄存器控制着輸入捕獲 1 2 的模式,包括映射關系,濾波和分頻等。這里我們需要設置通道 1 為輸入模式,且 IC1 映射到 TI1(通道 1)上面,並且不使用濾波(提高響應
速度)器。
4) 設置 TIM5 CCER,開啟輸入捕獲,並設置為上升沿捕獲。
TIM5_CCER 寄存器是定時器的開關,並且可以設置輸入捕獲的邊沿。 只有 TIM5_CCER寄存器使能了輸入捕獲,我們的外部信號,才能被 TIM5 捕獲到,否則一切白搭。同時要設置
好捕獲邊沿, 才能得到正確的結果。
5) 設置 TIM5 DIER,使能捕獲和更新中斷,並編寫中斷服務函數
因為我們要捕獲的是高電平信號的脈寬,所以,第一次捕獲是上升沿,第二次捕獲時下降沿,必須在捕獲上升沿之后,設置捕獲邊沿為下降沿,同時,如果脈寬比較長,那么定時器就
會溢出,對溢出必須做處理,否則結果就不准了,不過,由於 STM32F4 TIM5 32 位定時器,假設計數周期為 1us,那么需要 4294 秒才會溢出一次,這基本上是不可能的。這兩件事,
我們都在中斷里面做,所以必須開啟捕獲中斷和更新中斷。
設置了中斷必須編寫中斷函數,否則可能導致死機。我們需要在中斷函數里面完成數據處理和捕獲設置等關鍵操作,從而實現高電平脈寬統計。
6)設置 TIM5 CR1,使能定時器
最后,必須打開定時器的計數器開關,通過設置 TIM5_CR1 的最低位為 1,啟動 TIM5 的計數器,開始輸入捕獲。


免責聲明!

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



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