STM32F4通用定時器TIM9-TIM14講解及PWM呼吸燈實例解讀
- 前言
- 小貼士
- 通用定時器原理
- 定時器的內部時鐘源
- 通用定時器TIM9-TIM14的對比
- 共同點
- 區別
- TIM9-TIM14功能說明
- 時基單元
- 計數模式
- 時鐘選擇
- 定時器框圖理解和分析
- TIM10/TIM11/TIM13/TIM14
- 輸入捕獲
- 輸出比較
- TIM9和TIM12
- 獨立通道
- 輸入濾波器
- 邊沿檢測器
- 輸入捕獲選擇器
- 預分頻器
- 捕獲比較寄存器
- 同步觸發
- 觸發選擇TS[2:0]
- 主從模式聯動
- 關于TRC的小提示
- PWM呼吸燈實例及解讀
- 配置界面與寄存器
- PWM模式代碼分析
- 初始化代碼分析
- 初始化代碼涉及的寄存器
- main函數中我們添加的代碼
- 在初始化階段調用的函數
- while(1)里添加的代碼
- 寄存器分析
- TIMx_DIER
- TIMx_SR
- TIMx_EGR
- TIMx_CNT
- TIMx_PSC
- TIMx_ARR
- TIMx_CCR1
- 參考文獻
前言
STM32F4的定時器分為高級定時器,通用定時器和基本定時器。上一篇文章已經講了基本定時器。本文遵從由簡入繁的原則,先講解通用定時器的原理,并通過PWM實例幫助大家加深對通用定時器的理解,最后介紹通用定時器的寄存器,旨在幫助大家逐步掌握通用定時器的全部功能。本文一萬余字,我傾注了些心血,如果對您有幫助,還請點贊、收藏、轉發、評論!謝謝!
通用定時器分為:
- TIM2-TIM5
- TIM9和TIM12
- TIM10/TIM11/TIM13/TIM14
雖然都是通用定時器,也有細微的差別。本文講解TIM10/TIM11/TIM13/TIM14和TIM9和TIM12兩個部分。
小貼士
通用定時器的寄存器,有些名稱中含有CC
,指的是“捕獲/比較”,即Capture/Compare
,與獨立通道的設置相關,可以將通道設置成輸入型的,也可以設置成輸出型的。輸入則對應著捕獲,輸出則對應著比較。
通用定時器原理
定時器的內部時鐘源
我們打開《STM32F4英文參考手冊》看到時鐘章節有時鐘樹,這里截取我們關心的定時器時鐘。看得出來,芯片設計者對定時器和其他的外設是區別看待的。
??很明顯,對于APB1和APB2,都是一樣的。由于STM32F4主頻最高是168MHz,我們就假定SYSCLK = 168MHz。
??就拿APB1舉例,如果APB1的分頻系數是1,也就是說,外設的工作頻率是168MHZ,那么定時器的工作頻率也是168MHZ;
??但如果APB1的分頻系數不是1,比如說是2,那么外設的工作頻率是84MHz,這個時候,定時器的工作頻率是84MHz的2倍,也就是168MHZ。
??如果APB1的分頻系數是4,那么外設的工作頻率是42MHz,這個時候,定時器的工作頻率是42MHz的2倍,也就是84MHZ。
??所以相信大家看明白關系了。
通用定時器TIM9-TIM14的對比
共同點
對于TIM9-TIM14,它們的共同點是:
- 都是16位的自動重裝載遞增計數器(只能遞增)
- 16位可編程預分頻器
- 都擁有獨立通道用于輸出比較、輸入捕獲、PWM生成、單脈沖模式輸出
- 可以產生中斷的方法:更新、輸入捕獲、輸出比較
區別
TIM9
和TIM12
比TIM10/TIM11/TIM13/TIM14
多的功能:
- 使用外部信號控制定時器且可實現多個定時器互連的同步
TIM9
和TIM12
擁有獨立通道的數量比較多,分別有2個通道,而TIM10/TIM11/TIM13/TIM14
只有1個通道。- 相比而言,
TIM9
和TIM12
生成中斷的條件多了一個:觸發事件(計數器啟動、停止、初始化或者由內部觸發器計數)
TIM9-TIM14功能說明
時基單元
請參見基本定時器一文。
計數模式
請參見基本定時器一文。
時鐘選擇
TIM10/TIM11/TIM13/TIM14
和基本定時器一樣,只有內部時鐘(CK_INT)作為時鐘源。
TIM9
和TIM12
除了可以使用內部時鐘(CK_INT),還可以:
- 使用外部時鐘模式(通過外部引腳輸入時鐘)
- 使用內部觸發輸入(ITRx)連接其他定時器的觸發輸出
對于TIM10/TIM11/TIM13/TIM14
,在基本定時器一文中已經有介紹時鐘,所以這里只介紹TIM9
和TIM12
。
對于SMS
,有以下幾種可選項,分別代表不同功能。
- 000——禁止從模式,定時器的時鐘由內部時鐘提供。(本定時器獨立計數,不聽命于其他)
- 100——復位模式,出現所選觸發輸入(TRGI)的上升沿時,重新初始化定時器并產生更新事件
- 101——門控模式,觸發輸入(TRGI)為高電平的時候才使能計數器時鐘,TRGI為低電平就立即停止計數,但不會復位計數器。(什么時候計數,什么時候暫停計數,完全取決于別人的臉色)
- 110——觸發模式,觸發信號(TRGI)出現上升沿則啟動計數,但不復位。(別人一聲令下,本定時器啟動計數,但什么時候停止,不聽別人的。)
- 111——外部時鐘模式1,在所選觸發輸入的上升沿驅動計數器。(來一個上升沿,我計一個數,再來一個上升沿,我又計一個數,如此往復……)
SMS
位其實對應到下圖中的控制器:
定時器框圖理解和分析
通過比較下面兩張圖片,可以直觀感受到兩種通用定時器的區別。
當然這兩張圖片是定時器的精髓,把這兩張圖看明白了,我們就掌握定時器了。“老太太吃柿子——撿軟的捏”,咱們先看第二幅圖,一眼望去,除了下面多了一個通道,上面的部分和基本定時器完全一樣。而這條通道左邊是外部引腳TIMx_CH1,右邊也是TIMx_CH1。納尼?什么意思?其實是這樣的,它只是把一個引腳的功能“展開”了,一個定時器外部引腳,既可以輸入,也可以輸出。但不可能同時輸入和輸出,除非不同的引腳復用到這一個定時器上,然后讓定時器分時復用,這種情況非常罕見,所以我們就當它是一個引腳就行。
TIM10/TIM11/TIM13/TIM14
輸入捕獲
“輸入捕獲”是對外部引腳輸入的信號而言的;“輸出比較”是對輸出的信號而言的!分別對應著圖上獨立通道的左右兩邊。
如果這個引腳作為“輸入捕獲”功能,那么我們就不看右邊的那半條通道。左邊輸入的時鐘,經過濾波器和邊沿檢測器,給到預分頻器,最后給了捕獲/比較寄存器,通過計數值和這個寄存器的值相比,然后得出輸入的時鐘信息,比如高電平持續了多久?
輸出比較
如果這個引腳作為“輸出比較”功能,那么我們就不看左邊的那半條通道,只看右邊捕獲/比較寄存器往右的這半條通道即可。相比之下,如果是“輸入捕獲”,則捕獲/比較寄存器的值是隨著輸入信號寫進去的,不是我們用戶通過代碼寫值進去的;但如果是“輸出比較”,則捕獲/比較寄存器的值是我們用戶通過寫寄存器寫值進去的。并且這個值可以隨時被我們改變,這就是PWM的生成邏輯。
到此,第二張圖TIM10/TIM11/TIM13/TIM14
定時器框圖已經分析完畢。這里先給大家簡單介紹一下,下面講TIM9和TIM12的時候,涉及寄存器的內容,在這里也可以對應。
TIM9和TIM12
現在,我們看第一張圖片TIM9
和TIM12
定時器框圖。是不是比第二張圖復雜了一些?不過對比之后發現,也沒太復雜,請聽我一一道來。
從獨立通道的數量來看,TIM9
和TIM12
擁有2條,從外部引腳TIMx_CH1或者TIMx_CH2進來,就是TI1和TI2。從左到右,這兩條獨立通道基本上完全一樣。但也有唯一的區別:對于TI1,經過輸入濾波和邊沿檢測之后,可以成為TI1F_ED
,連接到上面的選擇器,與TRC
共同被選擇。其他方面兩個獨立通道是完全一樣的。
當SMS
位等于111時,就選擇TI1F_ED
作為定時器的外部時鐘,每個上升沿都觸發一次計數。(關于SMS
前文已有講解,此處不贅述)
獨立通道
輸入濾波器
我們沿著獨立通道從左到右看,首先就是數字濾波器和邊沿檢測器。
1、首先,我們要考慮的是輸入濾波器的采樣頻率,由寄存器TIMx_CCMR1->IC1F
決定。
邊沿檢測器
邊沿檢測器要根據寄存器的值選擇上升沿還是下降沿作為觸發的極性。
因為兩個通道的寄存器位完全一樣,所以介紹通道1為例即可。
首先,CC1P
這個位在輸出模式下,表示有效電平是高電平還是低電平。如果=1,則有效電平是高電平,反之是低電平。
在輸入模式下,CC1NP
和CC1P
兩個BIT共同組成2BIT的寄存器位,就有四種不同的值,代表不同含義:
- 00——上升沿是輸入捕獲的觸發極性。
- 01——下降沿是輸入捕獲的觸發極性。
- 10——保留。
- 11——上升沿和下降沿都是輸入捕獲的觸發極性。(在編碼模式下不允許使用)
最后一個位是CC1E
。如果是輸出模式,就決定了輸出是否使能;如果是輸入模式,就決定了捕獲是否使能。
在PWM呼吸燈實例中,可以看到HAL庫對這一位的處理是:初始化的時候就清零。而它的置位是由用戶調用API啟動的。
輸入捕獲選擇器
經過濾波器和邊沿檢測器,就到了下圖的選擇器。
CC1S[1:0]
實際上對應著上面這個選擇器。回到上面的定時器框圖就理解了。
CC1S[1:0]
可以選擇:
- 01——就是TI1FP1連接到IC1;
- 10——就是TI2FP2連接到IC1;
- 11——就是TRC連接到IC1。
以上是將CC1(捕獲比較通道1)設置成輸入型的。如果想要設置成輸出型的,CC1S
等于00,比如PWM模式就需要將波形從引腳輸出的外部。
舉一反三,CC2S
的含義類似。
預分頻器
再往右是預分頻器,就是外部輸入幾個事件,才會完成一次捕獲。如下圖,分為幾種情況:
- 00——不分頻,每次檢測到邊沿輸入,都完成一次捕獲。
- 01——每檢測到2次事件,完成一次捕獲。
- 10——每檢測到4次事件,完成一次捕獲。
- 11——每檢測到8次事件,完成一次捕獲。
捕獲比較寄存器
最后到了捕獲/比較寄存器。CNT計數器分別與兩個捕獲/比較寄存器連接,可以進行捕獲比較。
同步觸發
觸發選擇TS[2:0]
還有一個問題需要我們留意:
ITR0-ITR3一共4路,都是其他主定時器輸入的觸發信號TRGI,還有TI1F_ED、TI1FP1、TI2FP2,這些都可以用來同步定時器。至于選擇哪一個,由下面的寄存器決定:
那另一個問題來了,上面的ITR0-ITR3分別是什么意思呢?
主從模式聯動
既然提到了寄存器TIMx_SMCR,那么就順便講一下MSM(Master/Slave Mode),它是用于控制定時器的主從模式聯動。當多個定時器需要協同工作時(如級聯觸發、同步計數),MSM位可確保它們的操作嚴格同步。
- 功能:使能主從模式聯動,確保觸發信號從主定時器傳遞到從定時器時,兩個定時器的操作嚴格同步。
- 取值:
0
:禁用主從模式聯動。1
:啟用主從模式聯動(推薦配置)。
當MSM位被置1時:
- 主定時器接收到觸發信號后,會先將觸發信號傳遞給從定時器。
- 從定時器根據自身配置(如SMS位)響應觸發信號(如復位計數器、啟動計數)。
- 主定時器在確保從定時器完成響應后,再執行自身的操作(如更新TRGO輸出)。
這一機制避免了主從定時器之間的時序競爭,確保同步精度。
關于TRC的小提示
最后請留意一下,上面的TRC可以被選擇在獨立通道上使用。
PWM呼吸燈實例及解讀
配置界面與寄存器
這里的配置和下面的寄存器相關,所以將其補充在下面進行解讀。
PWM模式的選擇。
快速模式
PWM模式代碼分析
初始化代碼分析
上圖漏說了一句:
/* Select the Output Compare Mode */tmpccmrx |= OC_Config->OCMode;
這是在配置OC1M
位,將配置值PWM1寫入“輸出比較1模式”位。
初始化代碼涉及的寄存器
補充對應的寄存器,供大家深入理解。
CC1E這一位,在代碼中先是清零,關閉輸出。
main函數中我們添加的代碼
在初始化階段調用的函數
HAL_TIM_PWM_Start(&htim14, TIM_CHANNEL_1);
之后我們分析一下這個函數的內部邏輯。
while(1)里添加的代碼
for(uint16_t i = 0; i < 500; i ++){__HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, i);HAL_Delay(9);}for(uint16_t i = 500; i > 0; i --){__HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, i);HAL_Delay(9);}
其中的宏定義:
#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \(((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\((__HANDLE__)->Instance->CCR4 = (__COMPARE__)))
本例中,使用的是channel1,此宏定義是設置CCR1寄存器的值。實現PWM占空比變化。
到此,PWM呼吸燈的實例及分析結束。
寄存器分析
上面已經講了一些寄存器,這里就沒有被提及的寄存器進行補充說明。
TIMx_DIER
所謂的使能位,就是一個開關。打開開關之后,下面的標志位一旦置位了,就會觸發相應的中斷;關閉了開關之后,即便下面的標志位置位了,也不會觸發中斷。
TIMx_SR
所謂“重捕獲”,是說上次的捕獲標志位還沒有清零,下一次的捕獲事件就又觸發了。為了防止第2次的捕獲事件丟失,所以這個寄存器就應運而生了。
TIMx_EGR
TIMx_CNT
由于TIM9-TIM14都只有遞增的模式,所以這個寄存器的值只能遞增計數。
TIMx_PSC
回顧上面的定時器框圖,你可能還有印象,這個寄存器就是下面框圖的預分頻器。而預分頻的時鐘來源,就是CK_PSC
。
TIMx_ARR
重裝載寄存器就是下圖中紅色框的這個。如果說,計數器是“吃包子的”,那么重裝載寄存器就是“喂包子的”。是不是很形象?哈哈哈……
TIMx_CCR1
TIMx_CCR1
寄存器在輸入和輸出模式下的功能不同,在輸出模式下,與OC1PE
相關。如果OC1PE=1
,寫進TIMx_CCR1
寄存器的值會在產生更新事件之后生效;如果OC1PE=0
,則寫進TIMx_CCR1
寄存器的值會立即生效。在輸入模式下,這個寄存器只允許讀,不允許寫,它的值是最后一次輸入捕獲事件的計數值。
這里補充OC1PE
(輸出比較預裝載使能)位的定義。
同樣有TIMx_CCR2
寄存器,由于僅僅是通道不同,所以不需要多講了。
參考文獻
《STM32中文參考手冊》
《STM32英文參考手冊》
本文到此結束,已經很詳細地介紹了通用定時器TIM9-TIM14,相信您可以從中有所收獲,期待您的點贊、轉發、收藏、評論!