STM32定時器概述
STM32F40x系列總共最多有14個定時器,定時器分為三類:基本定時器、通用定時器和進階定時器。它們的都是通過計數來達到定時的目的,和51的定時器差不多,基本原理都是一樣的,就是功能多了一些,這些計數器都是自動重新裝載初值的,使用起來非常友善,而且計數時鐘頻率可以通過分頻系數來設定。本文章将介紹使用定時器中斷來控制LED間隔1s閃爍。

計數的時鐘來源主要有四個:
- 内部時鐘CK_INT
- 外部時鐘模式1:外部輸入腳TIx
- 外部時鐘模式2:外部觸發輸入ETR,僅适用于 TIM2、 TIM3、 TIM4
- 内部觸發輸入ITRx:使用 A 定時器作為 B 定時器的預分頻器(A為B提供時鐘)
我們使用定時器内部時鐘,即CK_INT作為計數器的時鐘源 = 168MHz / 2 = 84MHz
時鐘框圖如下:
定時器的配置
1.使能定時器時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //定時器3時鐘使能
2.初始化定時器參數,設定分頻系數和計數初值,計數模式設定等。如果要定時1s定時器溢出,那麼可以設定分頻系數為8400 ,則分頻後的時鐘頻率為 : 84MHz / 8400 = 10KHz = 0。1ms ,計數初值設定為1s / 0。1 ms = 10000即可。
/*初始化定時器參數,設定自動重裝值,分頻系數,計數方式*/
TIM_Init。TIM_ClockDivision= TIM_CKD_DIV1; //時鐘分頻因子
TIM_Init。TIM_CounterMode=TIM_CounterMode_Up; //定時器模式
TIM_Init。TIM_Period=Period; //自動重裝值,0-65535
TIM_Init。TIM_Prescaler= Prescaler;
// TIM_Init。TIM_Prescaler= 8400; //分頻系數-0。1ms
// TIM_Init。TIM_Prescaler= 42000; //分頻系數-0。5ms
// TIM_Init。TIM_RepetitionCounter=
TIM_TimeBaseInit(TIM3,&TIM_Init);
TIM_RepetitionCounter是使用進階定時器要進行設定的。我們使用的是定時器3,屬于通用定時器,計數模式設定為向上計數,則計數器從0 開始計數,當計數到設定的初值時,然後計數器重新從0開始計數,并将溢出标志位置1,如果設定了溢出中斷,則會産生計數器溢出中斷。
3.定時器3中斷設定,注意優先級的設定,如果程式中開啟了多個中斷。就要考慮中斷優先級的設定,本程式隻使用了一個定時器中斷,則配置為任何優先級都是可以的。
/*定時器3中斷優先級設定*/
NC_Init。NVIC_IRQChannel=TIM3_IRQn; //中斷通道指定定時器3
NC_Init。NVIC_IRQChannelCmd= ENABLE;
NC_Init。NVIC_IRQChannelPreemptionPriority=0; //設定搶占優先級
NC_Init。NVIC_IRQChannelSubPriority=0; //設定響應優先級
NVIC_Init(&NC_Init);
4.使能定時器,當執行完這一句後,定時器就開始從 0 開始計數了。我們可以通過使能定時器來暫停計數器,或者使能定時器來啟動定時器,在開發時鐘時可以使用這個。
相當于51中的TR1 = 1 / TR1 = 0
TIM_Cmd(TIM3,ENABLE);
5.中斷服務函數,本程式是讓LED1間隔1s閃爍,那麼中斷服務函數的功能就是讓LED1的狀态反轉。
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)) //如果産生溢出中斷
{
LED1=!LED1; //那麼狀态反轉
// LED0=!LED0;
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清楚更新中斷标志位
}
這裡檢測的是定時器溢出中斷,即計時1s時間到,則将LED1的狀态反轉,然後将溢出标志位清零。
主函數
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
LED_Init(); //LED初始化熄滅
Timer3_Config(2000,42000); //0.5ms*2000 = 1s
while(1)
{
LED0=!LED0;
delay_ms(1000);
}
}
這裡使用延時函數來延時1s控制LED0閃爍,實際運作效果可以看出兩個LED的閃爍在一定的時間内是同步的,但是時間一長還是有點誤差。
總結
當學完這一節定時器的時候,我就有一個想法了,那就是寫一個LCD電子時鐘的程式,通過定時器來達到準确延時的目的,當然還要學習一下LCD1602的驅動方法,哈哈,想想就很有成就感。
參考資料:
STM32F4_TIM基本延時(計數原理) STM32-通用定時器基本定時功能STM32F4xx中文參考手冊
以上是我學習過程的一些個人了解,有不對或不準确的地方,歡迎各位大神指正。
2017年4月21日21:33:44