3. PWM调制原理:自然采样与规则采样、单极性调制与双极性调制、SPWM的数学实现
各位工程师朋友,咱们今天聊聊PWM调制。说实话,这玩意儿是逆变器控制算法的基本功。我见过不少新手,一上来就调PID、搞矢量控制,结果波形乱七八糟,最后发现是PWM调制这块没吃透。嗯,咱们今天就把这块硬骨头啃下来。
3.1 自然采样法:最直观,但最不实用
自然采样法,说白了就是拿正弦波和三角波直接比大小。正弦波比三角波高的时候,输出高电平;低的时候,输出低电平。你想想看,这不就是模拟电路里比较器干的事吗?
我在项目里第一次用这个方法,是在一个实验室验证平台上。当时觉得这方法多好啊,物理意义清晰,谐波含量也低。但一上DSP就傻眼了——计算量太大了。
核心问题:自然采样法需要求解超越方程,才能算出每个开关周期的导通时间。在实时控制里,这几乎不可能。
为什么会这样?因为正弦波和三角波的交点,没法用简单的代数表达式算出来。你得用牛顿迭代法或者查表法。查表法占内存,迭代法占CPU。我当年用TMS320F2812,主频才150MHz,跑一次迭代要几十微秒,根本扛不住。
我的建议:自然采样法适合做离线仿真,或者用FPGA做硬件比较。实时控制里,别碰它。
3.2 规则采样法:工程界的标准答案
规则采样法,说白了就是自然采样法的简化版。它不找正弦波和三角波的真实交点,而是用正弦波在三角波顶点(或底点)的采样值,去近似整个周期的导通时间。
我习惯把规则采样法分成两种:
- 对称规则采样:在三角波的顶点采样,认为整个周期内正弦值不变。计算简单,但精度一般。
- 不对称规则采样:在三角波的顶点和底点各采一次,相当于用两个采样值逼近正弦波。精度更高,但计算量翻倍。
你可能会问:精度差多少?我拿实测数据跟你说。对称规则采样在低频段(50Hz)基本够用,THD能做到3%以内。但到了高频段(400Hz以上),不对称规则采样明显更优,THD能压低到1.5%以下。
避坑指南:我曾经在一个航空电源项目里,用了对称规则采样,结果输出波形在过零点附近出现了明显的畸变。后来换成不对称规则采样,问题就解决了。原因是过零点附近正弦波变化率最大,对称采样跟不上变化。
规则采样的数学实现很简单:
// 对称规则采样,载波周期为Tsw
ton = (Tsw/2) * (1 + M * sin(θ))
// 其中M为调制比,θ为当前采样点的角度
// 不对称规则采样,载波周期为Tsw
ton1 = (Tsw/2) * (1 + M * sin(θ_顶点))
ton2 = (Tsw/2) * (1 + M * sin(θ_底点))
// 实际导通时间为两个半周期的平均值
3.3 单极性调制 vs 双极性调制
这两个概念,我刚开始学的时候也搞混过。说白了,它们描述的是输出电压的极性变化方式。
| 特性 | 单极性调制 | 双极性调制 |
|---|---|---|
| 输出电压极性 | 只在正半周输出正电压,负半周输出负电压 | 整个周期内,输出电压在+Vdc和-Vdc之间切换 |
| 开关损耗 | 较低(每个周期只有一半时间在开关) | 较高(全程都在开关) |
| 谐波特性 | 谐波集中在载波频率附近,且幅值较小 | 谐波含量更高,且包含更多的低频分量 |
| EMI | 较好(电压跳变幅度小) | 较差(电压跳变幅度大) |
| 适用场景 | 对效率要求高的场合(如光伏逆变器) | 对动态响应要求高的场合(如电机驱动) |
我个人习惯在单相逆变器里用单极性调制。为什么呢?因为单极性调制在过零点附近有一个自然死区,能有效降低开关损耗。我记得有一次做3kW的离网逆变器,用单极性调制,效率做到了97.5%。换成双极性,直接掉到95%。
但双极性调制也有它的优势。它的控制逻辑简单,不需要判断电压极性,适合做快速电流环。我在做电机驱动时,就偏爱双极性调制,因为电流响应快,不容易出现零电流钳位现象。
关键区别:单极性调制需要两个载波(一个正半周用,一个负半周用),或者用逻辑电路处理过零点。双极性调制只需要一个载波,简单粗暴。
3.4 SPWM的数学实现:从公式到代码
SPWM,全称是Sinusoidal Pulse Width Modulation。说白了,就是让脉冲宽度按正弦规律变化。数学上,它的核心公式就一个:
D(t) = 0.5 + 0.5 * M * sin(ωt + φ)
// D(t)为占空比,M为调制比(0~1),ω为输出角频率,φ为初始相位
你可能会觉得这太简单了。但实际工程里,坑都在细节里。我列几个常见的:
- 调制比M不能超过1:超过1就进入过调制区,输出电压会失真。我见过有人把M设到1.2,结果波形顶部削平了,谐波含量暴增。
- 载波比要选好:载波频率和输出频率的比值,一般建议在20以上。太低的话,输出波形会明显阶梯化。
- 死区补偿不能忘:实际开关管有死区时间,会导致输出电压偏低。我习惯在占空比里加一个死区补偿量,大概占载波周期的1%~2%。
下面是我常用的SPWM实现代码,基于定点数运算,适合在低成本MCU上跑:
// 假设载波频率10kHz,输出频率50Hz,载波比200
// 使用查表法,正弦表长度200个点
#define TABLE_SIZE 200
#define PWM_PERIOD 1000 // 载波周期对应的定时器计数值
uint16_t sin_table[TABLE_SIZE] = { /* 预计算的正弦值,范围0~1000 */ };
void spwm_update(uint16_t index) {
uint16_t duty;
uint16_t sin_val = sin_table[index];
// 占空比计算:D = 0.5 + 0.5 * M * sin(θ)
// 这里M=0.8,用定点数表示
duty = (PWM_PERIOD >> 1) + ((sin_val * 800) >> 10);
// 更新PWM比较寄存器
PWM_CMPA = duty;
PWM_CMPB = PWM_PERIOD - duty; // 互补输出
}
我的经验:正弦表不要用浮点数算,太慢了。用定点数,把0~1映射到0~1000或者0~4095,查表加线性插值,精度完全够用。
最后说一句,SPWM的数学实现,本质上就是用时间换电压。你输出的不是正弦波,而是一串宽度变化的脉冲。但经过滤波后,它就变成了正弦波。这个思想,贯穿了整个逆变器控制算法。
嗯,这一章就到这里。下一章咱们聊聊载波频率怎么选,以及不同载波频率对系统性能的影响。到时候我会拿几个实际项目的波形图出来,咱们一起分析分析。