stm32學習之基本定時器--TIM


  stm32f1系列,有基本定時器、通用定時器、高級定時器三類TIM定時器。其中,TIM6/7是本文要講的基本定時器。

  基本定時器TIM6/7是16位的只能向上計數的定時器,只能用於定時。而通用定時器和高級定時器有更多的功能,如還可以進行輸出比較、輸入捕捉等功能,相關的介紹會寫在后面的文章,這里只講基本定時器。

  先看看基本定時器的框圖,如圖24-1。

  

 

  圖24-1

  時鍾源

  我們查閱參考手冊RCC章節的時鍾樹可以知道,RCC的定時器時鍾TIMxCLK,即內部時鍾CK_INT是由APB1預分頻器分頻后提供。如圖24-2所示,如果APB1預分頻系數為1,,則頻率不變,否則頻率為2倍。即此時用於分頻的APB1的預分頻系數為2,所以TIMxCLK = 36 * 2 = 72MHz。

  

 

  圖24-2

  計數器時鍾

  如圖24-1的框圖,計數器時鍾由內部時鍾CK_INT提供,經過PSC預分頻器后得到CK_CNT。PSC是一個16位的預分頻器,可以對定時器時鍾TIMxCLK進行1~65536之間的任何一個數進行分頻。分頻后的CK_CNT值的計算在參考手冊TIMx_PSC寄存器描述里有提到,如圖24-3。

  

 

  圖24-3

  即CK_CNT = CK_PSC/(PSC[15:0]+1)。

  計數器

  計數器CNT是一個16位的計數器,只能往上計數,最大計數值為65535。

  自動重裝載寄存器TIMx_ARR

  TIMx_ARR寄存器里存着最大的計數值,當計數到該值時,會產生中斷。當然了你得使能了中斷才可以。

  定時時間計算

  計一個數的時間是1/CK_CNT,產生一次中斷的時間為(ARR+1)/CK_CNT。如果在中斷服務程序里設置一個變量time用於記錄中斷次數,則定時時間為:(ARR+1)/CK_CNT*time。

  TIM_TimeBaseInitTypeDef

  如圖24-4為基本定時器TIM_TimeBaseInitTypeDef結構體定義。

  

 

  圖24-4

  TIM_Prescaler:指定定時器預分頻器數值,由TIMx_PSC寄存器配置,可設置范圍為0x0000~0xFFFF,即0~65535;

  TIM_CounterMode:計數模式,可分為向上計數、向下計數以及三種中心對齊模式。而基本定時器只能向上計數;

  TIM_Period:計數器周期,即自動重裝載寄存器TIMx_ARR的值,在事件生成時更新到影子寄存器,由TIMx_CR1寄存器的ARPE位配置是否使能緩沖;

  TIM_ClockDivision:時鍾分頻,配置定時器時鍾CK_INT頻率與數字濾波器采樣時鍾頻率分頻比,基本定時器沒有這個功能,不用設置;

  TIM_RepetitionCounter:重復計數器,屬於高級控制寄存器專用寄存器位,利用它可以很容易控制輸出PWM個數,這里不用設置。

  定時1s實驗

  例如,需要做一個1s的定時,CK_PSC=72MHz,則PSC=71,那么CK_CNT=1MHz,

  計一個數時間:1/CK_CNT = 1/1MHz = 1us,

  中斷一次的時間:(ARR+1)/CK_CNT = (999+1)/1MHz = 1ms,

  則定時時間:(ARR+1)/CK_CNT*time = 1ms*1000 = 1s

  我們用led的亮滅狀態變化來展示1s的定時。

  初始化TIM_TimeBaseInitTypeDef

  前文提到的TIM_TimeBaseInitTypeDef結構體有5個成員,但基本定時器TIM6/7只用到了TIM_Prescaler和TIM_Period這兩個成員,其他三個是通用定時器和高級定時器才會用到的。

 

 /**

  * @brief 基本定時器配置

  * @param 無

  * @retval 無

  */

  static void BASIC_TIM_Mode_Config(void)

  {

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); // 內部時鍾72MHz

  TIM_TimeBaseStructure.TIM_Period = 999; // 自動重裝載寄存器的值

  TIM_TimeBaseStructure.TIM_Prescaler= 71; // 預分頻器數值

  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

  TIM_ClearFlag(TIM6, TIM_FLAG_Update); // 清除計數器中斷標志位

  TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

  TIM_Cmd(TIM6, ENABLE);

  }

 

  中斷優先級配置

  有關中斷配置相關已經在之前的文章介紹過,有不清楚的地方可移步閱讀。這里只說幾個配置的關鍵點。可配置中斷優先級分組為0,即0位搶占優先級,4位子優先級。配置中斷源為TIM6_IRQn。

  

/**

  * @brief 中斷優先級配置

  * @param 無

  * @retval 無

  */

  static void BASIC_TIM_NVIC_Config(void)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  }

 

  中斷函數

  中斷函數在stm32f10x_it.c文件里配置。

  

extern volatile uint32_t time; // 該變量定義在main()函數里

  void TIM6_IRQHandler(void)

  {

  if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)

  {

  time++; // 每中斷一次,time值加1,中斷一次時間為1ms,需要中斷1000次才可定時1s,即time值為1000

  TIM_ClearITPendingBit(TIM6, TIM_FLAG_Update);

  }

  }

 

  最后在main()函數里調用led和定時器的初始化配置函數,在一個循環里判斷time變量的值是否為1000,如果已經達到1000,則led燈狀態變化(亮或滅)一次,並且time變量值重賦為0,以便繼續判斷及定時。

最后給大家分享些smt32方面的資料便於學習參考

(STM32中斷系統)
http://www.makeru.com.cn/live/1392_1124.html?s=45051

(定時器)
http://www.makeru.com.cn/live/1392_1199.html?s=45051

基於STM32-WiFi智能小車機器人開發實戰
http://www.makeru.com.cn/course/details/3008?s=45051

 


免責聲明!

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



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