首页 / 资讯中心 / 文章详情

SVPWM算法原理与Simulink仿真全流程详解

SVPWM算法原理与Simulink仿真全流程详解 ★ FEATURED ARTICLE
1. 项目概述1.1 为什么偏偏是SVPWM做过电机控制或者电力电子方向的朋友大概率都绕不开SVPWM这个算法。空间电压矢量脉宽调制英文全称Space Vector Pulse Width Modulation中文圈子习惯直接叫SVPWM或者叫空间矢量调制。它在变频器、伺服驱动器、光伏逆变器、电动汽车电驱控制器里几乎是标配只要是需要三相逆变器驱动交流负载的场合基本都能看到它的身影。我当年第一次接触SVPWM是在做异步电机矢量控制项目的时候导师直接把Simulink模型扔过来说“你把这个跑通把波形调好看就行”。但真正上手才发现光是把模型跑起来不叫会你得理解它为什么好用。SVPWM和传统SPWM正弦脉宽调制最大的区别在于它不是单纯追求三相电压波形接近正弦而是从整体电压矢量的角度出发用六个有效开关状态和两个零矢量来逼近一个旋转的圆形磁链轨迹。这样的做法带来的直接收益有两个一是直流母线电压利用率更高二是电机的电流谐波更小、转矩脉动更低。传统的SPWM直流母线电压利用率最高只有约86.6%也就是相电压峰值最多只能做到母线电压的一半。而SVPWM把线性调制范围拓宽了可以做到相电压峰值为母线电压除以√3相当于把母线利用率提升了15%以上。在电池供电的电动车应用里这15%就意味着在同样电池电压下电机能跑出更高的转速和更大的功率。所以说搞懂SVPWM不只是为了应付仿真作业而是理解现代电机控制底层逻辑的关键一步。这篇文章我就用一次完整的Simulink仿真过程来拆解从算法原理、模型搭建到波形分析、坑点排查争取让第一次接触的人也能照着做出一个跑得通的SVPWM仿真模型。1.2 这套仿真方案解决什么问题我们把目标拆清楚。这次仿真不是做一个孤立的单模块demo而是要搭建一套“从三相给定电压 → 坐标变换 → 扇区判断 → 矢量作用时间 → PWM波形发生 → 逆变器 → 电机负载 → 电流反馈”的完整闭环链路。你可以把它理解为一个微型的电机驱动系统模型只不过我们把核心价值放在SVPWM算法本身。我的做法是分两个阶段第一阶段先做开环的SVPWM发生器验证——给定一个固定的电压矢量和频率观察输出的PWM波形、相电压和相电流是否正常第二阶段再接上异步电机负载看闭环电流响应和转矩波动。这个方案的好处是既能清楚地看到算法每一步的中间结果又不会一开始就被闭环参数和电机模型干扰混淆。实际项目开发中底层算法验证和上层控制逻辑调试本来就是分开的逐层打通可以减少大量的联调返工。从工具选型来说用Simulink做这件事是最合适的。市面上也有用DSP或FPGA做硬件在环验证的方案但在算法验证阶段Simulink的可视化、模块化和快速迭代能力无可替代。尤其是它的Power System Blockset里自带了三相逆变桥和电机模型省去了我们自己搭建功率电路的大量工作。2. 算法原理拆解在仿真之前必须弄懂的三件事2.1 三相电压是怎么变成空间矢量的理解SVPWM的第一个关键点是把三相交流量看成一个旋转的空间矢量而不是三个独立的标量。三相正弦电压的表达式写出来是这样的UA(t) Um·cos(ωt) UB(t) Um·cos(ωt - 120°) UC(t) Um·cos(ωt - 240°)如果我们定义一个空间矢量合成公式Us UA UB·e^(j·120°) UC·e^(j·240°)把这个式子代进去算一步你会发现一个神奇的结果Us的幅值恒定为1.5·Um且它的相角随时间匀速旋转旋转角速度就是电网频率ω。换句话说三相对称正弦电压的“空间合成”在复平面上画出来是一只匀速旋转的矢量。SVPWM的基本思路就是用逆变器的八个基本开关状态六个非零矢量V1-V6两个零矢量V0和V7去合成这个目标旋转矢量。具体怎么合成呢就好比你在平面直角坐标系里要到达某个点可以用水平和垂直两个方向的位移来实现。SVPWM的做法是在一个PWM周期里用目标矢量所在扇区的两个相邻基本矢量和零矢量按不同的时间占比去“拼接”出一个平均效果。这里要注意基本矢量不是连续的它只有六个固定方向、固定大小的离散值。零矢量就是三个上桥臂同时导通或者同时关断的状态它不产生有效电压只是用来填充时间。2.2 扇区判断和合成矢量的选择规则给定目标电压矢量Us之后第一步要判断它在六个扇区中的哪一个。这个判断不用去算角度可以直接通过UA、UB、UC的瞬时值大小来做。工程上常用三个中间变量U1、U2、U3来辅助判断U1 UBB相给定电压 U2 √3·UA - UBA相映射 U3 -√3·UA - UBC相映射然后通过判断这三个量的正负组合来确定扇区号。我在Simulink里是用比较器和逻辑运算做的判断规则如下扇区N的计算可以用一个简单公式N sign(U1) 2·sign(U3) 4·sign(U2)。这里sign是符号函数取1或0。算出来的N值映射到1到6的扇区编号。说白了就是把矢量落在哪个60度区间内这件事转化成了几个简单的符号比较。这样在DSP上实现也非常快不需要调用三角函数。在Simulink里实现的时候建议大家用Fcn模块或者MATLAB Function模块来做输入三个电压瞬时值输出扇区号N。我当时第一次做的时候傻乎乎地用atant2去算矢量的角度再去判断范围虽然结果也对但计算量大多了而且放在后续做实时仿真时会有问题。算法本身追求的就是轻量级、便于在MCU上高频执行。2.3 作用时间计算与七段式发波过程判断了扇区之后就是算两个相邻矢量的作用时间。这里先定义中间变量X、Y、ZX √3·UB·Ts / Ud Y √3·(√3/2·UA 1/2·UB)·Ts / Ud Z √3·(-√3/2·UA 1/2·UB)·Ts / Ud其中Ts是PWM开关周期Ud是直流母线电压。每个扇区的作用时间T1和T2就是从这三个变量里选两个组合出来的。以第一扇区为例T1 ZT2 Y。它们满足的约束是T1 T2 ≤ Ts差值部分用零矢量填充T0 Ts - T1 - T2。这里有个细节很多人写代码时会踩坑T1和T2计算出来之后必须做饱和限幅处理。当电压矢量超过最大线性调制范围时T1 T2会超过Ts如果不限幅输出波形就会直接乱掉。标准做法是把T1和T2按比例缩放T1_adj T1 / (T1 T2) · Ts T2_adj T2 / (T1 T2) · Ts这个过调制处理在实际电机高速运行时经常被触发是SVPWM实现里绝对不能省的一个步骤。发波方式我选择的是七段式也就是在一个开关周期内矢量的顺序是“零矢量 → 有效矢量1 → 有效矢量2 → 零矢量 → 有效矢量2 → 有效矢量1 → 零矢量”并且保证两个零矢量V0和V7都被使用。这样每次开关切换只动一个桥臂开关损耗最小谐波也相对集中。3. Simulink模型的完整搭建从零到能跑3.1 模型的总体架构设计我建的模型分成了六大模块从输入到输出依次是信号源与坐标变换模块负责产生三相正弦给定电压和目标频率并完成三相静止坐标系到两相静止坐标系的变换。SVPWM算法核心模块扇区判断、时间计算、矢量切换最终输出三相桥臂的占空比信号。PWM生成模块把占空比和三角载波比较输出六个开关管的驱动脉冲。三相逆变桥模块Simulink自带的Universal Bridge设置成IGBT或者MOSFET模式。电机负载模块我用的Asynchronous Machine参数按常规的小功率异步电机设置。测量与示波器模块采集电流、电压、转速、转矩等信号。模型搭建的时候有一个建议把每个功能做成一个Subsystem不要把所有逻辑都堆在一个页面里否则后续排查问题会非常痛苦。3.2 坐标变换模块的搭建细节坐标变换这块主要是完成Clark变换。三相定子坐标到两相静止αβ坐标的公式Iα (2/3)·[IA - 0.5·(IB IC)] Iβ (2/3)·[(√3/2)·(IB - IC)]在Simulink里直接用一个Fcn模块就能写也可以用四个Gain和两个Add组合出来。我个人偏好用Fcn模块因为公式块一目了然后期改成其他变换也方便。这里有一个取舍要注意坐标变换的系数。有些教材里Clark变换用的2/3系数有些用的√(2/3)这是功率不变变换和幅值不变变换的差别。在SVPWM算法内部如果只用来做扇区判断和作用时间计算其实系数并不关键因为最后计算时间时系数会对消掉。但如果后续还要做闭环电流控制Park变换和Clark变换的系数必须跟PI调节器的增益匹配不能混着用。我习惯统一用幅值不变变换也就是2/3系数并且整个模型里所有变换保持一致。3.3 SVPWM核心子系统逐模块实现我把SVPWM核心部分拆成了三个子功能块扇区判断、时间计算、占空比生成。扇区判断模块的Simulink实现不复杂把三相电压经过Gain后分别拉三个比较器输出的逻辑组合很直接。需要注意的一点是所有信号的数据类型要保持double不要自动转成boolean否则后面做算术运算时会报维度错误。时间计算模块我用了MATLAB Function因为里面要写多层的条件分支。核心代码如下function [T1, T2] time_calc(ua, ub, uc, Ts, Ud) U1 ub; U2 sqrt(3)*ua - ub; U3 -sqrt(3)*ua - ub;if (U1 0), A 1; else, A 0; end if (U2 0), B 1; else, B 0; end if (U3 0), C 1; else, C 0; end N A 2*B 4*C; X sqrt(3)*ub*Ts/Ud; Y 1.5*ua*Ts/Ud sqrt(3)/2*ub*Ts/Ud; Z -1.5*ua*Ts/Ud sqrt(3)/2*ub*Ts/Ud; switch N case 1 T1 Z; T2 Y; case 2 T1 Y; T2 -X; case 3 T1 -Z; T2 X; case 4 T1 -X; T2 Z; case 5 T1 X; T2 -Y; case 6 T1 -Y; T2 -Z; otherwise T1 0; T2 0; end sumT T1 T2; if sumT Ts T1 T1/sumT*Ts; T2 T2/sumT*Ts; endend要注意MATLAB Function模块默认输入输出是double标量如果给的是向量或者矩阵会报错。所以进这个模块之前一定要确保三个电压是独立的标量信号。占空比生成模块的思路是先算出三相桥臂的切换时刻再用切换时刻生成三角载波比较信号。七段式发波的切换时刻由T1、T2和零矢量时间T0共同决定。以第一扇区为例A、B、C三相上桥臂的导通时间分别为Ta T0/2 Tb T0/2 T1/2 Tc T0/2 T1/2 T2/2其他扇区只是这三路切换时刻的顺序不同。我直接建了一个查找表来处理扇区与切换时刻的对应关系这样比用if-else一层层套要清晰得多。3.4 PWM波形生成与逆变桥连接占空比信号生成之后接下来要让它在每个开关周期里和三角载波做比较。Simulink里的Repeating Sequence模块可以生成三角波设置周期为1/开关频率幅值为Ts也就是周期值方便跟切换时刻直接比较。我用的是比较器切换时刻 载波值输出为1否则输出0。这样就能得到六个IGBT的栅极驱动信号。三相桥臂的上下管是互补的上管导通时下管必须关断所以我把每一个桥臂的PWM取反后送给下管。搭建逆变桥的时候直接从Simulink库中拖Universal Bridge模块设置为三桥臂、开关器件选IGBT母线电压参数为Ud。这里提醒一个常见问题Universal Bridge默认不缓冲母线端如果直接把直流电压源接上去启动瞬间的冲击电流可能会导致仿真发散。建议在直流母线端并联一个较大的电容并且在电源回路串联一个小电阻限流。3.5 电机负载的连接和初始化电机我直接用Asynchronous Machine SI Units模块。配置时最关键就三样额定功率、额定频率、极对数。我做的是一个约3kW的异步电机额定电压380V、频率50Hz、极对数2。电机参数如果不确定就先保持默认模型能跑通再慢慢对参数。电机接口那边要注意逆变桥输出的三相交流直接接电机的三相定子端口电机机械输出端接一个Simulink-PS Converter模块转成物理信号再接一个恒定负载转矩或者带惯量的负载模型。为了保证仿真能快速稳定我把电机初始转差设为接近额定值的状态避免模型一启动就从零开始转差很大的启动过程那样仿真步长会被拉得很小跑得巨慢。4. 关键参数的选择与调试过程4.1 母线电压、开关频率和采样时间的匹配SVPWM的几个关键参数的匹配非常影响仿真结果。我这次用的参数见下直流母线电压Ud取540V模拟典型的三相整流后的母线电压。开关频率选10kHz这是工业变频器比较常用的频率兼顾了开关损耗和电流谐波。PWM采样时间Ts_sample取1e-6秒也就是微秒级用来生成三角载波和进行开关逻辑判断。采样时间设置这里有个常见的取舍如果采样时间太粗比如跟开关周期一样PWM的边沿精度会不足产生的谐波会偏离理论值。如果太细仿真速度又会很慢。1微秒在10kHz的开关周期下相当于每个周期内有100个采样点精度和速度都够用。另外坐标变换、扇区判断这些算法模块的采样时间可以单独设置我统一给的是1e-5秒也就是开关周期的十分之一。这样既能保证算法更新速度足够快又不至于让Simulink把仿真步长都花在这些低延迟模块上。4.2 死区时间的影响和仿真设置实际逆变器里上下桥臂不能同时导通否则会出现直通短路。所以必须加死区时间。在Simulink里仿真时如果只做理想模型死区可以不设但加上死区能更真实地反映硬件工况也有助于观察死区对电流波形的影响。死区时间的设置方式有很多最简单的做法是用On-Off Delay模块设导通延迟为2微秒。我在模型里加上死区后对比了下电流波形加了死区之后电流波形在过零附近会出现轻微的毛刺和畸变这就是真实系统中死区效应的体现。实际做硬件工程时死区还会引起低次谐波和转矩脉动严重时会产生比较明显的振动噪声这个问题在低速轻载时尤其突出。4.3 调制比的边界线性区、过调制区和方波区做SVPWM仿真时调制比这个概念一定要搞清楚。调制比m √3·Um / Ud。当m小于1时工作在线性调制区输出相电压不会失真。当m超过1就进入过调制区这时T1与T2之和会超过Ts不加以处理就会导致输出畸变。我们的限幅处理其实从某种程度来说就是弱化过调制影响的尝试即在高调制比下仍可以保持基波幅值保持不变、只是波形会发生一定变形。我在仿真里特意把给定电压幅值加大触发限幅逻辑观察到了相电压波形出现明显顶削平的现象。这个现象在理论上就是过调制区的典型特征——一方面基波达到了最大可输出值另一方面输出波形里会出现更多的高次谐波。在实际项目中正常调速都会把调制比控制在1以下但在弱磁高速段经常会迫不得已运行在过调制区这时就要评估谐波对电机温升和噪声的影响是个很典型的工程权衡问题。5. 仿真结果验证怎么看波形判断算法对没对5.1 开环测试从PWM波形反推矢量轨迹仿真第一步我先给一个固定的给定电压矢量幅值60V频率25Hz不接电机只接一个阻感负载先把开环波形看明白。第一个观察点是三相桥臂的PWM脉冲。展开后能看到10kHz的载波周期里占空比在缓慢变化而且三相占空比的变化是互相关联的——桥臂A的开关切换点变化规律对应的是A相输出电压在基波周期内的变化而桥臂B和C则分别滞后120°和240°。第二个观察点是相电压波形这个要看滤波后的值而不是直接看PWM脉冲。接上负载后相电压是阶梯状的PWM波形舍去开关纹波看平均电压可以看出它接近正弦。用示波器里的FFT工具看一下频谱基波分量非常清晰谐波主要分布在载波频率及其倍数附近。第三个观察点更关键——线电压。SVPWM输出线电压波形是标准的马鞍波中间部分呈现凹陷这正是SVPWM名字里“叠加零序分量”的特征。很多人第一次看到马鞍波会以为波形错了恰恰相反这恰恰说明算法正确地注入了零序分量直流母线利用率才因此提高。5.2 闭环测试带电机后的动态响应开环没问题的前提下我把三相阻感负载换成异步电机给定电压频率调到接近电机的额定同步转速观察稳态电流和电磁转矩。正常情况下的电流波形是三相对称的幅值平稳谐波小转矩波形是一条基线上叠加微小脉动脉动频率在6倍基波频率附近。当我把开关频率降到2kHz时电流谐波明显变大转矩脉动也随之增加。这验证了开关频率对系统性能的影响规律——频率越高谐波越小但开关损耗也越大。这里有一个点分享给第一次跑闭环的人接上电机后电机初始状态如果不对电流很容易爆表。国产的Simulink教材、论文里你看到的理想波形往往都是大量初始化和参数调节后的结果。我在模型里给电机设置了合适的初始转差和零初始电流才避免了启动瞬间的巨大冲击仿真才有机会进入稳态。5.3 潜在性能指标谐波分析工具的使用波形“看起来像正弦”是不够的一定要量化分析。Simulink的powergui模块里提供FFT分析工具可以对录波数据做谐波分析。我测量了A相电流的总谐波畸变率THD。在线性调制区10kHz开关频率下THD大约在3%到5%之间这个水平与工业变频器的标称值基本一致。然后把死区效应加上、或者在过调制区延长运行THD会升高到10%以上输出的基波幅值基本不再上涨但谐波却在猛增。我截取了不同工况下的FFT谱线做了个对照表在哪里能看到经典的边带谐波、哪些谐波分量是死区效应的标志一清二楚。用FFT分析工具来判断算法的好坏可以说比“看波形顺眼”可靠得多它能把谐波水平变成数字这才是写技术报告和做方案论证的素材。6. 常见坑点与调试经验分享6.1 仿真报错发散先查代数环和步长新手跑SVPWM模型最常遇到的就是仿真报错或者数值发散报错信息通常是“Solver failed”或者“Algebraic loop detected”。出现代数环的原因一般是信号从SVPWM模块输出到坐标变换再回到输入形成了没有延迟的循环依赖。解决办法有三种一是把负责算法更新的模块采样时间设置成离散比如1e-5秒打破连续求解器的迭代环二是给反馈信号加一个单位延迟单元人为制造一拍延迟三是换用离散求解器如Fixed-step discrete solvers跑仿真。我一开始踩过这个坑模型的SVPWM输出占空比又反馈给了电机电流控制完全没意识到形成了代数环报错后我用了第二种方法在反馈通路里加了个Unit Delay问题直接就解决了。6.2 占空比莫名超过1或者变成负数如果你发现示波器里占空比信号超过了0到1的范围大概率是前面的坐标变换系数或者限幅环节没做好。占空比超过1会导致PWM输出一直是导通相电压就无法跟随给定值直接出现畸变。排查思路很简单在SVPWM核心模块的三个关键输出T1、T2、切换时刻分别挂示波器看它们是怎么失去约束的。我实际测试时发现扇区边界附近如果采样点没有对齐切换时刻的计算会出现微小跳变加一个单步延迟就能解决。不过根子上的做法还是确保限幅条件永远先于逻辑计算即在MATLAB Function内部完成所有约束。6.3 仿真速度太慢分清计算瓶颈和采样瓶颈仿真速度慢是高频PWM仿真的通病。10kHz的载波加上1微秒的采样时间对一个好几秒的电机启动过程来说可能要跑上大半个小时实在浪费时间。提速的经验有三点第一是尽量用变步长求解器配合容差设置在“电机快速暂态阶段尽量准确、稳态阶段自动放大步长”之间取得平衡。第二是电源端和电机机械端不要用物理模型把每一个元件都建得过于细致电气元件能简化就简化。第三是在波形录波时不要把数据点无脑全都存下来设置合理的抽样率最后分析时再用插值把关心的频段补回来。6.4 用示波器还原真实性录波之后的数据处理很多人在Simulink里做仿真只用Scope看一眼波形就结束了。但实际用于实验对比的时候需要的不是屏幕截图而是离散波形数据。用To Workspace模块把关心的信号存到工作区再在MATLAB里统一做后处理效率会高不少。我通常会存这几个信号三相电流、相电压、转速、电磁转矩、PWM触发脉冲。利用MATLAB的脚本可以把它们统一绘制成“仿真结果报告”的图档包括FFT分析、波形拟合误差等。这样以后论文或者技术方案里需要写仿真论证的时候所有素材都能直接从脚本一键生成不用再回到模型里重新截图。7. 最后想强调的几个实战细节做了这么多次SVPWM仿真我自己最深的一条体会是跟算法本身相比容易出问题的地方都在模型的衔接和参数的匹配上。坐标变换系数的统一、离散采样步长的匹配、限幅逻辑和过调制处理的优先级——这些细节才是区分新手和老手的分水岭。如果你只是想“跑通一个demo”照着别人的模型改一改就行但如果想把SVPWM用到实际项目里上述每一个细节都可能影响系统在边界工况下的表现。另外建议有条件的朋友可以把这个模型跟硬件验证结合起来。Simulink模型通过代码生成工具比如Embedded Coder转成C代码下到MCU里与真实的逆变器和电机驱动平台做对照。仿真阶段发现不了的问题比如ADC采样延时、中断优先级对时间精度的影响在硬件联调时会暴露但有了扎实的仿真经验和参数依据调试起来相对会有的放矢得多。
阅读完成 · 觉得有帮助?
咨询建站