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的驅動方法,哈哈,想想就很有成就感。
參考資料:
STM32F4xx中文參考手冊
以上是我學習過程的一些個人理解,有不對或不准確的地方,歡迎各位大神指正。
2017年4月21日21:33:44