[STM32] 08-Timer-Output_Compare

Morgan Ting
閱益如美
Published in
10 min readApr 9, 2022
Photo by Adrien Robert on Unsplash

STM32 通用計時器提供輸出比較 ( Output Compare ) 功能可以用來設定計數時間,當計時器計數到特定時間便會觸發中斷。本文章將介紹 STM32 的 Timer Output Compare 功能,以 STM32CubeIDE 作為開發環境並搭配 Hardware Abstraction Layer, HAL 函式庫完成實作。

文章內容

  1. Timer output compare 介紹
  2. Timer output compare 設定步驟
  3. 實作
  4. 成果展示
  5. 總結

工具與材料

  1. STM32CubeIDE
  2. Blue Pill ( STM32F103C8T6 ) 開發板
  3. ST-LINK v2
  4. 示波器

Timer output compare 介紹

介紹 Timer output compare 之前先來複習一下計數器的運作,以上數模式為例,當計數器從 0 開始上數到 TIMx_ARR 內容值時便停止上數並且歸零觸發上數溢位中斷事件,之後再繼續新一輪計數週期。我們知道 TIMx_ARR 掌管計數週期,計數器會忠實地重複從 0 到 TIMx_ARR,如果想要在 0 ~ TIMx_ARR 之間指定一個時間提醒微處理器做其他事情可以用輪詢的方式一直檢查計數暫存器內容,不過這樣太浪費資源了,解決之道便是 output compare 。

Output compare 就是在計數週期範圍內額外指定一個數值,當計數器數到該數值時便觸發相應的中斷事件,由於計數時脈是可調的因此指定一個計數值也等於指定一特定時間。

Output compare 的指定計數值由暫存器 TIMx_CCRy 決定 ( x 表示 Timer ,y 表示通道 ),由於計數器從 0 數到 TIMx_ARR 所以 TIMx_CCRy 數值必須落在 0 ~ TIMx_ARR 之間,否則怎樣也數不到。

下圖說明了 Timer output compare 計數器的計數狀況

Timer Counter

當計數器內容與 TIMx_CCRy 吻合時便會觸發中斷事件。

因為 STM32F103C8T6 每一個 Timer 有 4 個輸入 / 輸出 通道,一共有 4 種狀態可以設定通道上的硬體腳位在發生比較中斷時呈現何種狀態。

  • 保持:通道上的硬體腳位狀態不變。
  • 高電位:通道上的硬體腳位輸出高電位。
  • 低電位:通道上的硬體腳位輸出低電位。
  • 翻轉:改變通道上的硬體腳位狀態,也就是 Toggle 。

下表列出搭載 STM32F103C8T6 的 Blue Pill 開發板對應的通道腳位。

Timer & Channel

Timer output compare 設定步驟

  1. 選擇計數器時脈來源。
  2. 設定TIMx_ARR與TIMx_CCRy 內容值。
  3. 設定是否產生 DMA 中斷。
  4. 設定輸出模式,保持、高電位、低電位、翻轉。
  5. 啟動計時器。

藉由 STM32CubeIDE 與 HAL 函式庫便可完成上述設定,唯一在程式中要做的只有啟動計時器這步驟,很方便吧 。

實作

我們利用 Blue Pill 開發板的 TIMER 2 與 通道 2 來輸出波形,TIMER 2 的時脈頻率為 72 MHz ,設定分頻 Prescaller為 72 使得 TIMER 2 計數頻率為 72 MHz / 72 = 1 MHz,輸出模式設定為翻轉 toggle 這樣才好觀察輸出波形,到目前為止都沒問題,聰明的讀者一定想到 TIMx_CCRx 呢 ?

在 STM32CubeIDE 環境設定中 Timer output compare 功能並不需要設定 TIMx_CCRy 暫存器內容而是由 TIMx_ARR 來決定,這坑夠大吧 ~

TIMx_ARR 設定 500 ,所以這時候 TIMER 2 計數頻率為 72 MHz / 72 / 500 = 2 KHz,又因為輸出模式為 toggle 每逢中斷事件即改變輸出狀態因此我們預期輸出腳位上的波形頻率是 2 Khz / 2 = 1 KHz。

接下來便開始來操作囉。

一、在歡迎畫面點選 Start New STM32 Project。

start a project

二、Target Selection 在搜尋列輸入「 F103C8」這時會列出 STM32F103C8T6 ,點選該晶片型號後按下一步。

target selection

三、此時輸入專案名稱,讀者可自行輸入,輸入完成後按 Finish 完成此步驟。

project name

四、在 Catagories 的 Timers 點選 TIM2,Clock Source 選擇 Internal Clock,Channel 2 選擇 Output Comapre CH2 。

