STM32學習筆記(五)——通用定時器計數延時


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM