3. GPIO与定时器配置故障排查

这一章,我们聊聊PWM输出中最容易踩的坑——配置错误。说实话,我见过太多工程师拿着逻辑分析仪抓波形,折腾半天发现是GPIO模式没设对。这种问题其实不难,但一旦疏忽,排查起来特别费时间。

PWM输出说白了就两件事:定时器产生正确的脉宽信号,GPIO把这个信号送到外部。任何一个环节出错,输出就不对。咱们一个一个来看。

3.1 GPIO模式设置错误

GPIO模式这个坑,我当年刚入行时就栽过。那时候做一个电机驱动板,PWM输出死活没波形,查了两天才发现——我把引脚设成了开漏输出。

核心要点:PWM输出必须使用推挽输出(Push-Pull)模式。开漏输出只能输出低电平或高阻,无法主动输出高电平。

两种模式的差异,我整理了一张表:

特性 推挽输出 开漏输出
高电平驱动 主动输出VCC 需要外部上拉
低电平驱动 主动输出GND 主动输出GND
PWM适用性 ✅ 直接使用 ❌ 波形畸变
典型应用 普通数字信号输出 I2C、多路复用总线

为什么会这样?你想想看,开漏输出在高电平时引脚是浮空的,靠外部电阻慢慢拉上去。PWM频率稍微高点,上升沿就变成斜坡了,波形完全走样。

我的习惯:初始化PWM引脚时,我会同时检查三件事——模式设为推挽输出、速度设为高速(通常50MHz以上)、上下拉设为无。这三项缺一不可。

3.2 定时器时钟源选择与分频系数错误

定时器时钟源这个坑,说实话比GPIO模式隐蔽得多。我记得有一次帮同事排查问题,他配置的PWM频率怎么算都不对,最后发现定时器挂在了APB1上,但APB1的时钟分频系数没算进去。

大多数MCU的定时器时钟树是这样的:

定时器时钟源与分频链路 HCLK / 系统时钟 APB1 / APB2 总线 定时器预分频器 (PSC) 计数器 (CNT / ARR) 注意:APB1时钟通常等于HCLK/2(如72MHz→36MHz),定时器时钟可能自动倍频,需查阅芯片手册 PWM频率 = 定时器时钟 / (PSC + 1) / (ARR + 1)

分频系数配置错误,通常表现为两种情况:

  • 频率偏差大——PSC或ARR算错了,实际频率和目标差好几倍
  • 频率完全不对——定时器挂错了总线,或者时钟源根本没使能

我曾经踩过的坑:用STM32F103时,TIM2挂在APB1上,APB1默认是HCLK/2。但我忘了APB1预分频系数不为1时,定时器时钟会自动倍频到HCLK。结果算出来的PSC和ARR全错,输出频率差了一倍。后来我养成了习惯——每次配置前先读RCC寄存器,确认定时器实际时钟频率。

3.3 自动重装载值与比较值配置错误

ARR和CCR这两个寄存器,是PWM的核心。ARR决定周期,CCR决定占空比。配置错误的话,波形要么周期不对,要么占空比不对,甚至可能没有输出。

我整理了一个常见错误清单:

错误类型 现象 原因
ARR = 0 无PWM输出 计数器无法计数,直接溢出
CCR > ARR 占空比100% 比较值超过周期,输出一直为高
CCR = 0 占空比0% 比较值等于0,输出一直为低
ARR值太小 频率极高,波形失真 计数器溢出太快,输出不稳定

这里有个细节很多人会忽略——ARR和CCR的更新时机。默认情况下,这两个值是在计数器溢出时才生效的。如果你在运行中修改CCR,要等当前周期结束才会更新。

我建议:如果需要动态调整占空比,记得使能预装载寄存器(Preload)。这样CCR的修改会在下一个周期同步生效,避免出现半个周期异常波形。

3.4 PWM模式选择错误

PWM模式这个坑,说实话比较隐蔽。边沿对齐和中心对齐,输出波形差异很大,但很多人一开始没注意。

两种模式的区别:

  • 边沿对齐(Edge-aligned):计数器从0数到ARR,然后跳回0。PWM信号在每个周期开始处对齐。这是最常用的模式,适合普通电机控制、LED调光。
  • 中心对齐(Center-aligned):计数器从0数到ARR,再数回0。PWM信号在周期中心处对齐。这种模式产生的PWM对称性更好,适合H桥驱动、死区时间控制。

我画了个对比图,方便你理解:

边沿对齐 vs 中心对齐 PWM 波形对比 边沿对齐 计数器: 0→ARR→0 中心对齐 计数器: 0→ARR→0→ARR→0 中心对齐模式下,PWM频率是边沿对齐的一半(相同ARR时),但对称性更好

选错模式会怎样?我遇到过这样的情况:用中心对齐模式做电机控制,结果电机噪音特别大。后来发现,中心对齐模式下PWM频率减半,超出了电机的响应范围。换成边沿对齐后,问题就解决了。

特别注意:中心对齐模式下,中断标志位的行为和边沿对齐不同。边沿对齐只在计数器溢出时触发中断,而中心对齐在向上计数和向下计数时都会触发。如果你在中断里修改CCR,可能会造成更新冲突。

3.5 综合排查流程

说了这么多,我总结一个排查顺序,你遇到PWM输出问题时可以照着来:

  1. 查GPIO配置——确认是推挽输出,速度够快,复用功能选择正确
  2. 查时钟树——确认定时器时钟源已使能,分频系数算对了
  3. 查ARR和CCR——确认ARR不为0,CCR在0~ARR之间
  4. 查PWM模式——确认是边沿对齐还是中心对齐,是否符合预期
  5. 查输出使能——确认定时器的PWM输出通道已使能,GPIO的复用功能已打开

这个顺序是我自己多年调试总结出来的。从最外层的GPIO开始,逐步往定时器内部排查,效率最高。你想想看,如果GPIO模式都没设对,后面查定时器配置就是白费功夫。

一个小技巧:调试时先用示波器看GPIO引脚有没有波形。如果没有,大概率是GPIO或时钟问题。如果有波形但频率不对,那就是ARR或PSC算错了。波形有但占空比不对,查CCR。这个方法能帮你快速定位问题范围。