目錄
一、基本定時器的作用
二、常用型號的TIM時鐘頻率
三、CubeMX配置
四、編寫執行代碼
一、基本定時器的作用
基本定時器,主要用于實現定時和計數功能。作用包括:
-
定時功能:可以產生周期性的中斷,用于實現定時任務。例如,可以設置一個定時器每隔一定時間(如1秒)產生一次中斷,用于執行周期性的任務,如數據采集、系統心跳等。
-
計數功能:基本定時器可以對外部事件進行計數,如脈沖計數。這在測量頻率、周期或者進行簡單的事件計數時非常有用。
-
驅動數模轉換器(DAC):可用于驅動DAC,以產生精確的模擬信號。
-
產生時基:基本定時器可以為系統提供時基,用于其他外設的同步操作。
-
中斷服務:通過配置基本定時器,可以在特定的時間點觸發中斷服務程序,執行特定的處理邏輯。
基本定時器結構簡單,易于理解和使用。在STM32系列中,基本定時器(如TIM6和TIM7)是16位的向上計數定時器,它們只能向上計數,沒有外部輸入/輸出通道,但可以用于簡單的定時任務。通用定時器(如TIM2、TIM3、TIM4)和高級定時器(如TIM1和TIM8)則提供了更多的功能和靈活性。
二、常用型號的TIM時鐘頻率
????????1.?常用的STM32F103C8,?是不帶TIM6、TIM7的,?F103系列要RC起,才帶基本定時器。
????????2.?F103系列:所有 TIM 的時鐘頻率都是72MHz;?
? ? ? ? 3. F407系列:TIM1、8、9、10、11的時鐘頻率是168MHz,其它TIM的時鐘頻率是84MHz.
三、CubeMX配置
????????通過CubeMX對基本定時器進行配置,過程相當簡單。
? ? ? ? 只需配置3個重要參數:PSC、ARR、打開中斷。
????????下面以“TIM6+每隔1秒執行LED閃爍”展開講解,TIM7的操作是一致,只是名稱不同。
????????1、配置參數
參數講解:
? ? ? ? ①?Prescaler(分頻系數):即PSC寄存器值,用于控制每一脈沖的時間。如STM32F407的TIM6,按上文內容得知,時鐘是84M。在設置預分頻為84后,脈沖頻率:84M/84=1MHz,即每秒產生1百萬個脈沖信號,1秒/1M=1us,? 即每1us產生一次脈沖信號。
? ? ? ? ② Counter?Mode (計數方式):? 向上計數
? ? ? ? ③?Counter Period (計數周期):? 即ARR寄存器值,多少個脈沖作為1個波形周期。
? ? ? ? ④?auto-reload preload (自動重載值的預裝載):? 當改變周期值ARR時,是否等到下一個更新事件再寫入數值,使得數值的更改不影響執行中的波形。
2、打開中斷
?基本定時器,只有一種中斷,按下圖,打勾即可。
注意:打勾中斷后,生成的代碼,只是幫我們添加了中斷的配置; 而中斷的開啟,需要使用代碼“手動”開啟。
四、編寫執行代碼
代碼共為3部分:初始化配置、開啟TIM、中斷回調函數。
1、初始化配置
CubeMX根據我們的配置,已生成好了初始化代碼,我們不用管它。
如果想查看它的初始化實現過程,可以雙擊 "tim.c"。
2、開啟TIM
謹記一個,當我們使用CubeMX配置外設功能時,它只是根據參數的配置生成初始化代碼(即上面的第1步),而不會主動開啟外設功能,特別是中斷的開啟,如TIM、ADC、UART等。
所以,我們需要在main.c中,“手動”開啟TIM6。
如下圖,在while前,添加:
HAL_TIM_Base_Start_IT(&htim6);?
調用HAL_TIM_Base_Start_IT(&htim6)后,TIM6就會開始工作。
下面是它的工作原理,自動進行的,不用干預,我們只需大概地知道工作過程、原理:
TIM會自動檢測脈沖信號,每來一個脈沖,計數器CNT就會硬件自動加1。
當寄存器CNT的計數值==設定的自動重裝載值ARR,就會產生中斷(溢出中斷)。
發生中斷時,CNT值會被硬件清0,重新開始下一輪計數; 硬件自動找尋中斷函數入口。
使用CubeMX生成的HAL代碼,我們不需要像使用標準庫時那樣自己編寫中斷函數,CubeMX已幫我們整理好中斷函數的跳轉,只需要重寫中斷回調函數。
3、重寫TIM6的中斷回調函數
基本定時器,只有一種中斷,所以也只有一個中斷回調函數:HAL_TIM_PeriodElapsedCallback();
我們可以在工程中任意一個c文件中編寫它。
習慣上,會在main.c的尾部編寫這個函數。
如下圖,我們在main.c的? 注釋行 /* USER CODE BEGIN 4 */?下面編寫它。
如果工程中已有這個函數,我們只需在函數內增加TIM6的判斷部分;
如果工程中沒有這個函數,增加即可。
所有TIM的ARR溢出中斷(即周期結束),? 都會統一調用它。
在這個回調函數中,我們執行的動作是:每1000ms,?反轉PB2電平(LED)。
如果你的開發板上,PB2引腳接的是?LED,?而且也初始化成輸出模式,它就會每1秒閃爍1次。
特別地說明一個情況:
在前面CubeMX的配置中,我們的TIM6配置是:84MHz的時鐘,84的分頻值,1000的周期值。
這樣,硬件上每個脈沖時長是1us,每1000個脈沖為1周期,即每1ms產生1次中斷,調用這個回調函數。
然后,我們在回調函數中,為了實現1秒的執行,定義了一個cnt變量,每調用1次回調函數,cnt加1。當cnt==1000時,就執行閃燈動作。
這里要特別說明的是:我們不應該這樣操作!
單片機,運行資源是很有限的。像STM32F407系列,168MHz。
這個回調函數,調用一次,大約300ns左右。如果按上面的設計,每秒調用1000次,那么每秒僅調用它就花費300us。
當任務少時,上面操作完全可行。但是當執行的中斷多、實時性要求高時,這樣就不適合了。
所以,我們設計單片機的代碼時,要適當地考慮資源的消耗。