STM32定時器(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)高級定時器+普通定時器,配置使用


2.1    時鍾來源

計數器時鍾可以由下列時鍾源提供:

·內部時鍾(CK_INT)

·外部時鍾模式1:外部輸入腳(TIx)

·外部時鍾模式2:外部觸發輸入(ETR)

       ·內部觸發輸入(ITRx):使用一個定時器作為另一個定時器的預分頻器,如可以配置一個定時器Timer1而作為另一個定時器Timer2的預分頻器。

    由於今天的學習是最基本的定時功能,所以采用內部時鍾。TIM2-TIM5的時鍾不是直接來自於APB1,而是來自於輸入為APB1的一個倍頻器。這個倍頻器的作用是:當APB1的預分頻系數為1時,這個倍頻器不起作用,定時器的時鍾頻率等於APB1的頻率(36MHZ);

當APB1的預分頻系數為其他數值時(即預分頻系數為2、4、8或16),這個倍頻器起作用,定時器的時鍾頻率等於APB1的頻率的2倍。

{       

        假如APB1預分頻為2(變成36MHZ),則定時器TIM2-5的時鍾倍頻器起作用,將變成2倍的APB1(2x36MHZ)將為72MHZ給定時器提供時鍾脈沖。 一般APB1和APB2的RCC時鍾配置放在初始化函數中例如下面的void RCC_Configuration(void)配置函數所示,將APB1進行2分頻,導致TIM2時鍾變為72MHZ輸入。

如果是1分頻則會是36MHZ輸入,如果4分頻:CKINT=72MHZ/4x2=36MHZ;  8分頻:CKINT=72MHZ/8x2=18MHZ;16分頻:CKINT=72MHZ/16x2=9MHZ 

   }

//系統時鍾初始化配置
void RCC_Configuration(void)
{
    //定義錯誤狀態變量
   ErrorStatus HSEStartUpStatus;
   //將RCC寄存器重新設置為默認值
   RCC_DeInit();
   //打開外部高速時鍾晶振
   RCC_HSEConfig(RCC_HSE_ON);
   //等待外部高速時鍾晶振工作
   HSEStartUpStatus = RCC_WaitForHSEStartUp();
   if(HSEStartUpStatus == SUCCESS)
   {
          //設置AHB時鍾(HCLK)為系統時鍾
          RCC_HCLKConfig(RCC_SYSCLK_Div1);
          //設置高速AHB時鍾(APB2)為HCLK時鍾
          RCC_PCLK2Config(RCC_HCLK_Div1);
          //設置低速AHB時鍾(APB1)為HCLK的2分頻(TIM2-TIM5輸入TIMxCLK頻率將為72MHZ/2x2=72MHZ輸入)
          RCC_PCLK1Config(RCC_HCLK_Div2);
          //設置FLASH代碼延時
          FLASH_SetLatency(FLASH_Latency_2);
          //使能預取指緩存
          FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
          //設置PLL時鍾,為HSE的9倍頻 8MHz * 9 = 72MHz
          RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
          //使能PLL
          RCC_PLLCmd(ENABLE);
          //等待PLL准備就緒
          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
          //設置PLL為系統時鍾源
          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
          //判斷PLL是否是系統時鍾
          while(RCC_GetSYSCLKSource() != 0x08);
   }
   //允許TIM2的時鍾
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
   //允許GPIO的時鍾
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
}

三、定時器代碼實例

 中斷優先級就不貼出來了,自己可以配置下

 Tout= ((arr+1)*(psc+1))/Tclk;

arr:計數重裝值,psc分頻數,Tclk系統時鍾頻率,Tout一個周期的時間。

 Tout= ((arr+1)*(psc+1))/Tclk;

 3.1、定時器1使用

這里假設APB2時鍾是1分頻即72MHZ(如果是4分頻則為36MHZ [=72MHZ/4x2=36MHZ] )配置,void RCC_Configuration(void)中配置如下代碼:

1           //設置高速AHB時鍾(APB2)為HCLK時鍾
2           RCC_PCLK2Config(RCC_HCLK_Div1);

則這里:APB2的時鍾為1分頻故出來的APB2時鍾還是72MHZ,TIM1對系統時鍾APB2(72MHZ)再進行7200分頻,然后計數重載初值設置為100,則一個定時周期Tout=(100-1+1)*(7200-1+1)/72,000,000=1/10=0.1s,即100ms為一個計數周期

