TIM——基本定時器

 

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

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

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

圖24-1spa

時鐘源

咱們查閱參考手冊RCC章節的時鐘樹能夠知道,RCC的定時器時鐘TIMxCLK,即內部時鐘CK_INT是由APB1預分頻器分頻後提供。如圖24-2所示,若是APB1預分頻係數爲1,,則頻率不變,不然頻率爲2倍。即此時用於分頻的APB1的預分頻係數爲2,因此TIMxCLK = 36 * 2 = 72MHz。3d

圖24-2code

計數器時鐘

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

圖24-3事件

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

計數器

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

自動重裝載寄存器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,以便繼續判斷及定時。

相關文章
相關標籤/搜索