在平时的工做作常常会遇到须要延时处理的状况。对于对时间要求不严格的延时来讲,咱们能够用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