在平時的工做作常常會遇到須要延時處理的狀況。對於對時間要求不嚴格的延時來講,咱們能夠用for loop這些循環結構來實現延時。但對於一些對時間要求比較嚴格的狀況,for loop明顯就不適用了。這個時候我常常會使用定時器來輔助延時,STM32的定時器又灰常的NB,也灰常的讓人頭大(對於我這樣的小白來講)。下面經過一個例子來講明定時器定時相關計算。oop
1 /*set the timer to 1ms*/ 2 void timer_config(void) 3 { 4 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; 5 6 TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; 7 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; 8 TIM_TimeBaseInitStruct.TIM_Period = 9; 9 TIM_TimeBaseInitStruct.TIM_Prescaler = 7199; 10 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; 11 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); 12 13 TIM_ClearFlag(TIM2, TIM_FLAG_Update); 14 TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); 15 TIM_Cmd(TIM2, ENABLE); 16 }
上面代碼的功能是將TIM2的定時時間設置爲1ms。下面咱們來講說我對TIM_TimeBaseInitTypeDef中各個字段的理解。spa
TIM_ClockDivision | 手冊上說的是內部時鐘(CK_INT)和數字濾波器(ETR ,TIx) 使用的採樣頻率之間的分頻比例。這裏我不太明白,但願知道的人說一下 |
TIM_CounterMode | 計數模式,是向上計數仍是向下計數 |
TIM_Period | Auto-Reload Register的值 |
TIM_Prescaler | 定時器分頻數,0-65535 |
TIM_RepetitionCounter | 重複計數,也就是說Timer重複溢出多少次纔給給出一個溢出中斷, 它對應的寄存器叫RCR. 若是這個值不初始化,由於上電的時候寄存器值但是隨機的,因此原本1s中斷一次,可能變成Ns中斷一次,這確定不是咱們但願見到的情景 |
那下面就來看看上面的代碼爲何可以實現1ms定時,由於我是使用庫的,因此默認TIM2的時鐘是72MHz。所以想要獲得1ms的定時就須要對時鐘進行72000分頻。由於720000〉65535所以沒法單純的使用prescaler來實現分頻。所以,須要將prescaler和period兩個結合起來達到定時的效果。code
TIM_Prescaler = 7199, //7200分頻 72MHz/(7199+1)=1MHzblog
TIM_Period = 9; //計數值9it
最終定時結果fout = ((1+TIM_Prescaler)/72M)*(1+TIM_Period ) = ((7200)/72M)*(1+9) = 1000Hz。io