定时器Timer详解计数、延时、PWM输出和输入捕获一次讲清一、本文适用场景定时器 Timer 是单片机中非常核心的基础外设。无论是 STM32、GD32、51 单片机还是其他 MCU只要涉及时间控制、周期任务、PWM 输出、测频率、测脉宽基本都会用到定时器。很多初学者刚开始学习 Timer 时通常只把它理解成“延时工具”。但实际上Timer 的作用远不止延时。定时器常见应用包括精确定时周期中断LED 周期闪烁按键消抖系统心跳任务调度PWM 输出LED 调光风扇调速电机控制舵机控制输入捕获测频率测周期测脉宽外部脉冲计数风扇测速。本文将从 Timer 的基本概念开始详细介绍什么是定时器PSC、CNT、ARR 分别是什么定时器为什么能实现延时定时器中断是怎么产生的PWM 频率和占空比怎么计算CCR 在 PWM 中的作用输入捕获如何测频率、周期和脉宽定时器常见应用Timer 不工作、PWM 没波形、输入捕获不准时如何排查。二、什么是定时器TimerTimer中文通常称为定时器从本质上看定时器就是 MCU 内部的一个硬件计数器。它可以按照固定节拍递增或递减计数。这个节拍可以来自内部时钟也可以来自外部脉冲当计数值达到预设值时Timer 可以产生一个事件比如更新事件 中断事件 PWM翻转事件 输入捕获事件 输出比较事件可以简单理解为Timer 按固定节拍数数的硬件模块它的核心能力是数时间 数脉冲 产生周期事件 输出周期波形 记录外部边沿到来的时间所以定时器不是单纯用来 delay 的而是整个嵌入式系统里非常重要的“时间控制中心”。三、定时器能做什么定时器常见功能包括功能说明典型应用基本计数对内部时钟或外部脉冲计数时间基准、外部计数定时延时计数到设定值后产生事件1ms、10ms、1s 定时定时中断周期性进入中断服务函数系统心跳、周期任务PWM输出输出固定频率、可调占空比波形LED调光、风扇调速、电机控制输出比较CNT 与 CCR 比较后触发动作精准翻转、定时输出输入捕获捕获外部信号边沿时的 CNT 值测频率、周期、脉宽外部计数对外部脉冲进行计数编码器、风扇测速、脉冲计数学习 Timer 时建议先掌握三个基础概念PSC预分频器 CNT计数器 ARR自动重装载寄存器后面无论是定时、PWM还是输入捕获本质都离不开这几个概念。图1 定时器 Timer 基础与作用Timer 本质上是单片机内部的硬件计数器可以用于计数、定时、PWM 输出、输入捕获、外部计数和中断触发等场景。四、定时器的基本组成一个基础定时器通常可以简化理解为下面几个部分定时器时钟 ↓ 预分频器 PSC ↓ 计数器 CNT ↓ 自动重装载寄存器 ARR ↓ 更新事件 / 中断下面分别解释。五、定时器时钟是什么定时器需要一个时钟作为计数节拍。这个时钟可以来自 MCU 内部总线时钟。例如在 STM32 中定时器时钟可能来自APB1 APB2不同定时器挂载在不同总线上。需要注意的是某些 STM32 系列中如果 APB 预分频不为 1定时器时钟可能会变成 APB 时钟的 2 倍。所以在计算定时时间前必须先确认当前定时器真正的输入时钟是多少如果这个时钟搞错后面的 PSC、ARR 再怎么算都会不准。六、PSC预分频器是什么PSC 的全称可以理解为Prescaler中文叫预分频器它的作用是把定时器输入时钟分频降低计数速度。例如定时器输入时钟是72MHz如果 PSC 设置为71实际分频系数为PSC 1 72那么计数器 CNT 得到的计数频率为72MHz / 72 1MHz也就是说CNT 每 1 微秒加 1。这里要注意实际分频值 PSC 1不是 PSC 本身。这是初学者很容易搞错的地方。七、CNT计数器是什么CNT 是当前计数值。定时器工作时CNT 会按照定时器计数频率递增或递减。常见向上计数方式是0 → 1 → 2 → 3 → ... → ARR当 CNT 计数到 ARR 后会产生更新事件然后 CNT 重新从 0 开始计数。所以 CNT 可以理解为Timer当前已经数到哪里了在调试定时器时如果能看到 CNT 正在变化通常说明定时器时钟已经工作 定时器已经启动 计数器正在运行如果 CNT 一直不变就要检查定时器时钟是否开启定时器是否启动计数模式是否正确外部时钟模式是否配置错误是否被调试器暂停。八、ARR自动重装载寄存器是什么ARR 的全称可以理解为Auto Reload Register中文叫自动重装载寄存器它决定计数器的上限。在向上计数模式中CNT 从 0 开始计数 CNT 数到 ARR 产生更新事件 CNT 清零重新开始所以 ARR 决定一个定时周期内需要计多少个数。注意实际计数个数 ARR 1因为 CNT 是从 0 开始数的。例如 ARR 999则 CNT 会数0 ~ 999一共是1000 个计数九、定时器为什么能实现延时定时器实现延时的原理非常简单固定频率计数 ↓ 数到设定值 ↓ 产生事件 ↓ 说明经过了一段固定时间假设定时器计数频率为1MHz也就是CNT 每 1 微秒加 1如果 ARR 999那么 CNT 从 0 数到 999一共 1000 个计数。耗时为1000 × 1us 1000us 1ms所以每次更新事件就表示经过了 1ms。十、定时周期计算公式定时器定时周期常用公式为定时周期 (PSC 1) × (ARR 1) ÷ 定时器时钟也可以写成Tout (PSC 1) × (ARR 1) / Ftimer其中PSC预分频器值 ARR自动重装载值 Ftimer定时器输入时钟频率对应的更新频率为更新频率 定时器时钟 ÷ [(PSC 1) × (ARR 1)]十一、1ms定时示例假设定时器时钟为72MHz想得到1ms可以设置PSC 71 ARR 999计算过程PSC 1 72 ARR 1 1000定时周期(71 1) × (999 1) ÷ 72,000,000 72 × 1000 ÷ 72,000,000 0.001s 1ms所以每 1ms 会产生一次更新事件。十二、1s定时示例假设定时器时钟为1MHz想得到1s可以设置PSC 999 ARR 999计算过程PSC 1 1000 ARR 1 1000定时周期1000 × 1000 ÷ 1,000,000 1s所以每 1s 产生一次更新事件。十三、定时器中断是怎么产生的当 CNT 计数到 ARR 后会产生更新事件。如果同时打开了定时器更新中断那么 CPU 就会进入定时器中断服务函数。完整流程为定时器时钟输入 ↓ PSC分频 ↓ CNT开始计数 ↓ CNT计数到ARR ↓ 产生更新事件 ↓ 更新中断标志置位 ↓ NVIC响应中断 ↓ CPU进入定时器ISR ↓ 清除中断标志 ↓ 执行定时任务定时器中断常用于系统心跳定时扫描软件计时任务调度按键消抖超时检测。图2 定时器计数与定时延时详解PSC 用于分频CNT 负责计数ARR 决定计数上限。CNT 从 0 数到 ARR 后产生更新事件从而实现固定周期定时。十四、PWM是什么PWM 的英文全称是Pulse Width Modulation中文叫脉冲宽度调制PWM 本质上是一种周期性的高低电平波形。它通过调节高电平持续时间占整个周期的比例来控制输出信号的平均电压或平均功率。PWM 有两个核心参数频率 占空比十五、PWM频率是什么PWM 频率表示1秒内PWM周期重复多少次单位是Hz例如1kHz表示每秒有 1000 个 PWM 周期。PWM 频率由定时器的计数周期决定。常用公式为PWM频率 定时器时钟 ÷ [(PSC 1) × (ARR 1)]可以看到PWM 频率和定时器更新频率本质上是一样的。十六、PWM占空比是什么占空比表示高电平时间占整个周期的比例公式为占空比 高电平时间 ÷ 周期 × 100%在定时器 PWM 中高电平时间通常由 CCR 决定。CCR 可以理解为比较寄存器在常见 PWM 模式中CNT 从 0 开始计数当 CNT 小于 CCR 时输出一种电平当 CNT 大于或等于 CCR 时输出另一种电平。常见占空比计算公式为占空比 CCR ÷ (ARR 1) × 100%例如ARR 999 CCR 500占空比约为500 ÷ 1000 × 100% 50%十七、PWM中的ARR和CCR分别控制什么可以这样理解ARR 决定 PWM 的周期 CCR 决定 PWM 的高电平持续时间也就是说ARR 影响频率 CCR 影响占空比例如ARR 增大 → 周期变长 → PWM频率降低 ARR 减小 → 周期变短 → PWM频率升高 CCR 增大 → 高电平时间变长 → 占空比增大 CCR 减小 → 高电平时间变短 → 占空比减小所以调 PWM 时必须区分改频率主要改 PSC / ARR 改占空比主要改 CCR十八、PWM占空比示例假设ARR 999那么一个周期有1000 个计数如果CCR 250占空比为250 / 1000 25%如果CCR 500占空比为500 / 1000 50%如果CCR 750占空比为750 / 1000 75%占空比越大高电平持续时间越长。对于多数低通或平均功率型负载来说占空比越大平均电压或平均功率越大。十九、PWM常见应用PWM 常见应用包括1. LED调光通过改变占空比改变 LED 的平均亮度。占空比小 → LED暗 占空比大 → LED亮2. 风扇调速改变 PWM 占空比可以改变风扇的平均驱动功率从而调节转速。3. 电机控制PWM 常用于直流电机调速。实际项目中通常配合MOSFETH桥电机驱动芯片电流采样速度反馈。4. 蜂鸣器通过改变 PWM 频率可以改变蜂鸣器音调。通过改变占空比可以影响声音效果。5. 舵机控制舵机通常根据固定周期内的高电平脉宽判断角度。例如常见舵机可能使用20ms周期 0.5ms ~ 2.5ms高电平脉宽不同舵机参数可能不同应以实际产品手册为准。图3 PWM 输出原理与应用详解PWM 通过频率和占空比描述波形。ARR 决定周期和频率CCR 决定高电平时间和占空比。PWM 常用于 LED 调光、风扇调速、电机控制和舵机控制。二十、输入捕获是什么输入捕获是定时器的一种重要功能。它可以在外部输入信号出现指定边沿时把当前 CNT 的值自动保存到 CCR 捕获寄存器中。可以简单理解为外部边沿到来的一瞬间 Timer立刻记录当前时间点输入捕获常用于测量周期频率高电平脉宽低电平脉宽占空比外部脉冲时间间隔风扇转速超声波回波时间PWM输入信号参数。二十一、输入捕获的基本流程输入捕获的基本流程如下外部信号接入定时器通道 ↓ 选择捕获边沿 ↓ 外部边沿到来 ↓ 定时器把当前CNT锁存到CCR ↓ 捕获标志置位 ↓ 可触发捕获中断 ↓ 软件读取CCR计算时间关键点是CCR中保存的是边沿到来那一刻的CNT值所以输入捕获本质上是让定时器“看见边沿并记下时间点”。二十二、输入捕获测频率如果要测一个周期信号的频率可以连续捕获两个上升沿。例如第1个上升沿捕获值 CCR1 第2个上升沿捕获值 CCR2两个捕获值的差为周期计数值 CCR2 - CCR1如果定时器计数频率为Ftimer那么周期为T 周期计数值 ÷ Ftimer频率为f Ftimer ÷ 周期计数值如果发生计数器溢出则需要考虑 ARR 溢出修正。二十三、输入捕获测脉宽如果要测高电平脉宽可以上升沿捕获作为起点 下降沿捕获作为终点假设上升沿捕获值 CCR_rise 下降沿捕获值 CCR_fall那么高电平计数值为CCR_fall - CCR_rise脉宽时间为高电平计数值 ÷ Ftimer例如定时器计数频率为1MHz也就是 1 个计数等于 1 微秒。如果上升沿和下降沿差值为1500那么高电平脉宽就是1500us 1.5ms这类测量常用于舵机信号测量PWM 输入占空比测量超声波回波时间脉冲宽度检测。二十四、输入捕获测风扇转速风扇通常会输出测速脉冲。假设风扇每转一圈输出 2 个脉冲。通过输入捕获测得脉冲频率后可以计算 RPM。如果测得脉冲频率为Fpulse每圈脉冲数为PPR则转速为RPM Fpulse × 60 ÷ PPR例如Fpulse 100Hz PPR 2则RPM 100 × 60 ÷ 2 3000 RPM实际项目中还要考虑滤波、抖动、低速测量、超时判断等问题。二十五、输入捕获注意事项输入捕获常见注意点包括1. 边沿选择要正确根据测量目的选择上升沿捕获 下降沿捕获 双边沿捕获如果边沿选错计算结果就会错误。2. 定时器计数频率要合适计数频率太低分辨率不够 测量精度差计数频率太高容易溢出 需要频繁处理3. 要考虑溢出如果两次捕获之间 CNT 发生了溢出就不能简单直接相减。需要根据溢出次数修正。例如真实计数差 溢出次数 × (ARR 1) 当前捕获值 - 上次捕获值4. 信号要滤波输入信号如果有毛刺可能导致误捕获。可以使用硬件滤波定时器输入滤波软件滤波外部整形电路。图4 输入捕获 Input Capture 详解输入捕获可以在外部信号边沿到来时锁存 CNT 值。连续两次捕获可以测周期和频率上升沿与下降沿捕获可以测高电平脉宽。二十六、输出比较是什么输出比较也是定时器常见功能。它的基本思想是CNT不断计数 当CNT等于CCR时 定时器产生比较事件根据配置不同比较事件可以触发输出翻转输出置位输出复位产生中断触发 DMA控制 PWM 波形。PWM 本质上也和比较功能密切相关。在 PWM 模式中定时器不断比较CNT 和 CCR然后根据比较结果决定输出高电平还是低电平。二十七、外部计数是什么除了使用内部时钟计数Timer 也可以对外部脉冲进行计数。这就是外部计数模式。例如外部每来一个脉冲 CNT加1外部计数常用于编码器脉冲计数流量计脉冲计数风扇转速脉冲统计外部事件计数频率较低的脉冲累计。外部计数和输入捕获的区别是外部计数关心来了多少个脉冲 输入捕获关心脉冲什么时候来二十八、Timer常见调试问题1. 定时器不计数可能原因包括定时器外设时钟没开启定时器没有启动计数模式配置错误PSC / ARR 设置不合理使用了外部时钟但外部没有脉冲调试模式下定时器被暂停定时器实例选错。排查时可以先查看CNT 是否在变化如果 CNT 不变说明 Timer 还没有真正跑起来。2. 定时时间不准可能原因包括定时器输入时钟算错APB 分频导致定时器时钟倍频没考虑PSC / ARR 公式使用错误忘记 PSC 和 ARR 实际都要加 1中断处理时间太长软件中重复修改计数器使用阻塞延时代替硬件定时。最常见错误是把公式写成PSC × ARR而不是(PSC 1) × (ARR 1)3. PWM没有波形可能原因包括GPIO 没配置成复用功能定时器通道没有映射到正确引脚PWM 通道没有使能定时器没有启动CCR 设置为 0CCR 大于 ARR 导致占空比异常ARR / PSC 设置错误高级定时器没有使能主输出 MOE输出极性配置错误示波器测错引脚。排查 PWM 时建议按顺序检查定时器是否启动 GPIO是否是AF复用 通道是否正确 ARR/PSC/CCR是否合理 通道输出是否使能 实际引脚是否有波形4. 输入捕获不准可能原因包括捕获边沿选错输入引脚复用错误信号没有真正到达引脚计数频率太低导致分辨率不足计数频率太高导致溢出频繁没有处理计数器溢出输入滤波设置不合理信号毛刺导致误捕获软件读取 CCR 顺序错误捕获中断处理太慢。排查输入捕获时建议先用示波器确认外部信号本身是否正常。二十九、Timer调试推荐顺序Timer 相关问题建议按下面顺序排查第1步确认定时器外设时钟是否开启 第2步确认定时器实例是否正确 第3步确认定时器是否启动 第4步查看CNT是否在变化 第5步确认PSC、ARR、CCR计算是否正确 第6步确认GPIO复用功能是否正确 第7步确认通道映射是否正确 第8步如果使用中断确认中断使能和NVIC配置 第9步确认中断标志是否正确清除 第10步如果使用PWM用示波器看输出波形 第11步如果使用输入捕获用示波器看输入信号 第12步最后再检查业务逻辑Timer 的调试核心是先看时钟和计数 再看寄存器配置 最后看引脚和波形图5 定时器调试与故障排查指南Timer 不工作、PWM 没输出、输入捕获不准时应从时钟、GPIO 复用、PSC/ARR/CCR、模式配置、中断/DMA 和实际波形逐层排查。三十、STM32 HAL定时器中断示例下面代码只作为理解思路不同芯片和库函数会有差异。1. 启动定时器中断HAL_TIM_Base_Start_IT(htim2);2. 定时器中断回调voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){if(htim-InstanceTIM2){/* 例如每1ms进入一次 */system_tick;}}通常建议中断中只做轻量处理例如计数或置标志。三十一、STM32 HAL PWM输出示例1. 启动PWMHAL_TIM_PWM_Start(htim3,TIM_CHANNEL_1);2. 修改占空比__HAL_TIM_SET_COMPARE(htim3,TIM_CHANNEL_1,500);如果ARR 999 CCR 500则占空比约为 50%。实际工程中可以封装函数voidpwm_set_duty(uint16_tduty){if(duty1000){duty1000;}__HAL_TIM_SET_COMPARE(htim3,TIM_CHANNEL_1,duty);}三十二、STM32 HAL输入捕获示例1. 启动输入捕获中断HAL_TIM_IC_Start_IT(htim4,TIM_CHANNEL_1);2. 捕获回调volatileuint32_tcapture10;volatileuint32_tcapture20;volatileuint8_tcapture_done0;voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim){if(htim-InstanceTIM4htim-ChannelHAL_TIM_ACTIVE_CHANNEL_1){if(capture_done0){capture1HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);capture_done1;}else{capture2HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);uint32_tdiff;if(capture2capture1){diffcapture2-capture1;}else{diff(htim-Instance-ARR-capture11)capture2;}/* diff就是两次捕获之间的计数差 */capture1capture2;}}}实际项目中还需要根据定时器计数频率计算周期和频率。三十三、Timer学习重点总结学习 Timer 可以先记住以下结论Timer 本质是硬件计数器。Timer 可以对内部时钟或外部脉冲计数。PSC 是预分频器。CNT 是当前计数值。ARR 是自动重装载值也就是计数上限。实际分频系数是 PSC 1。实际计数个数是 ARR 1。定时周期由定时器时钟、PSC 和 ARR 共同决定。定时周期 (PSC 1) × (ARR 1) ÷ 定时器时钟。CNT 数到 ARR 后会产生更新事件。打开更新中断后更新事件可以触发定时器中断。PWM 是周期性的高低电平波形。PWM 频率由 PSC 和 ARR 决定。PWM 占空比由 CCR 和 ARR 决定。占空比 CCR ÷ (ARR 1) × 100%。ARR 主要影响 PWM 周期和频率。CCR 主要影响 PWM 高电平时间和占空比。输入捕获可以记录外部边沿到来时的 CNT 值。两次上升沿捕获值相减可以测周期和频率。上升沿和下降沿捕获值相减可以测高电平脉宽。外部计数关心脉冲数量。输入捕获关心边沿到来的时间点。Timer 调试要先看时钟和 CNT 是否变化。PWM 没波形要检查 GPIO 复用、通道使能和 CCR。输入捕获不准要检查边沿、时钟、滤波和溢出处理。三十四、结语Timer 是单片机中非常重要的基础外设。它看起来只是“计数器”但实际能完成很多关键功能延时 周期中断 PWM输出 输入捕获 输出比较 外部计数 测频率 测脉宽 风扇测速 电机控制真正理解 Timer需要把下面这些概念串起来定时器时钟 PSC CNT ARR CCR 更新事件 中断 PWM 输入捕获可以用一句话总结Timer 的本质是计数 定时是数时间 PWM 是按计数比较输出波形 输入捕获是记录外部边沿到来的计数值。当你能理解 PSC、ARR、CNT、CCR 之间的关系时Timer 的大部分功能就已经入门了。