第5章
計時器與PWM訊號產生
5.1 STM32的Timer硬體簡介
SIOC的Timer主要分成兩種類型,一為高級控制計時器(Advanced Control Timer)一為通用計時器(General-Purpose Timer),高級控制計時器(TIM1)主要的功能如下
l 16-bit向上、向下、向上/向下自動裝載計數器(counter)
l 16-bit可編程的預除器,計時器clock頻率的除頻係數為1~65535之間的任意數值
l 四個獨立通道
n 輸入捕獲
n 輸出比較
n Pwm生成
n 單脈衝模式輸出
l 死區時間可編程的互補輸出
l 使用外部信號控制計時器和計時器之間互相的同步電路
l 允許在指定數目的計數器週期後更新計時器暫存器的重複計數器
l 剎車輸入信號可將計時器的輸出信號設定於重設狀態(reset state)或者是已知狀態(known state)
l 如果遇到下列事件發生會產生中斷/DMA
n 更新:如計數器向上或向下溢出,計時器初始化
n 觸發事件:計數器啟動、停止、初始化或者由內部/外部觸發計數
n 輸入捕獲
n 輸出比較
n 剎車訊號輸入
l 支援定位增量編碼器和霍爾感應電路(Hall-sensor cicuitry)
l 觸發輸入作為外部的clock或者週期的電流管理
圖1. 高級計時器架構圖
通用計時器(TIM2-TIM4)主要功能如下
l 16-bit向上、向下、向上/向下自動裝載計數器(counter)
l 16-bit可編程的預除器,計時器clock頻率的除頻係數為1~65535之間的任意數值
l 四個獨立通道
n 輸入捕獲
n 輸出比較
n Pwm生成
n 單脈衝模式輸出
l 使用外部信號控制計時器和計時器之間互相的同步電路
l 如果遇到下列事件發生會產生中斷/DMA
n 更新:如計數器向上或向下溢出,計時器初始化
n 觸發事件:計數器啟動、停止、初始化或者由內部/外部觸發計數
n 輸入捕獲
n 輸出比較
n 剎車訊號輸入
l 支援定位增量編碼器和霍爾感應電路(Hall-sensor cicuitry)
l 觸發輸入作為外部的clock或者週期的電流管理
圖2. 通用計時器架構圖
5.2 Timer與Interrupt處理
這一小節中,我們利用計時器產生中斷,並且以通用計時器的TIM3為例其步驟如下:
- I. Peripheral reset register: ENABLE TIM3的該暫存器
- II. 設定TIM3_ARR和TIM3_PSC 的值:透過這兩個暫存器,我們來設定自動重裝的值和除頻係數。這兩個參數加上時鐘的頻率決定了計時器的溢出時間。
- III. 設定TIM3_DIER允許更新中斷:因為在中斷實驗中要使用TIM3的更新中斷,所以設定DIER的UIE位元,並使其能觸發中斷。
- IV. 開啟TIM3:設定完TIM3後,若未開啟計時器,是無法使用TIM3,在整個配置完後要透過拉起TIM3_CR1這暫存器的CEN位元。
- V. TIM3中斷分組設定:在計時器設定完後因要產生中斷,利用NVIC這相關的暫存器使TIM3中斷。
- VI. 撰寫中斷服務函數:最後需要撰寫計時器的中斷服務函式,透過該函數對計時器產生處理相關中斷。在中斷產生後,透過狀態暫存器的值來判斷此次產生的中斷是屬於類型。這次舉例為更新溢位中斷,在處理中斷完之後應該向TIM3_SR的最低為寫入0來清除該中斷標誌。
5.3 立即演練
實驗1:Timer的控制
l 實驗說明:利用3個timer(TIM2,TIM3, TIM4)分別產生1 sec, 2 sec及3 sec等3個不同時間訊號,輸出訊息至螢幕。
<目錄>/檔案 |
說明 |
|
<…\Timer_Counter\E1> |
<project> |
單元實驗project目錄 |
<source> |
程式碼目錄 |
<include |
引入檔目錄 |
<library> |
函式庫目錄 |
<image> |
燒錄配置檔目錄 |
|
<…\Timer_Counter\E1\image> |
Lab.dfu |
燒錄配置檔 |
|
<…\Timer_Counter\E1\source> |
main.c |
硬體配置程式 |
stm32f10x_it.c |
中斷服務程式 |
l 程式碼解說:
I. 程式發展流程
說明 整個程式流程為一開始初始化設定整個系統(Set_System)使得其virtual com port可以跑起來,之後設定需要使用的GPIO腳位(Gpio_configuration), TIMER(TIM_Configuration)和中斷(NVIC_Configuration)的基本設定。
II. RCC configure
說明 Enable TIM2, TIM3和TIM4。
III. GPIO configure
說明 Enable需要使用到的GPIO腳位如PIN3, PIN4及PIN5,並且將它的輸出模式設定成Output push-pull及設定他的速度為50MHz。
IV. TIMs Configure
說明 對TIMER做基本設定如其的period, prescaler, clock division, counter mode及repetition counter,並且將counter enable。另外設定TIMER的預除器的值、模式。此外要清除TIMER的更新pending flag和更新TIEMR的interrupt。
V. NVIC Configure
說明 透過NVIC對TIMER的中斷做處理,從設定他的中斷向量table、還有該中斷的IRQ channel、以及其中斷的優先權順序。
VI. IRQ Service
說明 透過中斷服務程式將每次中斷完後的pending bit清除,下次才可中斷呼叫進服務程式。
實驗2:計時碼表設計
實驗說明:使用者輸入“1”馬錶開始計時並印出;使用者輸入“2”馬錶暫停計時並印出;使用者輸入“3”馬錶繼續計時並印出;使用者輸入“4”馬錶停止計時並印出。
l 檔案結構:如表一
<目錄>/檔案 |
說明 |
|
<…\Timer_Counter\E1> |
<project> |
單元實驗project目錄 |
<source> |
程式碼目錄 |
<include |
引入檔目錄 |
<library> |
函式庫目錄 |
<image> |
燒錄配置檔目錄 |
|
<…\Timer_Counter\E1\image> |
Lab.dfu |
燒錄配置檔 |
|
<…\Timer_Counter\E1\source> |
main.c |
硬體配置程式及馬錶設定 |
stm32f10x_it.c |
中斷服務程式 |
l 程式碼解說:
可利用實驗一的範例程式下去修改,主要修改內容為主程式改用使用者輸入指令、撰寫Stopwatch_counter()副程式的時間計數以及TIM2_IRQHandler中斷服務的呼叫。
I. 程式發展流程
說明 整個程式流程為一開始初始化設定整個系統(Set_System)使得其virtual com port可以跑起來,之後設定需要使用的GPIO腳位(Gpio_configuration), TIMER(TIM_Configuration)和中斷(NVIC_Configuration)的基本設定。此外又多加了Stopwatch_counter()副程式去累加每次中斷所累計的counter數值。
II. Stopwatch Counter
說明 利用每次每秒鐘的中斷呼叫此副程式,利用變數儲存秒數且印出。
III. IRQ Service
說明 利用每一秒鐘斷實呼叫Stopwatch_counter()這個副程式壘計秒數,並且清除Pending bit以便下次中斷進入。
實驗3:以Timer產生PWM訊號
實驗說明:使用timer產生PWM訊號,控制LED燈亮度(或蜂鳴器音量、或直流馬達)。
l 檔案結構:如表一
<目錄>/檔案 |
說明 |
|
<…\Timer_Counter\E1> |
<project> |
單元實驗project目錄 |
<source> |
程式碼目錄 |
<include |
引入檔目錄 |
<library> |
函式庫目錄 |
<image> |
燒錄配置檔目錄 |
|
<…\Timer_Counter\E1\image> |
Lab.dfu |
燒錄配置檔 |
|
<…\Timer_Counter\E1\source> |
main.c |
硬體配置程式及馬錶設定 |
pwm.c |
Pwm設定 |
l 程式碼解說:
I. 程式發展流程
說明 整個程式流程為一開始初始化設定整個系統(Set_System)使得其virtual com port可以跑起來,之後設定需要使用的GPIO腳位(Gpio_configuration), TIMER(TIM_Configuration)和中斷(NVIC_Configuration)的基本設定。此外又多加了PWM_output ()副程式去pwm的duty cycle和frequency。
II. PWM output
說明 此副函式利用頻率套入公式算出Prescaler值,利用TIM_TimeBaseInit這副程式做初始設定之後再透過TIM_OC1Init設定duty cycle值。