第三章 PWM基本原理:占空比、频率、分辨率与电机控制

各位同学,今天我们来聊聊PWM。说实话,PWM这东西在嵌入式领域太常见了,但很多人用了好几年,真问起原理来,还是模模糊糊的。我记得刚入行那会儿,调一个舵机PWM,频率设错了,舵机吱吱叫就是不转,折腾了一下午才发现是频率不对。嗯,今天咱们就把这些基础概念彻底捋清楚。

3.1 什么是PWM?

PWM,全称Pulse Width Modulation,脉冲宽度调制。说白了,就是通过调节脉冲的宽度来控制平均电压。你想想看,单片机输出的数字信号只有0和3.3V(或者5V),但电机需要的是连续可变的电压,怎么办?

答案就是:快速开关。让电压在0和3.3V之间高速切换,通过调节高电平持续的时间比例,来模拟出一个中间电压。这就是PWM的核心思想。

核心公式:平均电压 = 高电平电压 × 占空比

比如3.3V的PWM,占空比50%,平均电压就是1.65V。

3.2 PWM的三个核心参数

搞懂PWM,你只需要记住三个东西:频率、占空比、分辨率。我习惯把它们比作水龙头——频率是开关的快慢,占空比是开多大,分辨率是你能多精细地调节开度。

3.2.1 占空比(Duty Cycle)

占空比就是高电平时间占整个周期的比例。单位是百分比,0%就是一直低电平,100%就是一直高电平。

  • 50%占空比:高电平和低电平各占一半时间
  • 75%占空比:高电平占3/4,低电平占1/4
  • 0%占空比:完全关闭
  • 100%占空比:完全打开

我在做四旋翼电调驱动时遇到过一个问题:电机在低占空比(比如5%以下)时根本不转,因为启动扭矩不够。后来我加了一个「软启动」策略,先给一个高占空比脉冲再降下来,问题就解决了。

3.2.2 频率(Frequency)

频率就是一秒钟内PWM波形重复的次数,单位是Hz。频率决定了PWM的「细腻程度」。

应用场景 典型频率 说明
LED调光 100Hz - 1kHz 人眼有视觉暂留,太低会闪烁
舵机控制 50Hz 标准舵机周期20ms
直流电机 10kHz - 50kHz 太高开关损耗大,太低有噪音
无刷电机(FOC) 16kHz - 40kHz 避开人耳可听范围

避坑指南:我曾经在PX4上调试一个电调,把PWM频率设成了400Hz,结果电机发出刺耳的尖叫声。后来才发现,400Hz刚好在人耳最敏感的频段附近。建议电机控制至少用16kHz以上,人耳基本听不到。

3.2.3 分辨率(Resolution)

分辨率决定了你能把占空比调节得多精细。比如8位PWM,分辨率就是256级(0-255);16位PWM,分辨率就是65536级。

计算公式很简单:

分辨率 = log2(定时器计数周期)

举个例子:STM32的定时器ARR设为999,那么分辨率就是log2(1000) ≈ 10位。这意味着你可以把占空比分成1000个等级。

我的经验:电机控制一般10位分辨率就够了,但LED调光或者高精度伺服,建议用12位以上。分辨率太高也有代价——定时器频率会受限,因为计数周期变长了。

3.3 PWM在电机控制中的应用

电机控制是PWM最经典的应用场景。我参与过好几个无人机电调项目,这里分享一下实际经验。

3.3.1 直流有刷电机

最简单的应用。通过PWM控制MOS管的开关,调节电机两端的平均电压,从而控制转速。

// 伪代码示例:直流电机PWM控制
void motor_set_speed(uint8_t speed) {
    // speed: 0-255
    TIM1->CCR1 = speed;  // 设置占空比
}

这里要注意:电机是感性负载,PWM开关时会产生反电动势。我刚开始做的时候没加续流二极管,结果MOS管烧了好几个。嗯,教训深刻。

3.3.2 无刷直流电机(BLDC)

BLDC需要六步换向,PWM配合换相时序。在PX4中,我们通常使用定时器的互补PWM输出,带死区插入。

// PX4中BLDC PWM配置示例
// 使用STM32 TIM1的CH1/CH1N互补输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;  // 互补通道
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

关键点:死区时间设置很关键。太短会导致上下管直通短路,太长会影响效率。我一般设1-2μs,具体看MOS管的开关速度。

3.3.3 永磁同步电机(PMSM)与FOC

FOC(磁场定向控制)是现在无人机的主流方案。它需要两路高频PWM(SVPWM调制),配合电流采样。

在PX4中,FOC的PWM频率通常设在20kHz-40kHz。为什么是这个范围?

  • 低于16kHz:人耳能听到,电机噪音大
  • 高于40kHz:开关损耗急剧增加,MOS管发热严重
  • 20kHz左右:平衡了噪音和效率

3.4 知识体系总览

下面这张图是我自己画的PWM知识体系,帮你把今天的内容串起来:

PWM基本原理 占空比 频率 分辨率 直流有刷电机 无刷直流电机(BLDC) 永磁同步电机(FOC) 关键设计参数 • 死区时间:1-2μs(防止上下管直通) • 频率选择:电机控制建议16kHz-40kHz • 分辨率:电机控制10位足够,高精度应用12位+

3.5 实际项目中的避坑指南

最后,分享几个我踩过的坑:

  1. 频率和分辨率是矛盾的:定时器时钟固定时,频率越高,分辨率越低。你需要根据应用做取舍。
  2. PWM输出要加RC滤波吗?:控制电机不需要,但如果你要测量PWM的平均电压,需要加低通滤波。
  3. 启动时别直接给满占空比:电机启动电流很大,容易烧MOS管。我习惯用软启动,从10%逐渐升到目标值。
  4. 注意PWM的极性:有些电调是高电平有效,有些是低电平有效。接反了电机不转,别问我怎么知道的。

调试小技巧:用逻辑分析仪看PWM波形,比用示波器方便多了。我一般先看频率对不对,再看占空比变化是否线性,最后看死区时间是否合适。

好了,PWM的基本原理就讲到这里。这些概念虽然基础,但真要在项目中用好,还是需要不少实践积累的。下次我们讲定时器的具体配置,到时候会结合STM32和PX4的代码,手把手教你配出稳定的PWM输出。


专注资料整理