STM32CubeMX Lesson 5 ─ TIMER應用之計時器

  TIMER 是MCU相當重要的功能之一,常會用於計數、計時、PWM輸出、波型擷取等等。原理大致上是利用內部RC震盪或外部石英震盪器訊號觸發SysTick計時器,計時器內部有 Counter 計算計數了幾次,由於觸發訊號週期性計算經過多少時間。

  下文將以STM32L053R8Tx為示範,使用意法半導體官方所提供的Nucleo開發板完成該實驗,使用的IDE為Keil uVision5(MDK-ARM),而STM32CubeMX的版本為6.2.1。

Nucleo-L053共有5個 TIMER ,大致上可以分類為四類,依照需求可以選擇不同的 TIMER 作為使用,詳細可以查看官方的Datasheet DM00095744

─ LPTIM1     低功耗 TIMER

─  TIM2          四通道 TIMER

─ TIM21 / TIM22 雙通道 TIMER

─ TIM6                 基礎型 TIMER

從官方提供的方塊圖可以了解時脈進入計數器前會先經過Prescaler除頻,因為若直接使用內部RC震盪或外部石英震盪器的32Mhz,則會造成 TIMER 計時或計數過快,在不少的應用上會受到影響,也會造成中斷進入過於頻繁。

而STM32的 TIMER 計數器 的計數方式有上數、下數、中心對齊計數3 種方式。

本次使用TIM6進行 計時器 的功能,可以使用 TIMER 的內部中斷,當計時一到就進入中斷服務程式,也可以使用 TIMER 的計數 Counter,當計數次數到達指定次數,就進行相關處理。

首先在STM32Cube須將TIM6打開,並致能INT中斷的產生。

設定的部分可以看到有Prescaler、 Counter Mode、Period等等,主要是設定TIMER6從Clock除頻多少為TIME6的基頻,以此頻率計算幾個Period中斷一次。


假設我們PSC設定為32,Period設定為1000,則是將32Mhz的Clock除頻32為1Mhz,以1Mhz的頻率計數1000次就進入中斷,則是每1ms中斷一次。

而我們這邊設定除頻3200次,計數5000次,使TIM6每500ms進入中斷一次。

產生程式碼後,可以發現在stm32l0xx_it.c最下方中,出現了TIM6的中斷服務程式。

可以發現進入中斷服務程式後,他呼叫的HAL_TIM_IRQHandler,並告知中斷源為TIM6,對該副程式點選右鍵Go to Definition,進入該副程式的原始碼。

進入後可以看到針對不同的中斷進入方式有不同的處理及呼叫,雖然TIM6僅有基礎的計時功能,但因為其餘的 TIMER 也是呼叫該副程式,因此可以觀察到有不少的觸發事件,如Capture compare 1 event、Capture compare 2 event、Output compare event等等。

往下拉可以看到TIM Update event,這正是TIMER6中斷進入後所處理的事件,並且可以看到清除中斷旗標後,呼叫了HAL_TIM_PeriodElapsedCallback,代表我們需要在main.c建立這個副程式,以利中斷產生時會呼叫該副程式。

再次對HAL_TIM_PeriodElapsedCallback副程式按下右鍵Go to Definition,可以找到完整的副程式宣告方式與說明。

回到main.c建立HAL_TIM_PeriodElapsedCallback副程式,並判斷所傳入的中斷源是否為TIM6,因為傳入的參數是指標,因此我們判斷中斷源需要多一個”&”符號,判斷htim的位址是否與htim6的位址相同,若一致則代表中斷源為TIM6,若正確的話則反向PA5(板子的LD2 LED燈)。

並在while前需要啟用TIM6的計數與中斷致能。

燒錄後則可以看到LD2每500ms就反轉一次,若用示波器觀察則可以看到1Hz的方波。

另一個方式是使用Counter的方式進行,在main.c的下方有TIM6的設定,將除頻設為32000(32Mhz/32000=1khz),將Period設為最大值65535,因為此暫存器是16bits,因此最大值為2的16次方65535,以1Khz的頻率進行計數,當計數到500則進行反轉,也可以達到一樣的效果。

因為此方式並沒有使用到內部中斷,因此也不需要使用Callback Function,在TIMER的致能也不需要使用中斷致能,僅需使用HAL_TIM_Base_Start_IT(&htim6);。

並在while迴圈判斷計數次數,當次數達到499,則反轉PA5,並將計數器清除,則可以完成一樣的功能。

兩者的差異在於計數與計時及是否進入中斷,大部分我的習慣會使用中斷,因為可以不受main的delay或其他函數的影響,例如Lesson4所提到的七段顯示器掃描是有時間限制的,就可以把掃描的程式放在中斷,而資料輸出仍可以在main當中變更資料。

TIMER 是相當好用的功能,在每個單晶片與微處理器都是很重要的功能,學習好後可以在各方面都有更好的應用。透過 TIMER 可以不用每次都使用HAL_Delay進行延遲,造成後續程式等待Delay完成,若需要同時多工, TIMER 計時是很好的工具之一。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *