本节摘要:定时器是单片机世界里唯一定义的"时间刻度尺":把时钟节拍经预分频后逐拍计数,计到设定值就触发事件。本节讲透"预分频 + 计数 + 比较"这个所有定时器共通的骨架模型,展开定时中断、PWM 输出、输入捕获三大玩法,并用呼吸灯与舵机的算例把公式落成手感。定时器是前面时钟知识的最大买主,也是后面中断体系最常打交道的触发源。
软件延时的误差在 3.2 节已经领教过:中断一插、流水线一抖,毫秒级延时就会漂移。精确时间的唯一可靠来源是硬件计数:晶振每秒给出稳定的节拍,定时器像个一丝不苟的计数员,来一拍数一个数,数到设定值就报告。因为节拍源头是晶振,计数的每一"步"都精确可知——这就是为什么产品级代码里的定时任务、通信波特率、脉宽测量,全都落在定时器上。
市面定时器型号繁杂,但骨架高度一致,三个部件构成模型的核心:
**预分频器(PSC)**决定"多少个时钟拍算一步"。72MHz 的时钟配预分频 71,即 72 拍算一步,计数步频变成 1MHz——每步恰好 1 微秒。**计数器(CNT)**从 0 数到自动重装值(ARR)后归零重来(向上计数模式),像手表的秒针循环。比较器时刻盯着计数值,与捕获比较寄存器(CCR)相等时触发动作:可以触发中断、可以翻转引脚、可以把引脚拉高拉低。
三个寄存器联合决定一切时间参数,两个公式吃遍天下:
定时周期 = (ARR + 1) × (PSC + 1) / 定时器时钟 PWM 占空比 = CCR / (ARR + 1)
算例一:要 500ms 定时中断,时钟 72MHz。选 PSC = 7199(步频 10kHz,每步 0.1ms),则 ARR = 5000 - 1,周期恰为 5000 步即 500ms。算例二:要 1kHz PWM、占空比 25%:选 PSC = 0,ARR = 71(步频 72MHz,周期 72 拍即 1kHz);CCR = 18,占空比 18/72 = 25%。先定步频颗粒度、再定循环长度、最后算比较值——三步走,任何定时需求都能落进公式。
/* 定时器配置:1ms 中断节拍(72MHz 时钟) */ TIM2->PSC = 7200 - 1; /* 步频 10kHz */ TIM2->ARR = 10 - 1; /* 数 10 步 = 1ms */ TIM2->DIER = TIM_DIER_UIE; /* 允许更新中断 */ TIM2->CR1 = TIM_CR1_CEN; /* 启动计数 */ NVIC_EnableIRQ(TIM2_IRQn); /* 打开中断通道(第5章详述) */

玩法一:定时中断。 周期时间到触发中断,主循环外的一切"准点任务"都靠它:系统节拍(RTOS 的心跳)、按键扫描、显示刷新。它是第 5 章中断体系的第一大客户。
玩法二:PWM 输出。 比较器直接控制引脚电平:计数小于 CCR 输出高、越过则输出低,硬件全自动。PWM 是单片机控制功率世界的万能语——LED 调光(平均电流随占空比变化)、电机调速、舵机角度(脉宽 1 到 2ms 对应 0 到 180 度)、开关电源的调节量。改一个寄存器就连续改变输出功率,这行云流水的体验全部来自硬件自动化。
玩法三:输入捕获。 反过来用:引脚上的边沿到来时,硬件把当前计数值"拍快照"存进捕获寄存器。两次快照相减,就得到外部脉冲的宽度或周期——超声波测距模块的回波脉宽、红外遥控的编码脉冲、风扇转速信号,全靠捕获测量。它是"用时间刻度尺量外部世界"的那一半功能,与 PWM 的"用刻度尺给世界定形"正好互补。
定时器家族还有两员值得点名。独立看门狗本质是一个只能喂不能停的倒计时器,时钟来自独立低速振荡器,与主时钟树彻底隔离——主时钟崩了它照跑,这就是它能"监护主时钟"的资格来源,7.2 节细讲用法。**实时时钟(RTC)**是一个以 32.768kHz 晶振驱动的超低速计数器,走的是日历时间(秒、分、时、天),由备份电池域供电——整机断电它也在走。32.768 这个奇怪的数字是 2 的 15 次方,经过 15 级二分频恰好得到 1Hz,是手表行业传下来的遗产。定时器家族的分工图谱由此完整:SysTick 管毫秒节拍、通用定时器管微秒级精确控制、RTC 管日历、看门狗管保命——四个时间尺度、四种职责,各用各的。初学者最常见的混乱是把这四种定时器混为一谈,选错对象后怎么配都不对。
背景:让 LED 呈现呼吸般的渐亮渐暗。操作:选 PWM 频率 1kHz(高于人眼闪烁融合频率即可),ARR = 71、CCR 从 0 渐增到 71 再渐减,每 5ms 调整一档,一个呼吸周期约 0.72 秒。结果:LED 亮度肉眼可见地平滑起伏,无闪烁、无台阶感。解读:占空比改变的是 LED 平均电流,人眼对平均亮度响应平滑;PWM 频率足够高时人眼察觉不到开关过程。变式:若调光出现可闻啸叫,是 PWM 频率落进了听觉范围(LED 驱动电路的陶瓷电容在唱歌),把频率提到 20kHz 以上即可;若渐变有台阶感,是因为低占空比区段人眼对亮度变化更敏感,用指数曲线代替线性递增能显著改善——这两个变式是呼吸灯项目里最高频的两个返工点。
一颗 STM32 的定时器少则三四个、多则二十来个,分工有讲究:高级定时器带互补输出与死区插入,是驱动半桥电机与逆变的专业户;通用定时器具备本节全部功能,是日常主力;基本定时器只会定时,专供触发 ADC 或产生时基;** SysTick** 是内核自带的 24 位节拍器,操作系统心跳的标配;看门狗定时器则完全独立成章(第 7 章专讲)。选用原则:先看功能需求(要不要互补输出、要不要捕获),再排资源(高速任务占高级定时器,简单节拍用基本定时器),最后核对引脚映射——定时器通道与具体引脚的对应关系在数据手册的复用表里定死,选错通道要换引脚重配。
把捕获玩法落成一堂十分钟的小实验,材料只要一块板加一个信号源(另一块板输出的 PWM 即可)。第一步,选定时器与通道,把捕获配置成"上升沿捕获",先开捕获中断。第二步,记录相邻两次上升沿的计数值快照,相减得到周期计数值 N。第三步,换算频率:定时器计数时钟若为 1MHz(72MHz 经预分频 72 分频),则被测频率 = 1000000 / N。第四步,处理溢出:若被测频率低到计数器中途溢出(ARR 循环了一整圈),快照相减会得到负数或异常大值——给计数器溢出中断计数、把它加进差值即可,这是本实验真正的教学点:时间量测量永远要回答"跨了几个循环"。验证环节拿另一块板输出 1kHz PWM,实测读数在 999 到 1001Hz 之间跳动,抖动来自两块板晶振的百万分之几十偏差——顺手复习了 2.3 节的时钟精度。实验全程不占 CPU,主循环该干嘛干嘛,这正是硬件捕获相对软件查询的价值宣言。