一、定時器介紹
STM32F1的定時器非常多,由2個基本定時器(TIM6、TIM7)、4個通 用定時器(TIM2-TIM5)和2個高級定時器(TIM1、TIM8)組成。基本定 時器的功能最為簡單,類似於51單片機內定時器。通用定時器是在基本 定時器的基礎上擴展而來,增加了輸入捕獲與輸出比較等功能。高級定 時器又是在通用定時器基礎上擴展而來,增加了可編程死區互補輸出、 重復計數器、帶剎車(斷路)功能,這些功能主要針對工業電機控制方面
1.1 通用定時器簡介
STM32F1的通用定時器包含一個 16 位自動重載計數器(CNT),該計 數器由可編程預分頻器(PSC)驅動。STM32F1的通用定時器可用於多種 用途,包括測量輸入信號的脈沖寬度(輸入捕獲)或者生成輸出波形(輸出 比較和PWM)等。 使用定時器預分頻器和 RCC 時鍾控制器預分頻器,脈 沖長度和波形周期可以在幾個微秒到幾個毫秒間調整。STM32F1 的每個 通用定時器都是完全獨立的,沒有互相共享的任何資源。
STM32F1的通用定時器TIMx (TIM2-TIM5 )具有如下功能:
(1)16 位向上、向下、向上/向下自動裝載計數器(TIMx_CNT)。
(2)16 位可編程(可以實時修改)預分頻器(TIMx_PSC),計數器時鍾頻率的分頻系數為 1~65535之間的任意數值。
(3)4個獨立通道(TIMx_CH1-4),這些通道可以用來作為: A.輸入捕獲 B.輸出比較 C. PWM 生成(邊緣或中間對齊模式) D.單脈沖模式輸出
(4)可使用外部信號(TIMx_ETR)控制定時器,且可實現多個定時器互連(可以用1個定時器控制另外一個定時器)的同步電路。
(5)發生如下事件時產生中斷/DMA請求: A.更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發) B.觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數) C.輸入捕獲 D.輸出比較
(6)支持針對定位的增量(正交)編碼器和霍爾傳感器電路
(7)觸發輸入作為外部時鍾或者按周期的電流管理
1.2 通用定時器結構框圖

二、通用定時器配置步驟
(1)使能定時器時鍾 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4時鍾
(2)初始化定時器參數,包含自動重裝值,分頻系數,計數方式等
voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
typedef struct
{
uint16_t TIM_Prescaler; //定時器預分頻器
uint16_t TIM_CounterMode; //計數模式
uint32_t TIM_Period; //定時器周期
uint16_t TIM_ClockDivision; //時鍾分頻
uint8_t TIM_RepetitionCounter; //重復計數器
} TIM_TimeBaseInitTypeDef;
了解結構體成員功能后,就可以進行配置,例如:
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_Period=1000; //自動裝載值 自己定義
TIM_TimeBaseInitStructure.TIM_Prescaler=35999; //分頻系數 自己定義
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //設置向上計數模式
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
定時器定時時間計算公式如下: Tout= ((per)*(psc+1))/Tclk; 1000*(35999+1)/72;
(3)設置定時器中斷類型,並使能
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
(4)設置定時器中斷優先級,使能定時器中斷通道 NVIC初始化庫函數是NVIC_Init();
(5)開啟定時器 void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
(6)編寫定時器中斷服務函數
三、定時器中斷編碼
1 /******************************************************************************* 2 * 函 數 名 : TIM4_Init 3 * 函數功能 : TIM4初始化函數 4 * 輸 入 : per:重裝載值 5 psc:分頻系數 6 * 輸 出 : 無 7 *******************************************************************************/
8 void TIM4_Init(u16 per,u16 psc) 9 { 10 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; 11 NVIC_InitTypeDef NVIC_InitStructure; 12
13 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4時鍾
14
15 TIM_TimeBaseInitStructure.TIM_Period=per; //自動裝載值
16 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分頻系數
17 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 18 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //設置向上計數模式
19 TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure); 20
21 TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //開啟定時器中斷
22 TIM_ClearITPendingBit(TIM4,TIM_IT_Update); 23
24 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//定時器中斷通道
25 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//搶占優先級
26 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優先級
27 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
28 NVIC_Init(&NVIC_InitStructure); 29
30 TIM_Cmd(TIM4,ENABLE); //使能定時器
31 }
進入中斷函數
1 /******************************************************************************* 2 * 函 數 名 : TIM4_IRQHandler 3 * 函數功能 : TIM4中斷函數 4 * 輸 入 : 無 5 * 輸 出 : 無 6 *******************************************************************************/
7 void TIM4_IRQHandler(void) 8 { 9 if(TIM_GetITStatus(TIM4,TIM_IT_Update)) 10 { 11 //填寫中斷中要完成的任務
12 } 13 TIM_ClearITPendingBit(TIM4,TIM_IT_Update); 14 }