STM32 學(xué)習筆記_TIME定時器詳解1
基本的基時單元就是上面提及的這幾個,下面看看3.0庫是如何實習的基本使用。
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_DeInit(TIM2); //重新將Timer設(shè)置為缺省值
TIM_InternalClockConfig(TIM2); //采用內(nèi)部時鐘給TIM2提供時鐘源
TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1; //預(yù)分頻系數(shù)為36000-1,這樣計數(shù)器時鐘為72MHz/36000 = 2kHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時鐘分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設(shè)置計數(shù)器模式為向上計數(shù)模式
TIM_TimeBaseStructure.TIM_Period = 2000 - 1; //設(shè)置計數(shù)溢出大小,每計2000個數(shù)就產(chǎn)生一個更新事件
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //將配置應(yīng)用到TIM2中
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除溢出中斷標志
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //開啟TIM2的中斷
以上是一個最基本的定時器配置的代碼,載自網(wǎng)上被轉(zhuǎn)載無數(shù)次的地方……
中斷函數(shù)自己按照需求寫,這里不多說。
在庫中的初始化函數(shù)和初始化數(shù)據(jù)類型有3類,TIM_TimeBaseInitTypeDef、TIM_OCInitTypeDef、TIM_ICInitTypeDef
與基時參數(shù)相關(guān)的數(shù)據(jù)類型是TIM_TimeBaseInitTypeDef
typedef struct
{
uint16_t TIM_Prescaler;
uint16_t TIM_CounterMode;
uint16_t TIM_Period;
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
以上是從庫stm32f10x_tim.h中截取的代碼,整體的數(shù)據(jù)結(jié)構(gòu)可以中這段注釋中得知,不懂E文的要么翻字典要么翻庫函數(shù)中文翻譯
版本(當然這個是2.0的庫,有部分會和3.0后的版本很不相同),這部分的數(shù)據(jù)類型還是很一樣的,不多說。
接著就是TIM_TimeBaseInit()這個函數(shù)了,在stm32f10x_tim.c的224行中
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
{
uint16_t tmpcr1 = 0;
assert_param(IS_TIM_ALL_PERIPH(TIMx));
assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
tmpcr1 = TIMx->CR1;
if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
(TIMx == TIM4) || (TIMx == TIM5))
{
tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
}
if((TIMx != TIM6) && (TIMx != TIM7))
{
tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
}
TIMx->CR1 = tmpcr1;
TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))
{
TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
}
TIMx->EGR = TIM_PSCReloadMode_Immediate;
}
可以看3.0后的函數(shù)里把所有的TIMx都加入一個函數(shù)里面做判斷了,不需要和2.0的區(qū)分TIM1和TIM 兩類函數(shù),比較其基本操作都一樣無非就是多了一個兩個寄存器而已。
程序中可以看到這一段:
if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
(TIMx == TIM4) || (TIMx == TIM5))
{
?
tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
}
if((TIMx != TIM6) && (TIMx != TIM7))
{
tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
}
TIMx->CR1 = tmpcr1;
高級定時器和通用定時器擁有向上計數(shù)、向下技術(shù)、向上/向下模式,三種,而基本計時器只有向上計數(shù)一種,因此TIM6和TIM7木有的設(shè)置計數(shù)模式,tmpcr1首先裝入了控制寄存器CR1d 值,然后把其中DIR(位4)和CMS(位6:5)清除,然后或運算上載入數(shù)據(jù)結(jié)構(gòu)中的值,這里代碼再跳轉(zhuǎn)到stm32f10x_tim.h中第362行
#define TIM_CounterMode_Up ((uint16_t)0x0000)
#define TIM_CounterMode_Down ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) 定義的是TIM_CounterMode的幾種情況,即控制計數(shù)器向上
技術(shù)或向下計數(shù),或是向上向下交替計數(shù),當設(shè)置的是交替計數(shù)的情況DIR位為只讀。
TIM_ClockDivision為時鐘分配因子,其中有 0、2x、4x ,在AHB低時鐘時為提高定時精度而實用的倍頻器,位于CR1寄存器中的位9:8。這段程序便配置好了CR1寄存器,然后再看下面的程序。載入了PSC寄存器和ARR寄存器值,如果是高級定時器還有RCR寄存器值,在這一步便基本配置得差不多了,但還是發(fā)現(xiàn)函數(shù)最后還有一句 TIMx->EGR = TIM_PSCReloadMode_Immediate; 這里在事件寄存器中做了一次軟件的事件更新觸發(fā)使得其UG位置1。
#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001)
評論