1. PWM 基础概念:从原理到实战

各位同学好,我是老周。今天咱们开始聊 PWM——脉冲宽度调制。这玩意儿在嵌入式里太常用了,电机、灯光、舵机,哪哪都有它。我最早接触 PWM 还是大学做智能车的时候,那时候只知道调占空比能让电机转得快一点,但到底为什么能调速,说实话没深想。后来踩了不少坑,才把这里面的门道摸清楚。

好,咱们一步步来。

1.1 什么是 PWM?

PWM,全称 Pulse Width Modulation,中文叫脉冲宽度调制。说白了,就是让一个方波信号的高电平时间占比发生变化。

你想想看,数字电路里只有 0 和 1,高电平 3.3V,低电平 0V。那怎么输出一个 1.5V 的电压?直接输出不行,但我们可以让信号快速地在 3.3V 和 0V 之间切换,只要高电平的时间占一半,低电平占一半,平均下来就是 1.65V。这就是 PWM 的核心思想——用数字信号模拟模拟量。

核心公式:

平均电压 = 高电平电压 × 占空比

占空比 = 高电平时间 / 整个周期时间 × 100%

举个例子,3.3V 的 GPIO,输出 50% 占空比的 PWM,平均电压就是 1.65V。输出 75% 占空比,平均电压就是 2.475V。嗯,这里要注意,这个平均电压不是真的直流,而是信号经过惯性环节(比如电机线圈、LED 人眼)之后的等效效果。

1.2 周期与占空比——两个关键参数

PWM 信号有两个核心参数:周期和占空比。我习惯把它们比作呼吸的节奏和深度。

  • 周期(Period):一个完整脉冲的时间长度,单位通常是微秒(μs)或毫秒(ms)。周期决定了 PWM 的频率,频率 = 1 / 周期。
  • 占空比(Duty Cycle):高电平时间占整个周期的百分比。范围 0% 到 100%。

举个例子,一个 1kHz 的 PWM 信号,周期就是 1ms。如果高电平持续 0.5ms,占空比就是 50%。

参数 符号 单位 典型范围 说明
周期 T μs / ms 1 μs ~ 100 ms 频率的倒数,决定 PWM 的刷新速度
频率 f Hz / kHz 10 Hz ~ 1 MHz 周期越短,频率越高
占空比 D % 0% ~ 100% 高电平时间占比,决定等效输出
分辨率 — bit 8 bit / 16 bit 占空比可调节的精细程度

我的经验:选频率的时候别盲目。我曾经在一个电机项目里用了 100kHz 的 PWM,结果电机啸叫得厉害,后来换成 20kHz 就安静了。人耳对 20kHz 以上的频率不敏感,但电机线圈和驱动器不一定受得了。建议先查一下负载的响应带宽,再定频率。

1.3 PWM 的三大应用场景

PWM 的应用场景太多了,但最经典的三个,我挨个说说。

1.3.1 电机调速

直流电机调速,PWM 是主流方案。原理很简单:电机两端的平均电压越高,转速越快。通过改变占空比,就能平滑地控制转速。

我曾经在一个 AGV 小车上用过 L298N 驱动板,PWM 频率设成 10kHz,占空比从 0% 调到 100%,电机转速跟着线性变化。但有个坑——死区。占空比低于 10% 的时候,电机根本转不起来,因为启动扭矩不够。所以实际项目中,我一般会设一个最小占空比阈值,比如 15%。

避坑指南:电机 PWM 频率不能太低,否则电机会一抖一抖的,像在跳舞。也不能太高,否则 MOSFET 开关损耗剧增,驱动器发热严重。我一般推荐 1kHz ~ 20kHz,具体看电机和驱动器的 datasheet。

1.3.2 LED 调光

LED 调光,PWM 也是首选。人眼有视觉暂留效应,只要 PWM 频率高于 60Hz,人眼就感觉不到闪烁,看到的只是亮度的变化。

占空比 0% 时 LED 全灭,100% 时最亮。中间任意比例都能实现平滑调光。我做过一个智能台灯项目,用 1kHz 的 PWM 调光,效果非常好,完全没有频闪感。

但要注意,LED 的亮度与占空比不是完全线性的。人眼对亮度的感知是对数关系,所以如果要做平滑的呼吸灯效果,需要对占空比做 gamma 校正。我一般用查表法,把 0~255 的占空比映射到经过校正的数值上。

// 简单的 gamma 校正查表(gamma = 2.2)
const uint8_t gamma_table[256] = {
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   1,   1,   1,   1,   1,   1,
    // ... 中间省略 ...
    251, 252, 253, 254, 255
};

1.3.3 舵机控制

舵机控制是 PWM 的另一个经典应用。标准舵机(比如 SG90)的控制信号是 50Hz 的 PWM,周期 20ms。占空比 1ms 对应 0°,1.5ms 对应 90°,2ms 对应 180°。

说白了,就是通过改变高电平的脉宽来控制舵机转动的角度。我刚开始做的时候,直接用延时函数模拟 PWM,结果舵机抖得不行。后来换成硬件定时器,精度到微秒级,才稳定下来。

角度 脉宽(μs) 占空比(50Hz) 说明
0° 1000 5% 最左位置
90° 1500 7.5% 中间位置
180° 2000 10% 最右位置

我的习惯:舵机控制一定要用硬件 PWM,别用软件模拟。软件模拟容易受中断影响,导致脉宽抖动,舵机就会跟着抖。STM32 的定时器 PWM 模式,或者 Arduino 的 Servo 库,都是好选择。

1.4 本章知识体系总览

下面这张图,把 PWM 的核心概念、关键参数和三大应用场景串起来了。你可以把它当作本章的思维导图。

PWM 知识体系总览 PWM 脉冲宽度调制 周期 / 频率 占空比 / 分辨率 平均电压等效 三大应用场景 电机调速 直流电机 / 无刷电机 LED 调光 视觉暂留 / gamma 校正 舵机控制 50Hz / 脉宽 1~2ms 核心:用数字信号模拟模拟量,通过占空比控制等效输出 频率决定刷新速度,占空比决定输出幅度

1.5 小结

这一章咱们把 PWM 的基础概念捋了一遍。周期和占空比是灵魂,电机调速、LED 调光、舵机控制是三大经典应用。我个人觉得,理解 PWM 的关键不在于背公式,而在于想清楚一个问题:为什么一个方波信号能控制模拟量?想通了这一点,后面配置定时器、调参数就顺了。