Timer setting

底下的參數設定如下:

  • Prescaler 分頻設定 72–1。
  • Counter Period 設定 500–1。
  • Output Compare Channel 2 的 Mode 選擇 Toggle on Match。
Timer parameter setting

完成後可以看到晶片圖示在 PA1 的位置自動顯示 TIM2_CH2,表示該腳位作為 Timer 2 的 Channel 2 輸出腳位。到這一步 TIMER 設定完成。

Timer output pin

五、在 System Core 點選 SYS ,在 Debug 項目選擇 Serial Wire。

SYS mode

六、點選 RCC ,在 High Speed Clock ( HSE ) 選擇 Crystal / Ceramic Resonator 外部震盪器做為系統時脈來源。

RCC mode

七、Clock Configuration 設定 TIMER 時脈來源,首先在 PLL Source Mux 選擇 HSE,PLL Mul 選擇 9 ,System Clock Mux 選擇 PLLCLK ,最後在 APB1 Prescaler 選擇 /2 。Timer 的時脈來源便設定完成。

Clock configuration

八、Project Manager 的部分確認一下專案目錄與名稱以及 Code Generator 的部分是否需要更改。

Project manager
Project manager

九、沒什麼問題的話上方命令列 Project ==> Generate Code 產生初始程式碼。

Generate code

九、在程式中由於 STM32CubeIDE 已經自動產生相關初始化設定程式碼,剩下的只有啟動計時器。我們借助 HAL 函式庫來啟動 TIMER,在 /* USER CODE BEGIN 2*/ 區段寫下一段程式來啟動計時器。

HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_2);
Start Timer

其中,&htim2 是指啟動 TIMER 2 ,TIM_CHANNEL_2 指定 CHANNEL_2 為輸出。

十、完成程式碼的撰寫後,上方命令列 Project ==> Build All 或是榔頭圖示,建立相關檔案。

Build code

十一、相關檔案建立後,按下 RUN 綠色播放鍵圖示。

Run code

此時會出現 Debug 設定,Main 項目一般不太需要更改設定。

點選 Debugger ,將 Interface 內的 ST_LINK 前方框框打勾並按下右方的 Scan 按鈕,如果此時ST-LINK v2 燒錄器有接在電腦上就會出現燒錄器 ID 號碼。

debugger

設定完成後按下 Run 按鈕就會將程式上傳到 Blue Pill 開發板上頭,以示波器量測 PA1 腳位可以觀察到輸出波形。

成果展示

Result

總結

Timer Output Compare 可以指定計時器在特定時間觸發中斷事件進行其他程序,或是藉由計時器通道輸出波形,總結如下:

  • STM32F103C8T6 每一個 TIMER 有 4 個輸出通道。
  • 通道有 4 種輸出狀態:保持、高電位、低電位、翻轉。
  • TIMx_CCRy 暫存器設定比較值,但 Timer Output Compare 模式下不設定此暫存器,而是由 TIMx_ARR 決定。

參考資料

  1. STM32F103 手冊 [ 連結 ]
  2. STM32F1 HAL and Low-layer drivers [ 連結 ]

感謝讀者

若文章有幫助到您可以拍手給我鼓勵,免費支持我。

相關文章

  • [STM32] 00-Install STM32CubeIDE [連結]
  • [STM32] 01-ST-LINK [連結]
  • [STM32] 02-STM32F103C8T6 [連結]
  • [STM32] 03-GPIO-Output [連結]
  • [STM32] 04-GPIO-Input [連結]
  • [STM32] 05-Ext-Interrupt [連結]
  • [STM32] 06-Timer-Basic [連結]
  • [STM32] 07-Timer-Interrupt [連結]
  • [STM32] 08-Timer-Output_Compare [連結]
  • [STM32] 09-Timer-PWM [連結]
  • [STM32] 10-Timer-Input_Capture [連結]
  • [STM32] 11-RTC-Second-Interrupt [連結]
  • [STM32] 12-RTC-Alarm_Interrupt [連結]
  • [STM32] 13-Independent_Watch_Dog [連結]
  • [STM32] 14-Windows_Watch_Dog [連結]
  • [STM32] 15-ADC_Conversion [連結]
  • [STM32] 16-ADC_Conversion_Temperature_Sensor [連結]
  • [STM32] 17-ADC_Convversion_DMA [連結]
  • [STM32] 18-SPI [連結]
  • [STM32] 19-UART [連結]
  • [STM32] 20-I2C [連結]

--

--

Morgan Ting
閱益如美

用好奇心探索世界。喜愛學習樂於分享。