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的定时器时钟树是这样的:
分频系数配置错误,通常表现为两种情况:
- 频率偏差大——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桥驱动、死区时间控制。
我画了个对比图,方便你理解:
选错模式会怎样?我遇到过这样的情况:用中心对齐模式做电机控制,结果电机噪音特别大。后来发现,中心对齐模式下PWM频率减半,超出了电机的响应范围。换成边沿对齐后,问题就解决了。
特别注意:中心对齐模式下,中断标志位的行为和边沿对齐不同。边沿对齐只在计数器溢出时触发中断,而中心对齐在向上计数和向下计数时都会触发。如果你在中断里修改CCR,可能会造成更新冲突。
3.5 综合排查流程
说了这么多,我总结一个排查顺序,你遇到PWM输出问题时可以照着来:
- 查GPIO配置——确认是推挽输出,速度够快,复用功能选择正确
- 查时钟树——确认定时器时钟源已使能,分频系数算对了
- 查ARR和CCR——确认ARR不为0,CCR在0~ARR之间
- 查PWM模式——确认是边沿对齐还是中心对齐,是否符合预期
- 查输出使能——确认定时器的PWM输出通道已使能,GPIO的复用功能已打开
这个顺序是我自己多年调试总结出来的。从最外层的GPIO开始,逐步往定时器内部排查,效率最高。你想想看,如果GPIO模式都没设对,后面查定时器配置就是白费功夫。
一个小技巧:调试时先用示波器看GPIO引脚有没有波形。如果没有,大概率是GPIO或时钟问题。如果有波形但频率不对,那就是ARR或PSC算错了。波形有但占空比不对,查CCR。这个方法能帮你快速定位问题范围。