引入:
定时器的本质就是计数器。
我们如果想要计时的话,只要有一个恒定频率的方波信号和一个寄存器,每当方波信号上的上升沿到达?,寄存器的数据就加1,也就可以实现计时。
假如方波频率为100HZ,那么当寄存器计数到达了100时,也就过去了1秒钟。我们之前提到过,APB总线上的时钟线连接到了定时器上,也就提供了这个方波信号。
那么我们假设方波信号的频率是常见的72Mhz,而寄存器的数据只有16bit,那么我们能计时的时间将很有限。
所以,计数器前面,STM32添加了一个预分频器,它通过计数来分频,其本质也是一个计数器。当设置预分频器为0时,预分频器便不分频,直接以72Mhz传递给计数器。以此类推,预分频为1时,便是2分频,每两个脉冲分频成一个脉冲,预分频器的输出为36MHZ。
预分频器也是16bit,因此我们最多可进行65536分频,这么算下来,定时器的定时时间就足够单片机使用了。
如果我们要实现长时间定时,可以将两个定时器串联,那样可以计时更多时间。只是累计误差可能会很高。
言归正传,我们完成了计时,接下来便是在此基础上完成定时。
STM32引入了自动重装载寄存器,当计数器的值与自动重装载寄存器的值相同时,便触发一次定时器更新中断,这时,我们便可以通过中断回调函数来发送数据了。与预分频器类似,我们要定时m个脉冲,自动重装载寄存器的值就要设置为m-1。
接下来我们看一看cubeIDE/cubeMX的配置部分。这里只展示定时器部分。
我们配置APB1与APB2定时器均为72Mhz
打开TIM4,勾选内部时钟
进入下面的配置,
Prescaler也就是我们所说的预分频器,这里设置为7199,也就是进行了7200分频。
假设我们要定时1秒,就设置自动重装载寄存器(Counter Period)为10000-1,最终也就是72000000/7200/10000=1s
用ide或keil打开为我们配置好的工程,我们便可以看到为我们调用的MX_TIM4_Init函数,按我们的要求为我们配置了初始化设置
之后我们便可调用如下语句来开启我们的定时器4。
我们在之后还可以调用下面这些函数来改变预分频器,计数器,自动重装载寄存器的值,大家可自行尝试。
为了让我们随时可以修改预分频器与自动重装载寄存器的值,STM32引入了影子寄存器,只有经过一个定时周期后,影子寄存器才会与预分频器与自动重装载寄存器的值同步。从而达到不影响当前定时器的作用。
我们可以自行选择开启影子寄存器。
我们到这里,能实现计时功能,定时来完成一些事情,我们还要使用定时器的更新中断。
首先打开定时器的全局中断功能,保存并生成代码。
接着我们调用如下函数就可以开启TIM4定时器在每次达到自动重装载值时触发更新中断了。
接下来重写中断回调函数,
我们就可以定时完成任务了。