最近把三相两电平逆变器的调制算法又重新过了一遍,重点把DPWM也就是不连续脉宽调制那一族拉出来做了仿真对比:DPWM00、DPWM01、DPWM02、DPWM03、DPWMMIN、DPWMMAX,六个变体在Simulink里逐个搭了一遍。网上讲DPWM原理的资料不少,但大多数停留在“少切一半开关”这种定性描述,真到要复现的时候才发现,连“这六种到底差在哪”都没人说清楚。这篇文章就把算法机理、仿真模型搭建、参数设置、结果对比和踩坑过程一次性讲透,给做电机控制、并网逆变器或者电力电子仿真验证的同行一个可以直接上手的参考。
1. DPWM到底是什么,它和SVPWM是什么关系
先说一个很多人绕不过去的点:DPWM并不是一个凭空冒出来的新调制算法,它本质上是从SVPWM演化出来的一类变体。理解这个概念,后面的仿真对比就顺了。
1.1 从SPWM到SVPWM再到DPWM的演进逻辑
SPWM的思路最简单,把三相正弦波分别和同一个三角载波比较,占空比按正弦规律变化,输出线电压也是正弦脉宽序列。但SPWM的直流母线电压利用率不高,线电压峰值最多到直流母线电压的一半,对380V交流输出,直流母线至少要给到620V以上。
SVPWM换了个角度,不是“逐相调制”,而是从空间电压矢量的角度出发,用八个基本开关矢量去合成期望的旋转电压矢量。因为加入了零矢量重新分配时间,SVPWM的线性调制范围提高了约15%,等效于在每相调制波里注入了一个零序分量。你可以把它理解为“给三相正弦波叠加了一个第三谐波为主的共模电压”。
DPWM的思路再往前走一步:既然可以注入零序分量,那能不能注入得更“狠”一点,让某一相在一段时间内直接钳位到正母线或负母线,完全不做开关动作?这样开关次数直接减少三分之一,开关损耗大幅下降,代价是这一相的波形暂时“不连续”,所以叫不连续脉宽调制Discontinuous PWM。
这里有个新手特别容易疑惑的地方:既然SVPWM已经注入了零序分量,DPWM注入的也是零序分量,那SVPWM算不算一种DPWM?严格说,SVPWM可以看作一种特殊的DPWM,因为它在一个60°扇区内确实存在某一相钳位。但通常讲的DPWM族,是指把人为主观设计的、带有更长钳位区间的那类调制,钳位角度可以连续调整,而SVPWM的钳位模式是固定的。
1.2 零序注入为什么不影响负载线电压
这一点是整个DPWM算法成立的根本,也是仿真验证时必须心里有数的前提。三相三线系统中,线电压等于两相电压之差。注入零序分量vz后,每相调制波变成ua+vz、ub+vz、uc+vz,线电压是(ua+vz)-(ub+vz)=ua-ub,vz正好抵消。所以无论零序分量怎么折腾,负载上得到的线电压基波分量不变,改变的是开关模式和谐波分布。
这就好比三个人抬一块板,三个人同时向上多垫了同样厚度的垫子,板子两端的相对高度差完全没变。DPWM所有“看起来诡异”的调制波形,都是在这个前提下做文章。
仿真里看相电压波形会明显看到不连续的部分,但看线电压波形依然比较规矩,就是因为这个原因。后面FFT分析时,也要注意区分:相电压某个扇区的谐波含量很高,不代表线电压同样糟糕,负载真正关心的是线电压和线电流。
2. 六种DPWM的算法机理与区别
标题里的六种DPWM,核心差异可以归纳成一句话:钳位方式不同,分别是钳位到正母线、负母线,以及钳位位置在不同角度之间的切换组合。
2.1 用零序注入公式统一理解DPWM
几乎所有载波类PWM策略都可以用零序注入公式来统一描述。设原始三相正弦波为ua、ub、uc,调制波为三相正弦与零序分量的叠加:
uam = ua + vz,ubm = ub + vz,ucm = uc + vz
其中vz就是在三相共模通道里注入的零序电压。对于SVPWM,常用公式是:
vz = -0.5 × (max(ua,ub,uc) + min(ua,ub,uc))
这个零序分量让三相调制波在±1之间波动,且永远不会过调制。DPWM的思路同样是给三相调制波加上零序,区别在于vz的选择会让某一相在某段时间内恰好达到+1或-1,只要达到限幅值,这一相在这一段时间内就一直输出正母线或负母线电平,开关自然就停止了。
用统一形式表达DPWM族可以写成:
vz = (2k-1) - k·max(ua,ub,uc) - (1-k)·min(ua,ub,uc)
其中k在0到1之间变化。k=1时,vz = 1 - max(ua,ub,uc),最大相被强行抬到+1,对应全上钳位,也就是DPWMMAX。k=0时,vz = -1 - min(ua,ub,uc),最小相被压到-1,对应全下钳位,也就是DPWMMIN。k取中间值时,对应钳位位置在正负母线之间交替的多种DPWM模式,DPWM00、DPWM01、DPWM02、DPWM03就落在这个区间里。
这套公式最大的好处是参数化:不用为每种DPWM单独写一套波形生成逻辑,一个k参数就串起来了。实际做仿真调参时,完全可以把k做成一个滑块,实时看不同钳位模式下波形和谐波的变化趋势。
2.2 DPWMMIN与DPWMMAX:两种极端钳位方式
DPWMMIN是所有相在对应的半个周期中都偏向负母线钳位,也就是说某个桥臂的下管会长时间导通,上管长时间关断。DPWMMAX正好相反,某个桥臂的上管长时间导通。
这两种极端方式的意义在于:功率器件的开关损耗与开关瞬间流过器件的电流直接相关。如果开关时刻恰好对应相电流很大的点,一次开关动作产生的损耗就很大;如果能在电流峰值附近把开关动作“屏蔽”掉,损耗就明显降低。
那么问题来了:电流峰值到底在什么位置?对于阻感性负载,相电流滞后于相电压,滞后角度就是负载功率因数角。如果负载是纯感性,电流滞后电压90°,这时应该把钳位区放在电压过零附近,因为电压过零附近电流接近峰值,屏蔽掉这一段的开关动作收益最大。DPWMMIN和DPWMMAX就分别针对电流超前和滞后的极端情况做了特殊处理。
实际电机负载大多是感性的,功率因数角在30°到60°之间,所以DPWMMAX在电机驱动里应用更广泛。但要注意,负载工况一变,最优钳位位置就变了,这也是DPWM00到DPWM03这些中间变体存在的意义——它们的钳位位置连续可调,可以匹配不同功率因数角。
2.3 DPWM00到DPWM03:钳位位置的连续变化
DPWM00、01、02、03这四组,我在仿真中采用的是“钳位中心角”来区分,也就是在一个60°扇区内,钳位区间中心相对于相电压峰值的位置偏移。这样说有点抽象,换个说法:把一相在一个基波周期内要做开关动作的区间看成一个窗口,窗口安装在哪个位置,决定了开关损耗和谐波性能的取舍。
- DPWM00:钳位区间中心基本对准相电压过零点,上下钳位交替对称,调制波形和SVPWM比较接近,开关损耗降幅相对有限,但电流谐波性能保持得不错。
- DPWM01:钳位位置向前偏15°,钳位中心往相电压峰值方向挪了一点,开关损耗进一步下降,谐波开始变差。
- DPWM02:钳位位置再往前偏,接近30°,这时候钳位区间开始覆盖电流峰值附近,开关损耗优势明显,但谐波畸变更严重。
- DPWM03:钳位位置偏向45°,是四种中间模式里钳位最“激进”的,开关损耗最低,谐波最大。
这里有一个工程上常见的折中逻辑:开关损耗和谐波THD是一对矛盾,DPWM族本质上就是在二者之间选一个平衡点。没有绝对最优的DPWM,只有最适合当前负载和开关频率的DPWM。仿真对比并不能得出“哪个最好”的结论,而是告诉你每种模式在什么工况下值得用。
3. Simulink仿真模型搭建全过程
理论说完,直接上实操。我用的是MATLAB/Simulink,版本是R2021a,Simscape Electrical工具箱。整体模型分成主电路、控制信号生成、PWM比较与死区、测量分析四块。
3.1 主电路拓扑与参数选择
三相两电平逆变器主电路不复杂:直流电压源、直流母线电容、三相桥臂六支IGBT和反并联二极管、三相RL负载。模型搭建时有两个容易忽略的细节。
第一个是直流母线电容不能省。即使直流侧用理想电压源,母线电容也建议保留,因为IGBT开关动作会产生脉动电流,电容能吸收这部分纹波。容值给到几百微法到几毫法之间都行,仿真里主要起稳定直流母线电压作用,取2000μF比较稳。
第二个是IGBT模块的导通压降和开关宏模型参数。做原理验证时可以直接把导通电阻设得比较小,比如1mΩ,开关时间设1μs,这样仿真速度快,波形也干净。但如果你要分析开关损耗的绝对数值,就必须用实际IGBT数据手册的参数,这就是另一套玩法了,建议先把原理跑通再考虑损耗标定。
我这次仿真用的参数如下:
| 参数项 | 数值 | 说明 |
|---|---|---|
| 直流母线电压Vdc | 700V | 模拟三相380V交流输出的常用母线电压 |
| 调制比M | 0.9 | 小于线性调制上限1.15,留出余量 |
| 基波频率f0 | 50Hz | 工频输出 |
| 载波频率fc | 5kHz | 兼顾损耗和谐波对比,可视化也清楚 |
| 负载电阻R | 10Ω | 每相阻值 |
| 负载电感L | 10mH | 对应功率因数约56°,接近典型电机工况 |
| 死区时间 | 2μs | 先设0观察理想波形,后加死区看畸变 |
| 仿真步长 | 0.5μs定步长 | 保证载波边缘采样精度 |
这里特别说下调波比。很多新手直接设M=1,觉得越大越好,结果调制波形一限幅就各种乱跳。DPWM本身就是要让调制波触及±1限幅的,M太大会让钳位区间完全覆盖半个周期,波形失真严重。M=0.9时,DPWM能清楚看到“某相保持不动”的钳位段,又不至于出现过调制导致的电流畸变。
3.2 MATLAB Function生成DPWM调制波
核心难点在于生成六种DPWM对应的三相调制波。我最开始试着用Simulink里的常量模块搭查表逻辑,搭到第三个扇区就乱成一团,后来果断改成MATLAB Function方式,用代码生成波形再送给PWM模块。
代码的核心思路就是前面说的零序注入公式,加上钳位模式选择。具体实现看下面这段:
function [uam, ubm, ucm] = dpwm_ref(wt, M, type) % wt: 当前电角度 rad % M: 调制比 0~1.15 % type: 1=DPWM00, 2=DPWM01, 3=DPWM02, 4=DPWM03, 5=DPWMMIN, 6=DPWMMAX ua = M*cos(wt); ub = M*cos(wt - 2*pi/3); uc = M*cos(wt + 2*pi/3); u = [ua; ub; uc]; umax = max(u); umin = min(u); switch type case 1 % DPWM00, 上钳位和下钳位对称交替 k = 0.5; case 2 % DPWM01, 钳位点前移 k = 0.5833; case 3 % DPWM02 k = 0.6667; case 4 % DPWM03 k = 0.75; case 5 % DPWMMIN, 全下钳位 k = 0; case 6 % DPWMMAX, 全上钳位 k = 1; otherwise k = 0.5; end vz = (2*k-1) - k*umax - (1-k)*umin; uam = min(max(ua+vz, -1), 1); ubm = min(max(ub+vz, -1), 1); ucm = min(max(uc+vz, -1), 1); end代码里的k值选择是基于钳位位置连续变化的映射,仿真实测下来能清楚看到钳位区间位置的移动。如果你手头有标准查表法的参考实现,也可以把查表逻辑写进去,效果更接近论文中的标准波形。区别在于查表法更精确,但代码更长,作为通用快速验证,k参数法完全够用。
一个重要的细节是限幅运算min和max一定要加,否则零序注入后调制波可能超过±1范围,送给PWM发生器后会产生幅值不可控的危险波形。
这个MATLAB Function的输入wt我直接用积分器或者时钟从0积分得到,乘以2πf0就是实时电角度。注意要用定步长求解器,否则电角度积分和载波比较不同步,波形会出现抖振。
3.3 PWM脉冲生成与死区设置
调制波生成好以后就简单了。我用的是PWM Generator模块,在Simscape Electrical的Specialized Power Systems里,选择Three-phase,Two-level桥臂,用外部输入调制波的模式,频率设5kHz,采样时间设0.5μs。
注意PWM Generator里有一个“内部生成载波”的选项,三角载波峰值默认是1,幅值类型跟调制波标幺值要匹配。如果发现开关动作异常或占空比错误,先检查调制波是不是标幺值,和模块里载波幅值是否一致。
死区时间我一开始设为0,先把纯PWM波形跑通,确认六种DPWM的钳位段清晰可见后,再把死区时间加回去。死区时间对低次谐波的影响其实很明显,做电流THD对比时一定要带着死区测,否则结果偏理想化。
还有一种做法是不用PWM Generator模块,自己搭三角载波加比较器加逻辑门电路,古典但直观,适合教学演示。缺点是模型很大,跑起来慢,改一个参数要找半天。我建议仿真验证阶段用PWM Generator,如果要做控制层面的联合仿真,再考虑把比较逻辑写进控制代码里。
3.4 数据测量与FFT谐波分析准备
仿真结果要拿数据说话,不能只看看波形就完事。我在模型里加了几个关键测量点:三相调制波直接通过Scope输出,桥臂中点对直流母线中点的相电压用Voltage Measurement测量,线电压和线电流分别测,输出用To Workspace存成结构体。
为了做FFT分析,采样时间必须固定,数据长度要覆盖整数个基波周期。电机控制里常用的是存0.1秒也就是5个工频周期的数据,FFT窗口选择“整周期截取”,这样可以避免频谱泄漏。
Powergui模块里可以直接做FFT分析,但我个人习惯用MATLAB脚本处理To Workspace导出的数据,这样批量对比六种DPWM时效率高得多。脚本里设置好基波频率50Hz,采样频率2MHz,取最后一个周期的数据,调用fft函数算出各次谐波幅值,再计算THD,一次循环就把六组结果全部输出。
这一步看似不起眼,但对比表能不能生成出来全看它。很多新手在Scope里看波形觉得挺好,一到写报告时发现没有THD数据,只能回去补测,很浪费时间。
4. 六种DPWM的仿真结果对比
模型跑通以后,我最先做的是把六种DPWM的调制波和相电压波形放在同一个图上对比。这一步不做任何数据处理,纯粹肉眼看趋势,信息量反而最大。
4.1 调制波与钳位效果直观对比
把DPWMMIN的A相调制波调出来看,最直观的感受是:波形在负半周有一段长时间保持-1,对应下管一直导通,上管完全关死。DPWMMAX则相反,正半周的某一段长时间保持+1。DPWM00到DPWM03的波形介于两者之间,钳位段在正负半周交替出现,而且随着编号增大,钳位段中心位置明显向正母线方向移动。
留意一个细节:每一相的钳位区间并不是连续120°一钳到底,而是分成正半周一段和负半周一段,各占约60°,拼起来才是一个基波周期的三分之一。所以“开关次数减少三分之一”是这个含义,不是某一相完全停掉三分之一周期。
另一个观察点是载波比较后的桥臂输出电压:钳位区间内,桥臂输出电平恒定不变,开关纹波消失。这个“恒电平段”在相电压波形上表现为一段干净的水平线,非常容易辨认。如果仿真结果里看不到明显的水平段,多半是调制比设置过高或者k参数映射出了问题。
4.2 线电压与电流波形的差异分析
线电压波形由于零序抵消,六种DPWM之间的差异比相电压小很多。基波分量基本一致,差异主要体现在脉冲位置和脉宽分布上。线电流波形则更平缓,因为电感起到了低通滤波作用,高频开关纹波被滤掉一部分,剩下的谐波以载波频率边带为主。
从电流波形看,DPWMMAX在这个阻感负载工况下的电流畸变最小,DPWMMIN最大,DPWM00到DPWM03介于之间。原因也很直接:本仿真负载功率因数角约56°,电流滞后电压约56°,DPWMMAX的钳位中心对准电压正峰值,正好也落在电流较大的区间,相当于把最耗损的开关动作都避开了,同时电流波形受到的扰动比DPWMMIN小。
这个结果正好印证了理论分析:特定负载功率因数下,钳位位置不同,电流谐波和开关损耗的分配比例显著不同。
4.3 FFT谐波分析:THD和边带分布对比
用脚本批量跑了六种DPWM的FFT分析,线电流THD数据整理如下:
| 调制方式 | 线电流THD | 高次谐波分布特点 |
|---|---|---|
| DPWMMIN | 4.62% | 载波边带能量分散,低次谐波略高 |
| DPWM00 | 3.91% | 边带分布较均匀,接近SVPWM特性 |
| DPWM01 | 3.48% | 边带略集中,2倍载波附近谐波增强 |
| DPWM02 | 3.72% | 3倍载波边带突出 |
| DPWM03 | 4.05% | 低次边带增强,高次边带衰减 |
| DPWMMAX | 3.16% | 边带集中,总谐波最低 |
这个数据只能代表当前负载和开关频率下的情况,换个载波频率或者改变电动机工况,排序可能就变了。我为什么要把这组数据列出来,是想说明:仿真对比的价值不在“选一个最优解”,而在“找到每个方案适合的工况区间”。
比如DPWM01在这里THD不算最低,但如果开关频率只有2kHz,它的边带谐波可能远离某个敏感频段,反而成为最佳选择。谐波分析一定要结合应用场景去看,脱离场景谈THD没有意义。
4.4 开关损耗的定性比较
开关损耗我用统计IGBT开关脉冲个数的方法来近似。一个基波周期内,每相桥臂上下管各导通若干载波周期,钳位区间内开关脉冲消失。统计六种DPWM的脉冲数,DPWMMIN和DPWMMAX的脉冲数最少,约等于标准SPWM的三分之二,中间四种随钳位位置不同在70%到80%之间波动。
如果要做绝对损耗数值对比,需要在IGBT模块里录入开关能量Eon、Eoff和反向恢复能量Erec,并用实际驱动电压电流波形计算。这一步比较复杂,但结论方向不会变:DPWM能显著降低开关损耗,降幅在20%到35%之间,具体看钳位位置和负载功率因数的匹配程度。
还有一点值得注意:DPWM降低的是开关损耗,传导损耗并没有明显变化。对于IGBT这类导通压降较高的器件,如果开关频率很低,传导损耗占主导,DPWM的优势就不明显。这也是为什么DPWM在大功率、低开关频率、损耗敏感场景下更受欢迎。
5. 常见问题与排查技巧实录
做这个仿真前前后后踩了不少坑,有些问题排查过程相当折腾。挑几个典型的记录下来,给后面做类似仿真的朋友省点时间。
5.1 调制波超限与电流畸变
最容易遇到的问题是电流波形明显畸变,甚至出现电流尖峰。检查顺序应该是:先看调制波是否在±1范围内,再看三角载波幅值匹配,最后看M参数是否过大。
我一开始直接把M设成1.1,想看看过调制边界的情况,结果DPWMMAX的调制波长时间饱和在+1,线电流波形出现明显平顶,这就是过调制了。在实际驱动中,过调制会导致电流谐波剧增和电机转矩脉动,除非是做最大电压利用率的极端工况,否则不建议仿真里长时间运行在这个区域。
如果调制波没有超限但电流依然畸变,检查是不是电感太小导致电流断续。RL负载的电感值要保证在最小输出电流下电流连续,可以用L > Vdc/(6·f0·Imin)做初步估算,建议10mH起步。
5.2 仿真速度慢与数据爆炸
模型跑0.1秒要等好几分钟,多半是步长设得太小或者Scope存储点数太多。定步长0.5μs,0.1秒就是20万步,如果连续仿真还会更多,MATLAB会把这20万个点全部存到工作区,内存吃不消。
解决方法是把数据采样率降下来。波形观测用Scope自带的Decimation功能,每10个点取一个显示;To Workspace只存最后2万个点,或者用Data Type Conversion转成单精度。FFT分析需要的数据其实只有最后几个基波周期,完全没必要从头存到尾。
还有一个加速技巧:仿真开始阶段用大步长让电路先进入稳态,比如先用1μs跑0.05秒,再切回0.5μs跑最后0.05秒。仿真结果基本一致,速度能快将近一倍。
5.3 FFT频谱分析时基波频率不对齐
用Powergui的FFT工具时,如果显示出来的基波不在50Hz,或者THD数值跳来跳去,绝大多数情况是分析窗口没有覆盖整数个信号周期。默认窗口是10个周期,如果你改了基波频率没有同步更新分析设置的基频,频谱就会出现泄漏,THD失真。
我的建议是:先把波形存到工作区,用FFT分析前手动取最后完整的几个周期,比如7个周期,然后把FFT窗口设成7个周期。用MATLAB脚本实现更灵活,窗口函数选择Hanning,基频设为50Hz,采样频率按实际采样率填,结果稳定很多。
5.4 六种DPWM波形看起来没有区别
如果切换type参数后,六种调制波形长得几乎一样,先检查是不是k值映射写错了,再检查限幅操作是否把差异抹平了。限幅本身不会抹平差异,但如果调制比太低,比如M=0.5,三相调制波加上零序后距离±1都比较远,钳位区间就不会触发,六种方案自然就没有区别。
这就是为什么前面反复强调M要取0.85到1.0之间的原因,太低看不到不连续现象,太高又过调制。建议第一组仿真M取0.9,把现象看清楚再去调参数。
还有一个小坑:MATLAB Function里如果用了全局变量或者persistent变量,连续切换type时可能不会自动清零上次的中间状态,导致输出延迟。写代码时尽量避免在函数内部用persistent,需要记忆状态的逻辑放到Simulink里的Unit Delay模块里处理。
6. 实际应用中如何选择DPWM变体
仿真最后都会回到一个实际问题:这个结果怎么用。对做逆变器产品或者算法开发的人来说,六种DPWM不是摆着看的,选对了能省下实打实的散热成本。
如果负载功率因数比较固定,比如异步电机在额定点附近运行,功率因数角基本在30°到60°之间,DPWMMAX或者DPWM03这类偏上钳位的方案比较有优势。如果负载变化范围大,从空载到满载功率因数角波动明显,DPWM00这种居中的方案更稳妥,虽然峰值损耗不是最低,但全工况表现最均衡。
如果开关频率本身很高,比如20kHz以上的SiC器件,开关损耗占总损耗比例下降,DPWM带来的收益有限,反而要担心不连续调制引入的低频噪声和电磁干扰。这时候SVPWM可能更合适,并不是所有场景都要上DPWM。
做系统层面的方案对比时,不要只看THD一个指标。建议仿真的同时把以下几个量一起测了:各桥臂的开关脉冲总数、IGBT结温估算值、直流母线电流纹波、输出电流的频谱包络,以及低载波比下的控制影响。DPWM影响的是整个系统层面的性能,而不只是PWM脉冲好不好看。
我个人的体会是,DPWM这类“偏门”调制策略,在传统SPWM和SVPWM教学里着墨不多,但在大功率变频器、风电变流器、轨道交通牵引逆变器这些对损耗敏感的领域,几乎每个项目都会遇到。把六种DPWM从头到尾仿真一遍,不仅把调制算法这个板块彻底打通了,对逆变器损耗模型和负载特性的理解也会深一大截。
最后再分享一个经验:仿真时拿几种方案先跑一个基波周期的调制波,存成图片贴到电脑旁边,调参数时对着图看,比盯着THD数值猜有效得多。波形里的钳位段、脉冲缺口、边带分布这些视觉效果,才是理解DPWM族最直观的入口。