
做 MMC 仿真的人十有八九都会卡在同一个坎上模型搭起来很快跑起来全是问题——波形发散、电容电压乱跳、桥臂电流畸形、仿真速度慢得离谱。我最近刚好把 N22 的模块化多电平换流器MMC在 Matlab/Simulink 里完整搭了一遍调制策略用的最近电平逼近NLM从参数计算、模型搭建到调参排错走了一整轮这里把能直接复用的经验整理出来。这个配置很典型N22 在学术研究和工程预研里都很常见既保留了多电平的波形质量优势又不会像 N200 那样把仿真器拖垮。这篇文章适合正在做课程设计、毕业论文或者刚接触柔直/变频方向、准备用 Simulink 验证控制算法的同学参考我尽量把每一步为什么这么做讲清楚。1. 方案选型为什么是 N22为什么用最近电平逼近1.1 NLM 与载波移相法的取舍MMC 的调制策略主流有两大类载波移相正弦脉宽调制CPS-SPWM和最近电平逼近调制NLM。很多人一上来就纠结选哪个我的建议很直接子模块数量 N 比较小比如 N≤10时CPS-SPWM 的优势明显因为能保住较高的等效开关频率波形谐波好但 N 到了 22 这个量级再用 CPS-SPWM 就有点自找麻烦了。为什么CPS-SPWM 每个子模块都需要一路三角载波N22 意味着每个桥臂 22 路载波三相六个桥臂就是 132 路载波相位要精确错开调制波要逐一比较模型里光载波生成和比较器就是一大片仿真步长稍大一点波形就失真。更关键的是CPS-SPWM 下每个子模块开关管都在高频动作仿真计算量非常大而且实际工程中这么高的开关损耗也不划算。NLM 的逻辑非常朴素参考电压是多少就投入最接近的那个电平数对应的子模块数量。每个桥臂需要投入的子模块个数 n 可以写为n round(u_ref / u_c)其中 u_ref 是当前时刻的参考电压u_c 是单个子模块电容电压的实时平均值或额定值。NLM 不需要三角载波不需要复杂比较器核心就是一个取整函数加一个限幅实现成本极低。在 N22 时输出相电压可以形成 23 个电平的阶梯波谐波含量已经相当可观完全够用。所以我的结论是N 一旦超过 10优先考虑 NLMN 到 22 这个量级NLM 基本是唯一合理选择。这也是现实中模块化多电平换流器工程普遍采用 NLM 的原因。1.2 子模块数量 N 对仿真的实际影响N 的取值直接决定了系统设计的好几个关键指标。首先单个子模块电容电压额定值由直流母线电压和 N 共同决定u_c U_dc / N如果直流母线电压是 20kVN22那么每个子模块电容电压额定值大约是 909V。N 越大单个模块电压应力越低对功率器件耐压要求越宽松但子模块数量增加会带来控制复杂度和成本上升。N22 是一个性价比很高的折中。从仿真角度看N22 的模型规模是三相六桥臂每个桥臂 22 个子模块总共 132 个半桥子模块。如果你用最详细的 IGBT 器件级模型去搭每个子模块里俩 IGBT、俩二极管、一个电容再带上开关动作的数值求解仿真会慢到怀疑人生。所以我后面会讲一套工程上常用的等效建模方法把开关动作抽象成理想的受控源把电容电压用积分器等效只保留控制层面的动态特性。这样既保留 MMC 的外特性又能让仿真跑得动。2. 调制与均压NLM 的原理、参数含义与工程实现2.1 最近电平逼近的数学本质最近电平逼近这个名字听起来高大上实际上就是一个“四舍五入”的问题。MMC 每个桥臂有一串子模块每个子模块要么旁路输出 0要么投入输出电容电压 u_c。桥臂能输出的电压是离散的只能取 0、u_c、2u_c、3u_c……也就是 N×u_c 这些台阶。而控制系统给出的参考电压是一个连续变化的正弦量我们需要在每个控制周期里找一个离参考值最近的台阶这就是最近电平逼近。用公式表达n_ref round(u_ref / u_c_avg)n_on max(0, min(N, n_ref))其中 u_c_avg 是当前桥臂所有子模块电容电压的平均值。这里有一个细节很多人会忽略u_c_avg 究竟用实时平均值还是额定值我建议用实时平均值。因为电容电压在运行中会有波动如果一直用额定值做除法参考值靠近峰值时可能会出现投入子模块数计算偏差导致输出电压台阶不平整。用实时平均值做归一化等效于把电容电压波动的影响从调制环节中隔离出去波形更干净。还有一个细节是取整方式。Simulink 里直接调用 round 函数即可但要注意 round 在 Simulink 的 MATLAB Function 块里是四舍五入不是向上取整也不是向下取整。最近电平逼近的关键就在这个“最近”上不建议用 floor 或 ceil否则输出电压会系统性偏低或偏高产生恒定偏差在闭环控制里会变成稳态误差。2.2 排序均压算法的 Simulink 实现技巧NLM 本身很简单真正决定 MMC 能不能稳定运行的是子模块电容电压均衡。因为每个子模块的电容参数不可能完全一致充放电时间也不一样如果不加均压控制各电容电压会逐渐发散有的模块电压飙升有的模块电压跌落最后损坏器件。经典的排序均压算法思路是每个控制周期对所有子模块电容电压排序根据当前桥臂电流的方向决定怎么投入。如果桥臂电流为正值说明电流在给电容充电那就优先投入电容电压最低的 n 个子模块让低电压模块多充电如果桥臂电流为负值说明电流在给电容放电那就优先投入电容电压最高的 n 个子模块让高电压模块多放电。用这样的规则电容电压会被拉向平均值。这个算法写出来非常简单排序用 sort 函数即可function [pulses, order] sorting_balancing(u_c_vec, n_on, i_arm) % u_c_vec: 当前桥臂N个子模块电容电压向量 % n_on: 需要投入的子模块个数 % i_arm: 桥臂电流正为充电方向 % pulses: 输出投切信号1表示投入0表示旁路 N length(u_c_vec); [~, idx] sort(u_c_vec); % 默认升序排列 pulses zeros(N, 1); if i_arm 0 % 充电投入电压最低的n_on个 pulses(idx(1:n_on)) 1; else % 放电投入电压最高的n_on个 pulses(idx(N-n_on1:N)) 1; end end这段代码在 Simulink 里放进 MATLAB Function 块就能跑。但有几个性能坑要提醒第一如果每个仿真步长都执行一次全局排序仿真速度会明显变慢。N22 时每个桥臂才 22 个数排序开销还不算大但如果你以后扩展到 N100 以上就必须优化。常见做法是加一个触发条件只有在参考电压变化超过一个电平或者每隔固定步数才执行排序。我在 N22 的模型里用了 PID 采样时间控制排序频率仿真速度快了将近一倍电容电压波动并没有明显恶化。第二排序均压会导致子模块开关频率偏高因为每次排序后投入组合都可能在变。为了降低开关频率可以在排序时加入滞环电压差小于一定阈值时保持原来的投切状态不变。这个技巧在做损耗分析时非常有用。第三MATLAB Function 块内的代码要注意变量初始化。很多人第一次跑就报“Output argument pulses not assigned”的错误就是因为 if/else 分支没有覆盖所有情况或者排序索引越界。建议在代码开头先把 pulses 全部置 0再根据条件修改。3. 从零搭一个 N22 的 MMC 仿真参数计算与建模步骤3.1 主电路参数计算含算例在动手搭模型之前先把参数算清楚。我以一个 10kV/5MVA 的交流系统为例直流母线电压 U_dc 取 20kV子模块数 N22。所有计算逻辑可以复用到你自己的工况只要替换电压和容量即可。第一步子模块电容电压额定值u_c U_dc / N 20000 / 22 ≈ 909 V第二步桥臂额定电流。MMC 的桥臂电流由两部分构成一部分是交流输出电流的一半另一部分是直流电流的三分之一。交流线电流有效值I_line S / (√3 × U_ac) 5e6 / (1.732 × 10e3) ≈ 288.7 A交流电流峰值约 408A桥臂电流里交流分量大约是峰值的一半也就是 204A 左右。直流电流I_dc P / U_dc 5e6 / 20000 250 A桥臂电流里直流分量是 I_dc / 3 ≈ 83A。两者叠加桥臂电流额定值大概在 230A 上下再加一点环流裕量可以取 250A 作为设计值。第三步子模块电容取值。工程上常用时间常数法C 2 × H × I_arm / u_c其中 H 是时间常数一般取 30ms 到 40ms。取 H35ms 的话C 2 × 0.035 × 250 / 909 ≈ 0.0193 F ≈ 19.3 mF这个电容值可以在仿真里先跑一版观察电容电压波动幅度。如果波动超过额定值的 ±10%就需要增大电容如果波动很小说明电容有余量可以适当减小以降低成本。第四步桥臂电抗。桥臂电抗的作用是限制环流和故障电流经验取值在 0.1 到 0.2 p.u. 之间。按 0.15 p.u. 计算L 0.15 × U_dc² / (2 × ω × S) 0.15 × 400e6 / (2 × 314.16 × 5e6) ≈ 19 mH这四个参数算完主电路基本就定了。这里特别提醒参数计算不是一锤子买卖仿真里观察到的波形会反过来要求你调整电容和电感先按公式算出一个基准再微调这是正常流程。3.2 系统级建模三相结构、信号路由与调制模块Simulink 模型的整体结构我建议分成四层主电路层、控制层、调制层、观测层。主电路层包括直流源、六个桥臂每相上桥臂和下桥臂、每桥臂的 22 个子模块等效电路、桥臂电感和交流负载。控制层负责生成三相参考电压最简单的开环控制就是直接给三相正弦参考闭环的话就加电压/电流环。调制层把参考电压换算成每个桥臂的投入子模块数再结合排序均压生成 132 路投切信号。观测层接 Scope 或 Data Inspector 看波形。子模块等效电路是仿真提速的关键。不要用 Simscape 里的 IGBT 器件去一个个搭正确做法是每个子模块建模成一个受控电压源输出侧和一个受控电流源电容侧投切信号直接控制这两个受控源的增益。电容侧电容电流 i_c i_arm × S_investS_invest 是投切状态1 投入0 旁路电容电压通过积分器积分得到输出侧子模块输出电压 u_sm u_c × S_invest。这样每个子模块在数学模型里只占一个积分器和两个乘法器132 个子模块算下来计算量也很小。我在实际测试里同样的参数和工况详细器件模型的仿真速度大约是等效模型的 1/20 到 1/30。做控制算法验证、参数优化、故障分析等效模型完全够用没必要用器件级模型折磨自己。桥臂之间的信号路由也要注意。每个桥臂输出的投切信号是 22 维向量电容电压也是 22 维向量这些信号在 Simulink 里建议直接用 Mux 或 Bus 组织成向量不要一根线一根线地连。排序均压模块放在每个桥臂内部输入是电容电压向量、投入子模块个数、桥臂电流输出是投切向量。这样封装好之后六个桥臂的子系统结构完全一致复制粘贴就能搭出三相改参数也只需要改桥臂内部的常量。3.3 启动策略预充电与解锁过程很多人搭完模型直接给方波或正弦参考一跑结果波形惨不忍睹电容电压直接崩掉。原因很可能是没有做预充电。MMC 启动时所有子模块电容电压都是零如果直接解锁投入冲击电流会非常大电容电压根本稳不住。标准的启动流程分两步。第一步是不解锁控制让所有子模块处于旁路状态通过直流电源经限流电阻给电容充电直到电容电压接近额定值。这个过程在仿真里可以用一个 Simulink Signal Builder 或 Step 模块控制接触器完成先串入限流电阻充电电容电压到达额定值后切除限流电阻。第二步再解锁调制和均压控制参考电压从零开始缓慢增大给定一个斜坡而不是阶跃让系统平滑过渡到稳态。我在实际仿真中发现N22 时预充电时间大约需要 0.1 到 0.2 秒取决于电容大小和限流电阻如果跳过预充电直接跑初始阶段桥臂电流会出现几十倍额定值的尖峰虽然仿真不至于崩但后面的动态过程会失真。4. 仿真提速与常见问题排查4.1 仿真速度慢的优化手段N22、132 个子模块的模型如果不做优化仿真推进会非常糟心。我总结了三层提速手段按性价比排序。第一层求解器设置。默认的变步长连续求解器在开关动作频繁时会不断缩小步长非常慢。如果控制算法是离散的建议把整个模型改成离散定步长步长取 20 微秒到 50 微秒。20 微秒对应 50kHz 采样率对于 50Hz 基波、NLM 调制等效开关频率本来就不高来说绰绰有余。改成离散定步长之后仿真速度可以提升好几倍。第二层等效模型。前面提到的受控源等效子模块已经是底线了不要用器件级模型。第三层降低排序频率。排序均压算法不一定要每个步长都跑可以每 10 个步长排序一次。N22 时排序本身不慢但这种习惯对以后扩展到更大 N 有好处。还有一个容易忽略的点Scope 模块不要放太多。Scope 本身不影响仿真主流程但如果开了大量数据记录尤其是把所有 132 路投切信号都送到 Scope 里内存和显示开销会让仿真明显变卡。我的做法是只观测关键的聚合量三相输出电压、桥臂电流、某个桥臂的电容电压向量、投入子模块个数需要看详细投切状态时再临时加 Scope。4.2 波形分析与电容电压波动问题定位模型跑起来之后第一件事是看三个波形输出相电压、桥臂电流、电容电压。输出相电压应该是 23 电平的阶梯正弦波。如果看到电平数不对先检查投入子模块个数有没有被限幅在 0 到 N 之间很多时候是 round 之后没做限幅或者 u_c_avg 传错了信号维度。如果电平做了但波形不对称检查上桥臂和下桥臂的参考电压是不是互补关系MMC 每相上桥臂和下桥臂的参考电压相位应该差 180 度且两者之和等于直流母线电压。电容电压波形应该是围绕额定值的小幅脉动脉动频率是二倍基波频率100Hz波动幅度在额定值的 5% 到 10% 之间属于正常。如果电压发散或整体漂移优先检查排序均压算法的方向对不对充电时投入低压模块放电时投入高压模块如果方向反了电容电压会越拉越偏。我调试时在排序模块里加了一个变量输出当前投入模块的电压平均值一眼就能看出均压逻辑是否在起作用。电容电压波动幅度过大的原因通常有三个电容值太小、桥臂电流过大、缺少环流抑制。前两个通过参数调整解决第三个需要单独说说。4.3 二倍频环流的来源与抑制MMC 运行中上桥臂和下桥臂的瞬时电压之和并不严格等于直流母线电压差值会在三相桥臂之间形成环流频率主要是二倍频100Hz。环流本身不体现在交流侧但它会增加桥臂电流有效值加剧电容电压波动还可能让桥臂电抗饱和。如果仿真里发现桥臂电流波形里有明显的 100Hz 正弦分量且三相之间相互流通这就是环流。抑制方法有两类。一是被动抑制增大桥臂电抗简单有效但会拖慢动态响应。二是主动抑制在控制系统里加一个二倍频负序环流抑制器常用的方案是 dq 坐标系下的 PI 控制器或静止坐标系下的 PR 控制器。检测三相环流在二倍频 dq 旋转坐标系下做控制输出补偿电压叠加到参考波上。对于 N22 的仿真验证我建议先加大桥臂电抗把环流压住把整个系统跑稳定了再决定要不要加主动环流抑制。一开始就上复杂的环流抑制环出了问题很难分清是调制的问题还是环流控制的问题。4.4 谐波评估与 THD 改善NLM 的输出波形是阶梯波谐波特性跟电平数直接相关。N22 时输出 23 电平THD 一般在 3% 到 5% 之间具体取决于调制比和电容电压波动。想看谐波成分在 Simulink 里可以直接用 Powergui 的 FFT Analysis或者把波形数据导到 MATLAB 工作区用 fft 函数分析。FFT 分析时会发现一个规律NLM 的谐波主要集中在中低频段不像 PWM 那样有明确的高次载波边带。电平数越大最低次谐波的次数越高幅值越小。如果 N22 的 THD 不满足要求最直接的办法是增大 N但在仿真里如果 N 已经被限定那就只能通过控制手段改善一是在调制波里注入合适的三次谐波零序分量提高调制比利用率二是优化电容电压波动幅度因为电容电压波动会直接耦合到输出电压里形成低频谐波。另外提醒一句FFT 分析时要注意加窗和采样点数直接取一个周期做 FFT 会有频谱泄漏。我习惯的做法是取 10 个周期的数据用汉宁窗再把结果换算到基波有效值归一化这样算出来的 THD 比较准。很多人仿真波形看着挺好一算 THD 数值偏大往往就是分析窗口和窗函数设置的问题。5. 从一次真实调试经历谈几个容易踩的坑最后分享一次印象比较深的调试经历。模型搭好之后第一次跑输出电压阶梯波出来了但电容电压以肉眼可见的速度往下掉掉到额定值的一半左右才稳住而且桥臂电流波形严重畸变。排查了很久最后发现是限幅条件写错了我把投入子模块个数的上限写成了 N-1导致每个桥臂永远少投入一个模块直流电压无法完全建立。这个错误很隐蔽因为在开环状态下交流输出波形看起来没问题只有看直流侧电压和电容电压平均值时才能发现。从那以后我每次跑仿真都会先看几个关键的平均值指标直流母线电压、各桥臂电容电压平均值、调制波和实际输出电压的偏差。这四个量能快速判断模型是“大体正确”还是“看似正确但暗藏问题”。还有一次模型一启动就报“Matrix dimension must agree”错误查了半天发现是电容电压向量的维度在某个信号路由处被截断成了 21 维因为有个 Mux 模块少接了一路信号。这个问题的教训是N22 的模型里所有跟子模块相关的向量信号维度必须是 22建议在调试阶段把关键信号的维度用 Display 模块显示出来一眼就能看出哪里断了。N22 的 MMC 仿真模型在我个人看来是整个模块化多电平技术里性价比最高的一个试验台。它比 N5、N11 那种低电平模型更贴近工程实际谐波和均压特性都有代表性又不像 N100 以上那样对仿真资源有苛刻要求。跑通这个模型之后往高压大容量方向扩展、换成全桥子模块、加环流抑制、做故障穿越都是在同一套框架上做增量修改。希望这篇经验整理能帮你少走几步弯路。