硬件定时器基础:通用定时器、PWM定时器、看门狗定时器的区别

各位同学,咱们今天聊聊硬件定时器。这东西在嵌入式系统里,就像人的心跳一样重要。我做了这么多年RTOS内核,可以说,搞不懂定时器,你就别想玩转实时系统。

很多初学者容易把三种定时器搞混。通用定时器、PWM定时器、看门狗定时器,名字听着像亲戚,但脾气秉性完全不同。咱们一个一个说清楚。

通用定时器:最基础的计时工具

通用定时器,说白了就是个计数器。给它一个时钟源,它就开始数数。数到预设值,就产生中断或者翻转电平。

我个人习惯把通用定时器分成两类:

  • 基本定时器:只能计时,没有外部引脚
  • 通用定时器:带捕获/比较通道,可以测量脉宽、产生PWM

我在项目中遇到过最典型的用法,就是用通用定时器做系统滴答时钟。RTOS的心跳,就是靠它来维持的。

核心要点:通用定时器的灵魂在于「可编程」。你可以设置预分频系数、自动重装载值、计数模式(向上/向下/中央对齐)。

举个例子,STM32的TIM2,配置成1ms中断一次:

// 假设时钟频率72MHz,预分频72-1,自动重装载1000-1
// 这样计数器每1us加1,1000次就是1ms
TIM_TimeBaseInitTypeDef tim;
tim.TIM_Prescaler = 72 - 1;      // 72分频,得到1MHz
tim.TIM_Period = 1000 - 1;       // 1000个脉冲,1ms
tim.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &tim);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);

嗯,这里要注意:预分频器和自动重装载寄存器的值,都要减1。因为计数器是从0开始数的。这个坑我踩过,调试了一下午才发现。

PWM定时器:专门输出方波的家伙

PWM定时器,其实是通用定时器的一个「特化版本」。它把比较器、输出控制逻辑做得更强大。

你想想看,通用定时器也能输出PWM,但PWM定时器专门优化了:

  • 多路独立输出,相位可调
  • 死区插入,防止上下桥臂直通
  • 刹车功能,紧急情况下强制关断

我记得有一次做电机驱动,客户要求PWM频率20kHz,占空比精度0.1%。普通定时器根本做不到,必须用高级PWM定时器。它的计数器是16位甚至32位的,配合高精度时钟源,才能满足要求。

个人经验:PWM定时器的死区时间设置很关键。我曾经因为死区设得太短,导致MOS管烧了三个。后来学乖了,死区时间至少留1-2个时钟周期余量。

看一个高级PWM定时器的配置片段:

// 以STM32高级定时器TIM1为例,输出互补PWM带死区
TIM_OCInitTypeDef oc;
TIM_BDTRInitTypeDef bdtr;

// 配置输出通道1
oc.TIM_OCMode = TIM_OCMode_PWM1;
oc.TIM_Pulse = 500;  // 50%占空比
oc.TIM_OutputState = TIM_OutputState_Enable;
oc.TIM_OutputNState = TIM_OutputNState_Enable;  // 互补输出
TIM_OC1Init(TIM1, &oc);

// 死区配置
bdtr.TIM_DeadTime = 72;  // 1us死区(72MHz时钟)
TIM_BDTRConfig(TIM1, &bdtr);

为什么需要死区?因为功率管从导通到关断需要时间。如果上下管同时导通,瞬间短路,电流巨大。嗯,这就是硬件工程师常说的「直通」问题。

看门狗定时器:系统的最后一道防线

看门狗定时器,这玩意儿跟前面两个完全不同。它的目的不是计时,而是「保命」。

工作原理很简单:启动后,它就开始倒计时。如果倒计时结束前你没有「喂狗」(重置计数器),它就认为系统跑飞了,强制复位整个芯片。

我曾经在一个工业控制项目里,因为看门狗配置不当,导致设备频繁复位。排查了三天,最后发现是喂狗的位置不对——我在中断里喂狗,但主循环卡死了,中断还能进,看门狗永远不超时。这其实掩盖了问题。

避坑指南:我曾经见过有人把喂狗放在定时器中断里。结果主程序死锁了,中断还在跑,看门狗永远不触发。正确的做法是:喂狗必须放在主循环的关键路径上,并且要检查各个任务的运行状态。

看门狗有两种常见类型:

类型 特点 典型应用
独立看门狗(IWDG) 使用内部低速时钟,不受系统时钟影响 对可靠性要求极高的场合
窗口看门狗(WWDG) 必须在特定时间窗口内喂狗 防止喂狗代码被异常频繁调用

窗口看门狗很有意思。它要求你在一个时间窗口内喂狗——不能太早,也不能太晚。太早说明程序执行太快,可能跳过了某些关键步骤;太晚说明程序卡顿了。这种设计比普通看门狗更安全。

三种定时器的核心区别

咱们用一张表总结一下:

特性 通用定时器 PWM定时器 看门狗定时器
主要用途 计时、计数、测量 产生精确方波 系统监控、故障恢复
输出能力 单路/多路,简单波形 多路互补,带死区 无输出,只产生复位
时钟源 系统时钟/外部时钟 系统时钟/外部时钟 独立低速时钟
中断类型 更新、捕获、比较 更新、比较、刹车 提前唤醒、复位
典型应用 RTOS心跳、延时、频率测量 电机控制、LED调光、开关电源 工业控制、汽车电子、医疗设备

说白了,通用定时器是「全能选手」,什么都能干但不够专精。PWM定时器是「专项运动员」,专门伺候电机和电源。看门狗定时器是「保安队长」,平时不干活,出事就重启。

实际选型建议

做项目时怎么选?我一般这么判断:

  • 如果只是做延时、计数、测量频率,用通用定时器就够了
  • 如果要驱动电机、控制LED亮度、做DAC,必须用PWM定时器
  • 任何产品级项目,必须开看门狗。这是底线

嗯,这里有个小技巧:很多芯片的通用定时器和PWM定时器是复用的。比如STM32的TIM2,既可以做通用定时器,也可以输出PWM。但高级PWM功能(死区、刹车)只有TIM1和TIM8才有。选型时一定要看数据手册的「定时器特性表」。

我记得有一次,一个同事选型时没注意,用了普通定时器做电机控制。结果死区时间调不出来,上下桥臂直通,板子冒烟了。从那以后,我每次画原理图前,都会把定时器的功能列表打印出来贴在墙上。

最后说一句:看门狗不是万能的。它只能检测到「程序跑飞」这种严重故障。对于逻辑错误、数据错误,看门狗无能为力。所以,别以为开了看门狗就万事大吉,该做的异常处理、数据校验,一样都不能少。