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