把电路仿真写成可重复的软件
以一份 Simscape 全桥模型为例:参数化建模、端口级连线、稳态截取与自动判定,如何组成一条可以重复运行的验证管线。
很多仿真项目最后只留下一个能打开的模型文件。它说明“某次跑通过”,却很难回答三个软件工程问题:换一组参数还能不能重建?仿真结果由什么规则判定?半年后谁能复现这次结论?
这次实践把模型本身当成脚本的构建产物。一份 MATLAB 程序负责创建 Simscape 网络、生成控制时序、执行编译与仿真、提取稳态窗口,最后输出机器可读的数据和 PASS / FAIL。电路是被验证的对象,重点是围绕它建立的自动化软件。
本文使用 400 V → 14 V、3 kW 的公开教学算例,只说明建模与验证方法,不对应任何实际产品。结果来自 MATLAB R2026a Update 4 的已完成运行。
一条从输入到证据的管线
- 01输入参数经过校核的算例与控制时序
- 02模型生成程序创建模块并连接物理端口
- 03编译门禁update 提前拦截端口与网络错误
- 04瞬态仿真运行 2 ms 物理开关模型
- 05稳态截取仅分析最后 20 个开关周期
- 06断言与证据理论对照 → CSV · MAT · PNG · LOG
这条管线把“搭模型”和“看波形”拆成了可以检查的阶段。物理端口接错会在编译门禁停止;仿真虽然完成但指标越界,会在断言阶段失败;只有两关都通过,结果才有资格进入基线。
参数层:让设计点成为显式输入
脚本开头集中保存设计点和第一层非理想参数。拓扑图不再承担“藏参数”的职责,任何改动都可以被代码审查和版本比较。
| 输入 | 值 | 在软件中的角色 |
|---|---|---|
| VH | 400 V | 母线与理论值输入 |
| fsw | 100 kHz | 时序与采样窗口基准 |
| Df | 0.28 | 每组对角桥占空比 |
| Np : Ns_half | 16 : 1 | 增益模型与模块参数换算 |
| Lout / Cout | 2 µH / 2 mF | 稳态均值与纹波计算 |
其中有一个容易被软件掩盖的接口细节:Center-Tapped Transformer 模块的参数是“原边 / 整个副边”,所以模块中写入 8,而不是 16;中心抽头设为 0.5 后,每半副边才是目标的 16:1。把这个换算写成表达式,比在图形界面里手填一个数字更不容易失去语义。
Np = 16;
Ns_half = 1;
nHalf = Ns_half / Np;
% Simscape 模块使用原边 / 整个副边
turnsRatioPrimaryToTotalSecondary = Np / (2 * Ns_half);
建模层:用函数封装重复动作
程序化模型最容易变成一长串脆弱的坐标和端口编号。这里没有试图隐藏 Simulink API,而是只封装两个高频、容易写错的动作:创建同规格 MOSFET,以及通过端口句柄连接 conserving ports。
function connect_ports(model, srcBlock, srcType, srcIndex, ...
dstBlock, dstType, dstIndex)
srcHandles = get_param([model '/' srcBlock], 'PortHandles');
dstHandles = get_param([model '/' dstBlock], 'PortHandles');
add_line(model, ...
srcHandles.(srcType)(srcIndex), ...
dstHandles.(dstType)(dstIndex), ...
'autorouting', 'on');
end
这层抽象很薄,却带来两个好处:连线语句仍然能读出源、目标和端口类型;R2026a 中模块库路径、器件参数或端口位置发生变化时,也有集中检查的位置。
脚本最终创建高压桥、隔直电容、中心抽头变压器、同步整流与箝位支路,并同时加入传感器、物理信号转换和 To Workspace 数据出口。模型不是孤立的“电路画布”,而是一个自带观测接口的软件测试夹具。
控制层:时序也必须可以被验证
控制信号没有停留在四个 Pulse Generator 的参数里。桥臂 A 驱动 S1 / S4,桥臂 B 驱动 S2 / S3,并相差半个周期;S6、S7 分别取两组桥信号的反相。S5、S8 箝位脉冲延迟 0.20 µs、持续 2.20 µs,被约束在各自传能区间内。
门极检查使用离散逻辑乘积。两组主桥同时为高,或箝位脉冲跑到所属传能区间之外,都会让 passGates 失败。
gateOverlapPrimary = max(gA(steadyMask) .* gB(steadyMask));
gateOverlapClampA = max(gS5(steadyMask) .* (1 - gA(steadyMask)));
gateOverlapClampB = max(gS8(steadyMask) .* (1 - gB(steadyMask)));
passGates = gateOverlapPrimary < 0.5 ...
&& gateOverlapClampA < 0.5 ...
&& gateOverlapClampB < 0.5;
这不是 MCU 量产固件的死区实现,但它建立了同样重要的习惯:控制时序既是驱动输入,也是测试数据。
验证层:先编译,再只看稳态
脚本保存模型后先执行 SimulationCommand = update。这相当于第一道静态门禁:物理域、端口或参数错误在昂贵的瞬态仿真之前暴露。
第二个关键点是分析窗口。仿真运行 2 ms,但统计仅使用最后 20 个 100 kHz 周期。首轮短窗口曾被开环 LC 启动振荡污染;如果直接对全程求峰峰值,会把启动过程误判成稳态纹波。
steadyMask = t >= (tStop - steadyPeriods * Tsw);
voMean = mean(vo(steadyMask));
iLRipplePP = max(iLData(steadyMask)) - min(iLData(steadyMask));
vClampMean = mean(vClampData(steadyMask));
判据来自同一组输入参数,而不是手工从截图中读数:
voTheory = 2 * Df * nHalf * VH;
vClampTheory = 2 * nHalf * VH;
iLRippleTheory = (nHalf * VH - voTheory) * Df / (Lout * fsw);
passOutput = abs(outputErrorPct) < 8;
passClamp = abs(clampErrorPct) < 8;
passRipple = abs(iLRipplePP - iLRippleTheory) ...
/ iLRippleTheory < 0.20;
这些阈值是当前 V1 基线的回归门槛,不是器件或产品指标。它们的作用是:脚本、模型或参数被修改后,明显偏离能够自动暴露。
一次可追溯的结果
除图片外,同一次运行还输出 summary.csv、waveforms.csv、results.mat 和 build_log.txt。CSV 适合版本间比较,MAT 保留完整时序数据,PNG 用于快速审阅,日志则留下重建过程。不同读者可以使用同一份运行证据,而不必反复打开模型点 Scope。
边界必须和 PASS 一起保存
当前模型的变压器采用 Ideal 模式。它能够验证拓扑增益、同步整流与箝位时序、稳态均值、纹波数量级和门极互锁,但不能据此定量宣称漏感—Coss 振铃、反向恢复、ZVS 窗口、磁芯损耗或 PCB 寄生尖峰已经得到验证;反向预充控制也没有进入 V1。
这条边界不是附注,而是验证软件的一部分。下一步若加入漏感、励磁电感、Coss、Qrr 和死区,应复制成新的非理想模型层级,并保留当前基线。这样当结果变化时,能够区分“拓扑或控制被改坏了”和“新增物理效应改变了波形”。
把仿真写成软件,真正得到的并不只是一份 .slx。更重要的是一条可重建、可审查、可失败、也能明确说出能力边界的工程证据链。