STM32实战:PWM精准调控直流电机转速

张开发
2026/5/7 20:41:46 15 分钟阅读

分享文章

STM32实战:PWM精准调控直流电机转速
1. 从玩具车到工业机械PWM如何成为电机控制的核心第一次接触PWM控制直流电机时我正尝试改造儿子的遥控玩具车。原装的碳刷电机噪音大、耗电快想换成更高效的直流无刷电机。当时完全没料到这个简单的需求会让我深入理解PWM脉冲宽度调制技术的精妙之处。现在回想起来PWM就像是用开关水龙头的方式控制水流大小——快速开关龙头通过调整开启时间占比来控制平均流量。这种看似简单的方法却是现代电机控制领域最基础也最有效的技术手段。在STM32项目中PWM的工作频率通常在几百Hz到几十kHz之间。频率太低会听到电机线圈的啸叫声太高则可能导致驱动芯片过热。经过多次实测我发现对于常见的直流有刷电机5-20kHz是最佳工作区间。比如使用TIM2定时器当系统时钟为72MHz时设置预分频器为36-1自动重装载值为100-1就能得到20kHz的PWM波形计算公式72MHz/(36×100)20kHz。这个频率既不会产生可闻噪音又能保证良好的控制响应。2. TB6612驱动模块小身材大能量的电机指挥官TB6612FNG这个火柴盒大小的驱动芯片曾多次拯救我的项目。相比传统的L298N它的效率提升非常明显——实测在驱动6V/1A的直流电机时TB6612的发热量不到L298N的三分之一。这得益于其内部MOSFET设计导通电阻仅有0.3ΩL298N通常在1.5Ω以上。但要注意虽然标称峰值电流可达3.2A实际使用中建议持续电流不要超过1.2A否则即使加装散热片也容易触发过热保护。硬件连接时最容易踩坑的是电源设计。TB6612需要两组电源VM接电机电源我常用7.4V锂电池VCC接逻辑电源通常3.3V或5V。有次偷懒把VCC直接接到VM上结果芯片瞬间发烫报废。后来养成习惯必定在VM端加装100μF以上的电解电容VCC端加0.1μF陶瓷电容这样的组合能有效抑制电压波动。控制信号方面AIN1/AIN2控制转向PWMA调节转速STBY引脚记得拉高才能正常工作——这些基础设置看似简单却是调试时最先要检查的环节。3. STM32的PWM配置定时器的艺术配置STM32的PWM输出就像在指挥交响乐团每个寄存器都要恰到好处。以TIM2的通道3为例PA2引脚关键配置步骤如下首先开启TIM2和GPIOA的时钟这步经常被新手忽略导致调试时找不到问题。然后设置GPIOA_Pin_2为复用推挽输出模式普通输出模式是无法产生PWM的。时基单元中TIM_Period决定PWM的分辨率设为100-1意味着有100级调速精度TIM_Prescaler与系统时钟配合决定PWM频率36-1的分频配合72MHz主频正好是20kHz。输出比较单元才是PWM的核心所在。TIM_OCMode_PWM1模式下当计数器值小于CCR时输出高电平大于时输出低电平。有次项目需要反向PWM波形低电平有效只需改为PWM2模式就轻松实现。TIM_OCPolarity参数也很实用当驱动电路需要低电平有效时设为Low就能省去外部反相器。建议在初始化完成后立即调用TIM_CtrlPWMOutputs使能主输出这个函数对高级定时器尤其重要。4. 电机控制代码的实战技巧Motor_SetSpeed函数是控制逻辑的集大成者。我习惯将速度范围定义为-100~100负值表示反转。函数内部首先要处理方向控制设置GPIOA_Pin_4和Pin_5的电平组合类似H桥的IN1/IN2信号。这里有个优化技巧先读取当前引脚状态只有需要改变时才写入寄存器能减少不必要的IO操作。速度值传递给PWM_SetCompare3前要取绝对值因为PWM占空比只能是正数。在实际项目中我增加了加速度限制功能。直接让电机从0加速到100%会导致电流冲击容易触发电源保护。解决方法是在主循环中逐步调整Speed值#define ACCEL_STEP 5 void Smooth_SetSpeed(int8_t target) { static int8_t current 0; if(current target) current ACCEL_STEP; else if(current target) current - ACCEL_STEP; Motor_SetSpeed(current); }按键处理也有讲究原始代码中长按按键会持续加速但更好的体验是单击加减速。可以修改Key_GetNum函数返回按键事件而非状态typedef enum {KEY_NONE, KEY_PRESS, KEY_HOLD} KeyEvent; KeyEvent Key_GetEvent(void);5. 调试过程中的血泪教训第一次通电测试时电机纹丝不动还伴随刺耳噪音。用示波器检查才发现PWM信号被干扰得面目全非。解决方法是在GPIO引脚就近加100Ω电阻和100pF电容组成低通滤波器。另一个常见问题是电机启动困难表现为低占空比时抖动不转。这通常是由于静摩擦力大于启动力矩我的解决方案是采用kick-start策略初始给一个较高占空比如30%维持50ms再降到目标值。电源问题引发的故障最隐蔽。有次电机运行时OLED突然闪烁复位原来是电源线过长导致压降过大。后来我养成了习惯电机电源与MCU电源完全隔离使用单独的稳压模块所有电源走线尽量短粗地线采用星型连接。电流检测也很重要在电机回路串联0.1Ω采样电阻配合运放电路实现过流保护这个改进让我的开发板成功躲过了多次短路事故。6. 性能优化与进阶玩法基础功能稳定后可以尝试PID闭环控制提升性能。通过编码器获取实际转速与目标值比较后经PID算法动态调整PWM占空比。STM32的硬件编码器接口TIMx_ETR配合正交编码器使用非常方便。一个简单的比例控制实现如下int32_t PID_Update(int32_t target, int32_t actual) { static int32_t last_error 0; int32_t error target - actual; int32_t adjust error * KP (error - last_error) * KD; last_error error; return adjust; }对于更复杂的应用可以启用STM32的定时器中断在中断服务程序中更新PWM参数。比如要实现正弦波驱动可以预计算正弦表在中断中查表修改CCR值。DMA功能还能进一步解放CPU将波形数据自动传输到定时器寄存器。这些高级用法需要仔细计算时序确保中断执行时间小于PWM周期。

更多文章