STM32——定时器分频计算

时间:2022-04-05 23:35:40

在平时的工作做经常会遇到需要延时处理的情况。对于对时间要求不严格的延时来说,我们可以用for loop这些循环结构来实现延时。但对于一些对时间要求比较严格的情况,for loop明显就不适用了。这个时候我经常会使用定时器来辅助延时,STM32的定时器又灰常的NB,也灰常的让人头大(对于我这样的小白来说)。下面通过一个例子来说明定时器定时相关计算。

Timer相关计算

 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中各个字段的理解。

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两个结合起来达到定时的效果。

TIM_Prescaler = 7199, //7200分频      72MHz/(7199+1)=1MHz

TIM_Period = 9; //计数值9

最终定时结果fout = ((1+TIM_Prescaler)/72M)*(1+TIM_Period ) = ((7200)/72M)*(1+9) = 1000Hz。