功能简介
本文以 STM32G0 系列 TIM 外设为例进行说明。TIM(定时器)是一种常用的微控制器外设,其核心模块包括一个 16 位计数器 和相关的 自动重载寄存器(ARR)。
计数器可以实现 向上计数 、向下计数 ,或 上下交替计数 (中心对齐模式)。计数器的时钟可以通过 预分频器 进行分频,以调节计数速度。
TIM 的主要寄存器------计数器、自动重载寄存器和预分频寄存器------都可以被软件读写,即使计数器正在运行,也可以访问这些寄存器进行配置或读取。
相关寄存器
预分频寄存器(TIMx_PSC)
TIMx_PSC(Prescaler Register) 用于配置定时器预分频器的分频系数,分频范围为 1 ~ 65536。该寄存器带有 缓冲机制(Shadow Register / Prescaler buffer),写入的新值不会立即生效,而是在特定时机由硬件自动更新。
图片来源:STM32G系列参考手册标题
从 TIM 的功能框图 可以看到,预分频器的输入时钟 CK_PSC 经过预分频器分频后,生成 输出时钟 CK_CNT,该时钟用于驱动计数器。
CK_CNT 只有在 TIMx_CR1 寄存器中的 CEN 位被置 1 后才会启用,并且在 CEN 置位后的下一个时钟脉冲(1 个 CK_CNT 脉冲),计数器才开始计数。
下图示例演示了 预分频器(Prescaler)在线更新 的工作过程。
图片来源:STM32G系列参考手册题
-
CK_PSC 表示预分频器的输入时钟。初始时,预分频器的值为 0,表示 不分频。当 CEN 位被置 1 后,经过 一个CK_CNT时钟脉冲,预分频器的输出时钟开始工作,其频率与输入时钟一致,计数器随之开始计数。
-
当计数器计数到 0xF8 时,我们向 TIMx_PSC 寄存器 写入一个新值 1(表示 2 分频)。此时,由于预分频器具有 缓冲(Prescaler buffer)机制,当前正在工作的分频值仍然保持为 0,输出时钟频率不会立即发生变化。
-
当计数器继续计数并到达 0xFC(即 ARR 的值) 时,产生一次 上溢事件(Overflow Event) ,同时触发 更新事件(Update Event)。在该更新事件中,TIMx_PSC 中的新值被加载到 Prescaler buffer。
-
从这一刻开始,预分频器的输出时钟频率发生改变: 每 2 个输入时钟脉冲,产生 1 个输出时钟脉冲。计数器随后基于新的时钟频率继续计数。
自动重载寄存器(TIMx_ARR)
自动重载寄存器(TIMx_ARR)也带有一个影子寄存器。 根据 TIMx_CR1 寄存器中的 ARPE 位(Auto-reload Preload Enable) 设置,预装载寄存器(preload register)的内容会 永久性或在每次更新事件(UEV, Update Event)时 被传送到影子寄存器中。
下图示例演示了 自动重载值(Auto-reload value)在线更新 的工作过程。
标题图片来源:STM32G系列参考手册题
前面提到,自动重载寄存器(TIMx_ARR) 具有 影子寄存器(Auto-reload shadow register) 机制。 当 ARPE 位(Auto-reload preload enable) 置位时,写入 TIMx_ARR 的新值并不会立即生效,而是会在 更新事件(Update Event) 发生时,被加载到影子寄存器中。
在该示例中:
-
当计数器计数到 0xF1 时,我们将 TIMx_ARR 的值从 0xF5 更新为 0x36;
-
此时,由于启用了 ARR 预装载(ARPE = 1),影子寄存器中的 ARR 值仍然保持为 0xF5,当前计数周期不受影响;
-
计数器继续按照旧的 ARR 值运行,并在计数到 0xF5 时产生一次 上溢事件(Overflow Event),同时触发 更新事件(Update Event);
-
在该更新事件中,TIMx_ARR 中的新值(0x36)被加载到影子寄存器; 从下一轮计数开始,计数器将以 0x36 作为新的自动重载值,并在计数到 0x36 时才再次产生溢出事件。
计数寄存器 (TIMx_CNT)
计数器记录当前的计数值,由预分频器输出时钟(CK_CNT)驱动。在 向上计数模式 下,当计数器计数到 ARR 值时,下一次计数会回到 0,并产生一次 上溢事件(Overflow Event) 和 更新事件(Update Event) ,同时将 更新中断标志(UIF) 置位。
重复计数器(TIMx_RCR)
重复计数器用于控制 更新事件(Update Event) 的触发频率。
-
当 RCR 值为 0 时,每次上溢或下溢事件都会触发一次更新事件。
-
当 RCR 值非 0 时,计数器需要重复达到上溢/下溢事件指定次数(RCR + 1)后,才会触发一次更新事件。
三种计数模式
向上计数模式
计数器从 0 开始递增计数,当计数到 自动重载值(TIMx_ARR 寄存器) 时,下一次计数回到 0,并产生一次上溢事件(Overflow Event)和更新事件(Update Event) 。更新事件可以通过TIMx_CR1寄存器的UDIS位禁用。
下图展示了一个示例:ARR = 0x36,预分频器值为 0 的向上计数时序图。
图片来源:STM32G系列参考手册题标题
- 当计数值到达 ARR 时,会产生 上溢事件(Overflow Event) 和 更新事件(Update Event)。
向下计数模式
计数器从 自动重载值(TIMx_ARR) 开始递减计数,当计数到 0 时,下一次计数重新加载为 自动重载值,并产生一次下溢事件(Underflow Event)。
下图展示了一个示例:ARR = 0x36,向下计数时序。
标图片来源:STM32G系列参考手册题题
- 当计数值到达 ARR 时,会产生 下溢事件(Underflow Event) 和 更新事件(Update Event) 。
上下交替计数模式
该模式也称为 中心对齐模式(Center-aligned mode)。
在上下交替计数模式下,计数器按照以下顺序工作:
- 从 0 递增计数到 自动重载值(TIMx_ARR) − 1,产生一次上溢事件;
- 然后从 自动重载值(TIMx_ARR) 递减计数到 1,产生一次下溢事件;
- 最后返回到 0,并重复上述过程。
下图展示了一个示例:ARR = 0x6的上下交替计数时序。
图片来源:STM32G系列参考手册题标题
- 当计数值到达 ARR - 1 时,会产生 上溢事件(Overflow Event) 和 更新事件(Update Event)
- 当计数值到达 1 时,会产生 下溢事件(Underflow Event) 和 更新事件(Update Event)