目录

1.定时器简介
https://www.bilibili.com/video/BV11X4y1j7si?t=79.1&p=40

上图为单片机内部结构框图。
STM32F1 系列 MCU 最多有 14 个定时器(最小系统版有四个,为上图中的 1 个高级定时器,3 个通用定时器)。定时器也是个片上外设。

RM0008 数据手册中,可看到定时器分三类:高级,通用 (高级定时器阉割版),基本(通用定时器阉割版)。
定时器 1、8 为高级定时器
定时器 6、7 为基本定时器
其他的都是通用定时器(2-5,9-14)

上图为定时器内部结构框图。
比较复杂,可拆分成四个部分:时基单元、输出比较、输入捕获、从模式控制器。
2.时基单元的基本结构
https://www.bilibili.com/video/BV11X4y1j7si?t=301.2&p=40
看看时基单元是咋工作的

上图为时基单元部分。分为五小部分:时钟、预分频器 PSC、计数器 CNT、自动重装寄存器 ARR、重复计数器 RCR。
1、 时钟源:时钟来源。可来自于时钟树,or 从模式控制器(先不考虑这个)。
2、PSC:时钟频率较高大材小用了,所以分频。比如时钟源 10MHZ,预分频器可设置 9,获得频率为 10/(9+1)=1MHZ。
3、CNT:对分频后的时钟脉冲信号计数。来一个脉冲 CNT+1。
4、ARR:设置定时周期。图中绿色线为 ARR 线,CNT 到达 ARR 则溢出重新计数。CNT==ARR ,再来一个脉冲就溢出了,所以 CNT 的计数周期为 ARR+1。
5、RCR:设置重复计数次数。如果没有 RCR,CNT 到达 ARR+1 后就直接溢出了。如果有 RCR,CNT 需要溢出 1+RCR 后,右边才会产生一个 update 事件。
总结:https://www.bilibili.com/video/BV11X4y1j7si?t=598.4&p=40
讲的确实不错。

Q:这时基单元真的能实现定时吗?
A:上图石英手表的结构可和时基单元类比。石英手表拆开后内部有个32.768KHZ 的石英晶振。如果直接驱动秒针会太快,所以内部有电路用来降低时钟频率,相当于预分频器,这样就可以驱动秒针。
秒针(CNT)到达 60(ARR),则给一个脉冲(update 事件)让分针动一下,perfect。
3.上计数、下计数和中心对齐
https://www.bilibili.com/video/BV11X4y1j7si?t=782.7&p=40
这个是 CNT 的计数方向:上计数、下计数和中心对齐

上计数:从 0 开始计数,来一个脉冲就加一,直到 ARR
下计数:从 ARR 开始计数,来一个脉冲就减一,直到 0
中心对齐:从 0 到 ARR,然后从 ARR 到 0.
一般都用上计数,其他俩用得少
4. 时钟的来源
https://www.bilibili.com/video/BV11X4y1j7si?t=877.7&p=40
此为 时基单元的时钟来源。

以一个小题目展开,上图为题目要求。
分辨率 1us,周期 1ms 含义:比如手表秒针最小只能跳 1s 而不能 0.1s,所以分辨率是 1s。转一圈是 60s,所以周期是 60。
所以 CNT 递增一下(秒针)就是分辨率 1us,CNT 到 ARR+1 溢出(秒针转一圈),就是周期 1ms
那么如何获得 1us (1us==1MHZ)的时钟脉冲呢?
假设输入 10MHZ,PSC=9,可得 1MHZ
假设输入 20MHZ,PSC=19,可得 1MHZ
假设输入 200MHZ,PSC=199,可得 1MHZ
时基单元的时钟有两种来源:时钟树,从模式控制器(按下不表后面讲)。那么时钟树的时钟信号的频率是多少呢?

上图为时钟树。定时器位于上图上方紫色圈住部分(TIM1 挂载在 APB2 上,TIM2-4 挂载在 APB1 上)。可看到定时器有个独有的倍频器(可选 1 和 2 倍频)。
倍频系数为自动设定的:
(上电启动默认)APB2=1 分频,则 TIM_CLK=PCLK2=72MHZ
(上电启动默认)APB1=2 分频,则 TIM_CLK=PCLK1 * 2=36MHZ * 2 =72MHZ
所以 TIM3 位于 APB1,时钟为 72MHZ。

所以 TIM3 的时钟为 72MHZ(PCLK1 *2)。所以 CNT 如果要得到 1MHZ 的分辨率,PSC=71.
要得到周期 1ms,1ms=1000us,所以 CNT 要 1000 次就得有个 update 事件,所以 ARR=999,RCR=0。
5.寄存器预加载
https://www.bilibili.com/video/BV11X4y1j7si?t=1402.9&p=40

上图的 PSC、CNT、RCR 背后都有一个阴影,我们把这个灰色的阴影叫影子寄存器。身前的白色方块就叫活动寄存器。
我们给寄存器写值的时候,是写入到影子寄存器的,而且这个值不会立即生效,直到 CNT 溢出产生一个 update 事件的时候,影子寄存器的值才会进入到活动寄存器(为啥这样设计啥意思啊。。。)。这种缓存的机制,就叫做寄存器的预加载。

定时器的定时周期:ARR+1
预加载作用:如果不使用预加载,突然在上图位置处改变 ARR,则 CNT 会加载到 65535(CNT=5,一直大于直接改后的 ARR=3,会一直累加),再发生溢出,这种情况下定时器会跑飞的(搜得私噶!)。

加入了预加载,在改变 ARR 后的第一个 update 事件更新处,活动寄存器的值被影子寄存器的值覆盖,这样定时器就不会跑飞哩。
总结:
简单介绍了下定时器,讲了下定时器的时基单元部分的基本结构和工作原理,并讲述了有寄存器预加载的好处。定时器可分为四部分:时基单元、输出比较、输入捕获、从模式控制器。时基单元可分为五部分:时钟源、PSC、CNT、RCC、RCR。讲得不错,有点东西。