2、PWM基础原理:什么是PWM?占空比、频率与分辨率的关系。PWM在电机控制中的角色(调速、转向、扭矩)
各位同学,咱们今天聊聊PWM。说实话,PWM这玩意儿在电机控制里,就跟炒菜离不开盐一样,太基础也太重要了。我刚开始做电机驱动那会儿,总觉得PWM不就是个方波嘛,有啥好研究的?结果第一次调电机,电机嗡嗡响就是不转,折腾了一下午才发现是频率没设对。嗯,从那以后,我再也不敢小看这个“方波”了。
2.1 什么是PWM?
PWM,全称Pulse Width Modulation,中文叫脉冲宽度调制。说白了,就是通过调节一个方波信号里“高电平”占整个周期的比例,来模拟一个模拟电压。
你想想看,单片机输出的数字信号只有0和3.3V(或者5V),但电机需要的是连续可调的电压。怎么办?PWM就是答案。我们让信号快速地在0和3.3V之间切换,只要切换得够快,电机看到的“平均电压”就是可调的。
核心概念:PWM不是真的输出一个连续变化的电压,而是通过高速开关,让负载“感觉”到平均电压在变化。
2.2 占空比、频率与分辨率
这三个参数,是PWM的灵魂。我一个个说。
2.2.1 占空比(Duty Cycle)
占空比,就是高电平时间占整个周期的百分比。比如一个周期是1ms,高电平0.5ms,那占空比就是50%。
占空比直接决定了平均电压:
- 占空比0%:一直低电平,平均电压0V
- 占空比50%:一半时间高,一半时间低,平均电压1.65V(3.3V供电时)
- 占空比100%:一直高电平,平均电压3.3V
我在项目中遇到过一个问题:用PWM控制LED亮度,发现50%占空比时LED不是半亮,而是明显偏暗。后来查资料才知道,人眼对亮度的感知不是线性的。电机也一样,占空比和转速之间也不是严格的线性关系,这个后面会细说。
2.2.2 频率(Frequency)
频率,就是PWM信号每秒切换的次数。单位是Hz。
频率的选择很关键。太低了,电机会“一抖一抖”地转,甚至发出刺耳的噪音。太高了,MOS管的开关损耗会急剧增加,发热严重。
我个人习惯:
- 直流有刷电机:1kHz ~ 20kHz,常用10kHz左右
- 步进电机:20kHz ~ 40kHz
- 无刷直流电机(BLDC):16kHz ~ 20kHz,避开人耳敏感区
避坑指南:我曾经把PWM频率设到100kHz,想着“频率越高越平滑嘛”。结果MOS管烫得能煎鸡蛋,电机反而没力。后来才明白,开关损耗和频率成正比,频率不是越高越好。
2.2.3 分辨率(Resolution)
分辨率,就是占空比能调节的精细程度。比如8位PWM,占空比可以从0到255共256级调节。10位就是0到1023,共1024级。
分辨率越高,电机转速控制就越精细。但要注意,分辨率受限于定时器的时钟频率和PWM频率。
举个例子:
// 8位PWM配置(以STM32为例)
TIM_HandleTypeDef htim2;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; // 72MHz / (71+1) = 1MHz
htim2.Init.Period = 255; // 8位分辨率,PWM频率 = 1MHz / (255+1) ≈ 3.9kHz
HAL_TIM_PWM_Init(&htim2);
// 设置占空比50%
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 128);
你看,定时器时钟1MHz,周期寄存器设255,那PWM频率就是1MHz/256≈3.9kHz。如果你想提高频率到10kHz,那周期寄存器就得设99(1MHz/100=10kHz),分辨率就降到7位(0-99)了。
这就是频率和分辨率的矛盾——鱼和熊掌不可兼得。
| 分辨率 | 占空比级数 | 最大PWM频率(72MHz定时器时钟) |
|---|---|---|
| 8位 | 256 | 72MHz / 256 ≈ 281kHz |
| 10位 | 1024 | 72MHz / 1024 ≈ 70kHz |
| 12位 | 4096 | 72MHz / 4096 ≈ 17.6kHz |
| 16位 | 65536 | 72MHz / 65536 ≈ 1.1kHz |
注意:实际项目中,PWM频率通常不会用到定时器的极限值。要考虑MOS管的开关速度、电机的电感特性、以及EMI(电磁干扰)等因素。我一般留50%以上的余量。
2.3 PWM在电机控制中的角色
PWM在电机控制里,主要干三件事:调速、转向、扭矩控制。咱们一个一个说。
2.3.1 调速
这是PWM最直接的应用。改变占空比,就改变了电机两端的平均电压,从而改变转速。
但要注意,占空比和转速不是简单的线性关系。因为电机有死区电压——电压太低时,电机根本转不起来。我做过一个测试:
- 占空比10%:电机不转(电压不够克服静摩擦力)
- 占空比20%:电机开始缓慢转动
- 占空比50%:转速约1500rpm
- 占空比80%:转速约2400rpm
- 占空比100%:转速约3000rpm
你看,从20%到100%,转速变化不是线性的。实际项目中,我一般会做一段“占空比-转速”标定表,或者用PID闭环控制来补偿。
2.3.2 转向
PWM本身不能改变转向。转向靠的是H桥电路——通过控制四个MOS管的开关组合,改变电机电流的方向。
典型的H桥控制逻辑:
// 正转:Q1和Q4导通,Q2和Q3关断
// Q1 = PWM, Q4 = 常开, Q2 = 关断, Q3 = 关断
// 反转:Q2和Q3导通,Q1和Q4关断
// Q2 = PWM, Q3 = 常开, Q1 = 关断, Q4 = 关断
// 刹车:Q1和Q3导通(或Q2和Q4导通),电机两端短路
// 滑行:所有MOS管关断,电机自由旋转
这里有个坑:切换转向时,一定要先让所有MOS管关断一段时间(死区时间),否则上下桥臂会直通,瞬间烧毁MOS管。我曾经就因为死区时间设得太短,烧了三个MOS管才找到原因。
2.3.3 扭矩控制
扭矩控制比调速复杂一些。简单来说,电机的扭矩和电流成正比(对于直流电机,T = Kt * I)。所以控制扭矩,本质上就是控制电流。
PWM怎么控制电流?通过调节占空比来改变电压,电压改变电流,电流改变扭矩。但这里有个问题:电机是感性负载,电流不会突变。
我举个例子:
- 占空比从0%突然跳到50%,电流不会瞬间到目标值,而是按指数规律上升
- 上升时间取决于电机的电气时间常数 τ = L/R
所以,如果你想要精确的扭矩控制,光靠开环PWM是不够的。需要加电流采样,做闭环控制。我常用的方法是:
// 电流环PID控制伪代码
while(1) {
target_current = 根据目标扭矩计算;
actual_current = ADC读取电流采样电阻;
error = target_current - actual_current;
pid_output = PID_Calculate(error);
set_pwm_duty(pid_output); // PID输出直接作为占空比
delay_ms(1); // 电流环通常1kHz左右
}
关键点:PWM控制扭矩,本质上是控制电流。而电流控制需要闭环,不能只靠开环的占空比调节。
2.4 实际项目中的PWM配置建议
说了这么多理论,最后给点实际建议。这是我这些年做电机驱动总结出来的:
- 频率选择:先看电机的手册,一般会推荐PWM频率范围。没有手册的话,从10kHz开始试,听声音、摸温度、看转速平稳性。
- 分辨率:调速用8位够用,扭矩控制建议10位以上。我一般用10位,兼顾精度和频率。
- 死区时间:MOS管的数据手册会给出最小死区时间。我习惯在最小值基础上加50%的余量。
- 启动处理:电机启动时,不要直接给目标占空比。我习惯用“软启动”——占空比从0逐渐增加到目标值,时间大约100-500ms。
- 保护机制:PWM输出一定要有过流保护。我一般用硬件比较器,电流超过阈值直接关断PWM输出,比软件响应快得多。
个人经验:调试PWM时,先用示波器看波形,确认频率、占空比、死区时间都对,再接电机。我见过太多人上来就接电机,结果波形不对,电机乱转,还以为是代码写错了。
好了,PWM的基础原理就讲到这里。下一节咱们聊聊具体的PWM生成方式——用定时器怎么配置,用软件怎么模拟,以及各自的优缺点。有什么问题,咱们课后交流。