一、定時器分類
STM32F1 系列中,除了互聯型的產品,共有 8 個定時器,分為基本定時器,通用定時器和高級定時器。基本定時器 TIM6 和 TIM7 是一個 16 位的只能向上計數的定時器,只能定時,沒有外部 IO。通用定時器 TIM2/3/4/5 是一個 16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,每個定時器有四個外部 IO。高級定時器 TIM1/8是一個 16 位的可以向上/下計數的定時器,可以定時,可以輸出比較,可以輸入捕捉,還可以有三相電機互補輸出信號,每個定時器有 8 個外部 IO。
基本定時器的核心是時基,通用計時器和高級定時器也有。
1、時鐘源
定時器時鐘TIMxCLK,即內部時鐘CK_INT,經APB1預分頻器后分頻提供,如果APB1 預分頻系數等于 1,則頻率不變,否則頻率乘以 2,庫函數中 APB1 預分頻的系數是 2,即 PCLK1=36M,所以定時器時鐘 TIMxCLK=36*2=72M 。
2、計數器時鐘
定時器時鐘經過 PSC 預分頻器之后,即 CK_CNT,用來驅動計數器計數。PSC 是一個16 位的預分頻器,可以對定時器時鐘 TIMxCLK 進行 1~65536 之間的任何一個數進行分頻。
具體計算方式為:CK_CNT=TIMxCLK/(PSC+1)。
3.計數器
計數器 CNT 是一個 16 位的計數器,只能往上計數,最大計數值為 65535。當計數達到自動重裝載寄存器的時候產生更新事件,并清零從頭開始計數。
4、自動重裝載寄存器
自動重裝載寄存器 ARR 是一個 16 位的寄存器,這里面裝著計數器能計數的最大數值。當計數到這個值的時候,如果使能了中斷的話,定時器就產生溢出中斷。
5. 定時時間的計算
定時器的定時時間等于計數器的中斷周期乘以中斷的次數。計數器在 CK_CNT 的驅動下,計一個數的時間則是 CK_CLK 的倒數,等于:1/(TIMxCLK/(PSC+1)),產生一次中斷的時間則等于:1/(CK_CLK * ARR)。如果在中斷服務程序里面設置一個變量 time,用來記錄中斷的次數,那么就可以計算出我們需要的定時時間等于: 1/CK_CLK *(ARR+1)*time。
1.定義
設置等待時間,到達等待時間之后執行指定的硬件操作。
定時器最基本的功能就是定時,比如說定時發送串口數據,定時采集AD數據,也可以產生PWM方波等,定時器產生PWM控制電機狀態是工業控制的普通。
2、STM32F4xx系列的芯片:2個高級控制定時器(TIM1和TIM8)、10個通用定時器(10TIM2-TIM5,TIM9-TIM14)、2個基本定時器(TIM6和TIM7)、2個看門狗定時器
具體可參考中文參考手冊了解其特性及原理
3、定時器計數模式:
通用定時器可以向上計數、向下計數、向上向下雙向計數模式。
①向上計數模式:計數器從0計數到自動加載值(TIMx_ARR),然后重新從0開始計數并且產生一個計數器溢出事件。
②向下計數模式:計數器從自動裝入的值(TIMx_ARR)開始向下計數到0,然后從自動裝入的值重新開始,并產生一個計數器向下溢出事件。
③中央對齊模式(向上/向下計數):計數器從0開始計數到自動裝入的值-1,產生一個計數器溢出事件,然后向下計數到1并且產生一個計數器溢出事件;然后再從0開始重新計數。
如圖:
4、通用定時器工作原理:
● 計數器寄存器 (TIMx_CNT)
● 預分頻器寄存器 (TIMx_PSC)
● 自動重載寄存器 (TIMx_ARR)
假如是向上增長模式,計數器(CNT)從0加到自動重載值(ARR),預分頻器(PSC)減一次。
時間計算方式:
假設頻率為:42M*2 == 84M == 84000000 == 1s //42根據定時器時鐘數可知 并且一般都是*2
定時器定時1s產生中斷:
ARR = 84000; // 1ms
PSC = 1000; // 1000*1ms == 1s
如圖:可知基本定時器的時鐘是42M,那么對應*2就是84M=84000000=1S(ARR*PSC)
高級的既是84*2=96M=96000000=1S
-----------------------------------------------------------------------------------------------------------------------------------------------------------
5、定時器中斷實現步驟
//5.1、能定時器時鐘。
RCC_APB1PeriphClockCmd();
//5.2、初始化定時器,配置ARR,PSC。(申明結構體)
TIM_TimeBaseInit();
typedef struct
{
uint16_t TIM_Prescaler;
uint16_t TIM_CounterMode;
uint16_t TIM_Period;
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
//5.3、啟定時器中斷,配置NVIC(申明結構體)
NVIC_Init();
進行NVIC中斷配置
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定時器 3 中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //搶占優先級 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //響應優先級 3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);// ④初始化 NVIC
TIM_Cmd(TIM3,ENABLE); //⑤使能定時器 3
//5.4、設置 TIM3_DIER 允許更新中斷
TIM_ITConfig();
//5.5、使能定時器。
TIM_Cmd();
//5.6、編寫中斷服務函數。
TIMx_IRQHandler();
//定時器 3 中斷服務函數
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中斷
{
/*處理的程序段*/
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中斷標志位
}
TIM3_Int_Init(5000-1,8400-1); //定時器時鐘84M,分頻系數8400,所以84M/8400=10Khz的計數頻率,計數5000次為500ms
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3時鐘
TIM_TimeBaseInitStructure.TIM_Period = arr; //自動重裝載值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時器分頻
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允許定時器3更新中斷
TIM_Cmd(TIM3,ENABLE); //使能定時器3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定時器3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //搶占優先級1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//定時器3中斷服務函數
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中斷
{
LED1=!LED1;//DS1翻轉
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中斷標志位
}
定時器初始化結構體詳解
在標準庫函數頭文件stm32f10x_tim.h中對定時器外設建立了四個初始化結構體,基本定時器只用到其中一個即TIM_TimeBaseInitTypeDef,其他三個在高級定時器章節講解。
typedef struct {
uint16_t TIM_Prescaler; // 預分頻器
uint16_t TIM_CounterMode; // 計數模式
uint32_t TIM_Period; // 定時器周期
uint16_t TIM_ClockDivision; // 時鐘分頻
uint8_t TIM_RepetitionCounter; // 重復計算器
} TIM_TimeBaseInitTypeDef;1234567
(1) TIM_Prescaler:定時器預分頻器設置,時鐘源經該預分頻器才是定時器時鐘,它設定TIMx_PSC 寄存器的值。可設置范圍為 0 至 65535,實現 1至 65536 分頻。
(2) TIM_CounterMode:定時器計數方式,可是在為向上計數、向下計數以及三種中心對齊模式。基本定時器只能是向上計數,即 TIMx_CNT只能從 0開始遞增,并且無需初始化。
(3) TIM_Period:定時器周期,實際就是設定自動重載寄存器的值,在事件生成時更新到影子寄存器。可設置范圍為 0至 65535。
(4) TIM_ClockDivision:時鐘分頻,設置定時器時鐘 CK_INT 頻率與數字濾波器采樣時鐘頻率分頻比,基本定時器沒有此功能,不用設置。
(5) TIM_RepetitionCounter:重復計數器,屬于高級控制寄存器專用寄存器位,利用它可以非常容易控制輸出 PWM 的個數。這里不用設置。
雖然定時器基本初始化結構體有 5 個成員,但對于基本定時器只需設置其中兩個就可以。
評論
查看更多