1 //放到主函數的初始化中初始化
 2 void Timer1CountInitial(void)
 3 {
 4     //定時=36000/72000x2=0.001s=1ms;
 5         TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
 6         ///////////////////////////////////////////////////////////////
 7         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
 8         
 9         TIM_TimeBaseStructure.TIM_Period = 100-1;//自動重裝值(此時改為100ms)
10         TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;//時鍾預分頻
11 //        TIM_TimeBaseStructure.TIM_Prescaler = 36000-1;//時鍾預分頻
12         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數
13 //        TIM_TimeBaseStructure.TIM_Period = 2-1;//自動重裝值
14 //        TIM_TimeBaseStructure.TIM_Period = 10-1;//自動重裝值(此時改為10ms)
15         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        //時鍾分頻1
16         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;            
17         TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
18         
19         TIM_ClearFlag(TIM1,TIM_FLAG_Update);
20         TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);  
21         TIM_Cmd(TIM1, ENABLE);
22 }
23 
24 
25 void TIM1_UP_IRQHandler(void)
26 {        
27     //TIM_TimeBaseStructure.TIM_Period = 100-1;//自動重裝值(此時進中斷的周期為100ms)
28     if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
29     {  
30         //添加行程開關去抖程序
31         if(XingChengTickNum_QuFantan<1000)//
32         {
33             XingChengTickNum_QuFantan++;
34         }             5455     TIM_ClearITPendingBit(TIM1,TIM_IT_Update);58 }

3.2、定時器2使用

 Tout= ((arr+1)*(psc+1))/Tclk;

arr:計數重裝值,psc分頻數,Tclk系統時鍾頻率,Tout一個周期的時間。

假設APB1時鍾是2分頻即72MHZ(如果是1分頻則為36MHZ)配置,void RCC_Configuration(void)中配置如下代碼:

//設置低速AHB時鍾(APB1)為HCLK的2分頻(TIM2-TIM5輸入TIMxCLK頻率將為72MHZ/2x2=72MHZ輸入)
 RCC_PCLK1Config(RCC_HCLK_Div2);

這里:APB1的時鍾為分頻故出來的APB2時鍾還是72MHZ,TIM1是對系統時鍾APB2(72MHZ)進行7200分頻,

則:Tout=(4-1+1)*(36000-1+1)/72,000,000=4/2,000=2ms

void TIM2_Int_Init(void)
{
    TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_DeInit(TIM2);

    TIM_TimeBaseStructure.TIM_Period = 4 - 1;//2000 - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = (36000 - 1);
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM2, ENABLE);
}
void TIM2_IRQHandler(void)
{

    if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {
                interrupt_rtc();//可以使你自己定義的執行函數
    }
     TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);
}

3.3、定時器3使用

 假設APB1時鍾是2分頻即72MHZ(如果是1分頻則為36MHZ)配置,void RCC_Configuration(void)中配置如下代碼:

1           //設置低速AHB時鍾(APB1)為HCLK的2分頻(TIM2-TIM5輸入TIMxCLK頻率將為72MHZ/2x2=72MHZ輸入)
2           RCC_PCLK1Config(RCC_HCLK_Div2);
TIM3_Int_Init(4-1,36000-1);

則:Tout=(4-1+1)*(36000-1+1)/72,000,000=4/2,000=2ms

//通用定時器3中斷初始化
//這里時鍾選擇為APB1的2倍,而APB1為36M
//arr:自動重裝值。
//psc:時鍾預分頻數
//這里使用的是定時器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時鍾使能

    TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值     計數到5000為500ms
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鍾頻率除數的預分頻值  10Khz的計數頻率
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鍾分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中斷
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優先級0級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優先級3級
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器

    TIM_Cmd(TIM3, ENABLE);  //使能TIMx外設

}
//定時器3中斷服務程序
void TIM3_IRQHandler(void)   //TIM3中斷
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查指定的TIM中斷發生與否:TIM 中斷源
        {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中斷待處理位:TIM 中斷源
        LED1=!LED1;
        }
}

3.4、定時器4使用

 假設APB1時鍾是4分頻即72/4=18MHZ(如果是4分頻則TIMxCLK=18MHZx2=36MHZ)配置,void RCC_Configuration(void)中配置如下代碼:

1 //在void RCC_Configuration(void)中配置APB1時鍾4分頻或1分頻都變為36MHZ
2 //設置低速AHB時鍾(APB1)為HCLK的4分頻(TIM2-TIM5輸入TIMxCLK頻率將為72MHZ/4x2=36MHZ輸入)
3 RCC_PCLK1Config(RCC_HCLK_Div4);//加入使用4分頻
TIM4_Int_Init(4-1,36000-1);

則:Tout=(4-1+1)*(36000-1+1)/36,000,000=4/1,000=4ms

void TIM4_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //時鍾使能
    //定時器TIM4初始化
    TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鍾頻率除數的預分頻值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鍾分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據指定的參數初始化TIMx的時間基數單位
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中斷,允許更新中斷

    //中斷優先級NVIC設置
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM3中斷
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優先級0級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先級3級
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器


    TIM_Cmd(TIM4, ENABLE); //使能TIMx
}


//定時器4中斷服務程序
void TIM4_IRQHandler(void) //TIM3中斷
{
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //檢查TIM4更新中斷發生與否
    {
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); //清除TIMx更新中斷標志
        LED0=!LED0;
        // Get_Angle();
    }
}

3.5、定時器5使用

假設APB1時鍾是1分頻即36MHZ(如果是1分頻則TimexCLK=36MHZx1=36MHZ)配置,void RCC_Configuration(void)中配置如下代碼:

1 //在void RCC_Configuration(void)中配置APB1時鍾4分頻或1分頻都變為36MHZ
2 //設置低速AHB時鍾(APB1)為HCLK的4分頻(TIM2-TIM5輸入TIMxCLK頻率將為72MHZ/4x2=36MHZ輸入)
3 RCC_PCLK1Config(RCC_HCLK_Div1);//假如使用1分頻
TIM5_Int_Init(4-1,36000-1);

則:Tout=(4-1+1)*(36000-1+1)/36,000,000=4/1,000=4ms

void TIM5_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //時鍾使能

    TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值     計數到5000為500ms
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鍾頻率除數的預分頻值  10Khz的計數頻率
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鍾分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

    TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷

    NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3中斷
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優先級0級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優先級3級
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器

    TIM_Cmd(TIM5, ENABLE);  //使能TIMx外?
}
//定時器5中斷服務程序
void TIM5_IRQHandler(void)   //TIM3中斷
{
    if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //檢查指定的TIM中斷發生與否:TIM 中斷源
        {
        TIM_ClearITPendingBit(TIM5, TIM_IT_Update  );  //清除TIMx的中斷待處理位:TIM 中斷源
        LED1=!LED1;
        }
}

 


免責聲明!

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



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