STM32學習筆記(8)定時器相關之通用定時器

簡介

STM32中有三種定時器,包括高級定時器,通用定時器,基本定時器。以STM32F103ZET6爲例,有高級定時器(TIM1,TIM8),通用定時器(TIM2~TIM5),基本定時器(TIM6,TIM7)。(三種定時器功能區別)本篇主要講解通用定時器。

STM32F1 的通用定時器是一個通過可編程預分頻器(PSC)驅動的 16 位自動裝載計數器(CNT)構成。

工作框圖

在這裏插入圖片描述
時鐘來源:
1) 內部時鐘(CK_INT)
2) 外部時鐘模式 1:外部輸入腳(TIx)
3) 外部時鐘模式 2:外部觸發輸入(ETR)
4) 內部觸發輸入(ITRx):使用 A 定時器作爲 B 定時器的預分頻器(A 爲 B 提供時鐘)。

預分頻器:將計數器的時鐘頻率按1到65536之間的任意值分頻。它是基於一個(在TIMx_PSC寄存器中的)16位寄存器控制的16位計數器。這個控制寄存器帶有緩衝器,它能夠在工作時被改變。預分頻器參數在下一次更新事件到來時被採用。

計數器模式:
1.向上計數模式 :計數器從0計數到自動加載值(TIMx_ARR計數器的內容),然後重新從0開始計數並且產生一個計數器溢出事件;
2. 向下計數模式 :計數器從自動裝入的值(TIMx_ARR計數器的值)開始向下計數到0,然後從自動裝入的值重新開始並且產生一個計數器向下溢出事件;
3.中央對齊模式(向上/向下計數) :計數器從0開始計數到自動加載的值(TIMx_ARR寄存器)-1,產生一個計數器溢出事件,然後向下計數到1並且產生一個計數器下溢事件;然後再從0開始重新計數。
每次計數器溢出時可以產生更新事件,在TIMx_EGR寄存器中(通過軟件方式或者使用從模式控制器)設置UG位也同樣可以產生一個更新事件。

定時時間計算

以RCC的TIMxCLK作爲時鐘來源爲例子,其頻率爲72MHz,則TimeOut=(ARR+1)(PSC+1)/Tclk。即溢出時間=(自動裝載值+1)(預分頻係數+1)/頻率。此時一般使得預分頻係數爲71或7199等,便於計算。

初始化相關參數

typedef struct
{
  uint16_t TIM_Prescaler;//預分頻係數
  uint16_t TIM_CounterMode;//計數模式     
  uint16_t TIM_Period;   //自動裝入值
  uint16_t TIM_ClockDivision;//設置時鐘分頻因子    
  uint8_t TIM_RepetitionCounter;  //重複計數器
} TIM_TimeBaseInitTypeDef;

使用步驟

1.使能定時器時鐘;RCC_APB1PeriphClockCmd();
2.初始化定時器,配置ARR,PSC;TIM_TimeBaseInit();
3.開啓定時器中斷,配置NVIC;TIM_ITConfig(); NVIC_Init();
4.使能定時器;TIM_Cmd();
5.編寫相應中斷服務函數。TIM3_IRQHandler();

設置一個500ms的定時器中斷爲例:

void TIM3_Int_Init(u16 arr,u16 psc)
{
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSrtue;//初始化相應結構體
 NVIC_InitTypeDef NVIC_InitStructure;
  
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定時器時鐘
 
 TIM_TimeBaseInitSrtue.TIM_Prescaler=psc;//預分頻係數
 TIM_TimeBaseInitSrtue.TIM_CounterMode=TIM_CounterMode_Up;//向上計數
 TIM_TimeBaseInitSrtue.TIM_Period=arr;//自動裝載值
 TIM_TimeBaseInitSrtue.TIM_ClockDivision=TIM_CKD_DIV1;//設置時鐘分割:TDTS = Tck_tim
 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitSrtue);//初始化TIMx的時間基數單位
   
 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能定時器的更新中斷
 
  //中斷優先級NVIC設置
 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寄存器
 
 TIM_Cmd(TIM3,ENABLE);//使能定時器
}

void TIM3_IRQHandler(void)//中斷服務函數
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
 {
  LED1=!LED1;
  TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除相應標誌位

}

之後,在主函數裏使用該函數並使用相應參數即可

 TIM3_Int_Init(4999,7199);//500ms
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章