单片机定时器计算

定时器的时长由三样东西决定:输入时钟、预分频器和自动重载值。公式是 (PSC + 1) × (ARR + 1) ÷ fclk。

PSC 和 ARR 填寄存器里实际写的值(也就是分频系数和计数次数各自减一之后的结果),不是分频系数本身。

定时器配置的常见坑

PSC 和 ARR 都要减一。预分频寄存器写的是「分频系数减一」,自动重载寄存器写的是「计数次数减一」,因为两者都是从 0 开始数。设 PSC = 0 表示不分频,ARR = 0 表示每个时钟周期就溢出一次。忘了减一会让定时差一个计数,做精确计时或 PWM 频率时会直接体现出来。

定时越长分辨率越粗。计数器位宽固定(常见 16 位,即最多 65536 个计数),定时越长就必须用越大的预分频,于是每个计数变长、可调档位变少。想要 10 秒定时又要 1 μs 精度,在 16 位定时器上做不到,得换 32 位计数器、提高时钟,或者用主定时器级联从定时器。

重载值生效有延迟。在计数过程中直接改 ARR,新值通常要等到下一次溢出事件才真正生效,而且有些芯片会先产生一次更新中断。想立即生效要先关掉定时器、写寄存器、再重新使能,或者把更新事件标志清掉再启动,否则第一次定时可能短一截。

预分频有影子寄存器。预分频寄存器大多带影子寄存器(缓冲),写入的新值要等到下一次更新事件才装载。这意味着运行时改分频不会立刻改变节奏,做动态调速时要么等一个周期,要么手动触发更新事件,不然会出现意料之外的一拍。

中断频率别超过调度能力。中断本身有进出开销,几十个时钟周期起步。100 kHz 的中断在 72 MHz 主频上已经吃掉约 5% 到 10% 的 CPU,再叠加中断里的处理逻辑就很容易把主循环饿死。高频计数宁可让定时器硬件直接输出或触发 DMA,不要靠中断。