目录
绪言
定时器可以说是32中非常重要的一个外设了,之前虽然知道怎么去配置和使用它,但是其中的原理却是一知半解。通过最近的学习,才慢慢摸索到其中的奥秘。这篇文章主要聊一聊定时器的工作原理和定时器中断,只是最最基础的东西,关于定时器的输入输出,会在接下来的文章中更新。
一、定时器整体工作流程梳理
在最开始,先来看一下ST官方手册给出的框图
这里只是截取了本次内容需要关注的东西,有兴趣的读者可以自行去查看官方手册。
可以看到,其最基本的工作原理还是比较简单的,就是一个时钟源的选择,然后用选择的时钟源作为一个计数器的时钟。CNT计数器按照自动重装载寄存器里面的值向上或者向下计数。当计数达到阈值时,可以选择产生中断与否,然后将自动重装载寄存器的值更新到CNT计数器重新计数。如此循环往复,就是定时器的工作原理。
二、寄存器剖析
上面已经说了定时器的基本工作原理,那它是怎么知道时钟源的选择以及该向上还是向下计数呢?这些问题都是通过配置相应的寄存器去控制定时器的。接下来就来剖析剖析定时器相关的寄存器。
1·CR1、ARR、PSC寄存器
基本上很多外设都会有一个CR寄存器(控制寄存器),各个外设的这个寄存器的大致作用也都差不多,都是对外设的一些初始化参数进行配置。
对于只是让定时器“跑起来”,我们只需要关注这个寄存器的以下位:
1)ARPE位:作用是使能预装载寄存器缓冲(会在后面介绍)
2)CMS位、DIR位:这两位组合起来用于配置定时器计数方式
3)CEN:定时器使能位
ARR寄存器就是上面整体框图中的自动重装载寄存器,一个16位的用于储存计数数值的寄存器。
有一个需要注意的点是计数周期是(ARR[15:0]+1)个时钟周期,这个应该不难理解。例如:ARR中的值是10,向上计数模式中,从0开始计数到10实际上是用了计数11次的时间。因为从上次10溢出到下一次0开始中间还有一个时钟周期。
PS:第一次开始计数时,使能计数器之后,会隔一个时钟周期,计数器才会开始工作。时序图如下:
这里我们只需要关注CK_PSC、CNT_EN和CK_CNT几个参数。CK_PSC就是定时器时钟源,CK_CNT是计数器时钟,CNT_EN是计数器使能位。可以看出,在CNT_EN置1后,隔了一个时钟周期,CK_CNT才开始工作。
PSC寄存器又叫预分频寄存器,是一个16位的寄存器,可实现时钟分频。并且自带缓冲器,故可以在定时器工作时读写。分频因子的计算公式为:
PSC[15:0]+1
可能很多人和我一样刚开始不能理解为什么要加1,我是这样理解的,当PSC复位时,也就是不分频时,就相当于CLK/1;但是这个寄存器的值是0,时钟是不可能去除0的。所以用(PSC[15:0]+1)作为分频因子。
可以得出定时器溢出时间的计算公式:Tout= ((arr+1)*(psc+1))/Tclk。
2·DIER、SR、CNT寄存器
这三个寄存器没有太多值得说的地方,这里就只做简单介绍。
DIER:UIE位:允许更新中断使能
SR:状态寄存器,用于记录各种标志位
CNT:记录计数器中的值
这些寄存器可总结为下图:
定时器计数的内部了解了,再来说一说时钟源的问题,时钟是每个外设工作必不可少的东西。定时器的时钟来源有很多,作为初学者我们只需要了解最简单的内部时钟来源。(CK_INT)
下图是CubeMX配置的时钟树:
图中绿色方框框选的地方是APB1的分频因子,这里的内部时钟CK_INT时钟是从 APB1 倍频的来的,除非 APB1 的时钟分频数设置为 1,否则通用定时器 TIMx 的时钟是 APB1 时钟的 2 倍,当 APB1 的时钟不分频的时候,通用定时器 TIMx 的时钟就等于APB1的时钟。
这里结合我们最开始的整体框图看,可能更便于理解。
通过APB1总线时钟得到内部时钟CK_INT之后,再由PSC分频得到计数器时钟。所以整个定时器的时钟树可以理解为下图:
最后采用抽象艺术给大家总结一下定时器计数的工作原理:
其中U代表用户配置的东西,这里以向下计数为例。可能存在一定问题,只是为了方便理解。下面着重介绍一下影子寄存器和前面说的ARR自动重装载缓冲。
影子寄存器:真正起作用的寄存器,用户无法操作。也就是说真正工作的其实是它,ARR只是将用户和它联系起来的媒介。
自动重装载缓冲:当ARPE置1时,用户写入ARR的不会立马更新,而是会在更新事件到来的时候,从ARR寄存器转移到影子寄存器,再由影子寄存器更新到CNT计数器中。如果ARPE=0,用户写入ARR之后,就会立即传送到影子寄存器。
这里如果大家有不理解的可以去看ST官方的手册,里面有非常详细的讲解。
三、CubeMX配置定时器
Mode栏的第一部分只需要关注时钟源,其他的暂时不需要关注。这里选择内部时钟。
第二部分的东西可以看出就是对前面说的寄存器的配置。可以配置分频系数(PSC)、计数模式、自动重装载的值(ARR),其中CKD不用管,是输入捕获才用到的东西,auto-reload preload是自动重装载,应配置为使能。TRGO这里不用管。
同时还可以在NVIC Setting一栏中选择中断开启与否。