开关电源知识库

40_仿真验证 03 —— LTspice 实战:Buck 纹波比对与仿真纪律

本篇回答的问题:LTspice 怎么在命令行下跑?纹波公式的理论值和仿真值差多少?wine 环境下跑 LTspice 有什么陷阱?

实测声明:本篇所有数据为 2026-10-01 在本机实测所得。LTspice 安装于 wine(/home/sam/.wine/drive_c/Program Files/ADI/LTspice/LTspice.exe),通过 -b batch 模式驱动。全部原始数据(.raw 文件)保留在 /tmp/ltspice/。

与库内的关系:纹波公式出自 01_开关电源基础概念 §3(CCM 电感纹波);buck 拓扑是反激的“非隔离版”(去掉变压器后同一套伏秒平衡);仿真纪律与工具矩阵见 07_开源仿真与设计工具。


本篇总结

  1. LTspice batch 模式可用:wine LTspice.exe -b "Z:\tmp\xxx.cir" 即可在命令行下运行仿真并产出 .raw 文件(无需打开 GUI)。
  2. 纹波公式比对:理论 ΔI_L = Vout(1−D)/(Lf) = 1.32 A,ngspice 实测 1.371 A(偏差 +3.8%)——偏差来源是二极管压降和开关 Ron 的二阶效应,属正常精度。
  3. 伏秒平衡比对:理论 Vout ≈ Vin×D−压降 ≈ 4.88 V,实测 4.72 V(偏差 −3.3%,同一组非理想因素)。
  4. wine 下 .tran 开关电路有数值稳定性问题:相同的 buck 电路,LTspice(wine) 在开关级瞬态产生指数发散(ΔI_L 达 10¹⁰ A),而 ngspice(原生 Linux)同一电路完美收敛——这是 wine 浮点/字体处理与 LTspice 求解器交互的兼容性问题,不是电路错误。
  5. 操作纪律:wine 下 LTspice 推荐只跑 .ac 线性分析(数值稳定);.tran 开关电路改用 ngspice 或 GeckoCIRCUITS;用 .options method=gear + snubber 电容可以改善但不可靠。
  6. 输出解析:.raw 文件头部为 UTF-16LE 编码(不是 ASCII),变量名在 Variables: 段的 \t数字\t名称\t类型 行中;数据段格式由 Flags: 行决定(real=float32,double=float64)。

1. Buck 电路与 netlist

1.1 电路

12V→5V/2A buck 变换器,100kHz,22µH 电感:

Vin(12V) ── [S1 开关] ── sw ── [L1 22µH] ── vout ── [RL 2.5Ω] ── GND
                              │                    │
                            [D1 二极管]          [Cout 470µF+ESR 30mΩ]
                              │                    │
                             GND ──────────────── GND
栅驱动: pg 脚,PULSE 0→5V,f=100kHz,D=0.417

1.2 ngspice netlist(推荐,原生 Linux)

* Buck: 12V->5V/2A @ 100kHz
V1 vin 0 DC 12
Vgate pg 0 PULSE(0 5 0 20n 20n 4.17u 10u)
S1 vin sw pg 0 SMOD
.model SMOD SW(Ron=10m Roff=1Meg Vt=2.5 Vh=0.1)
D1 0 sw DMOD
.model DMOD D(Is=1u Rs=20m)
L1 sw vint 22u
Resr vint vout 30m
Cout vout 0 470u
RL vout 0 2.5
.tran 0.1u 10m 5m 0.1u
.end

注意:ngspice 不支持 LTspice 的 Rser= 参数——ESR 须拆为独立电阻 Resr。

1.3 运行命令

# ngspice(原生,推荐 .tran)
ngspice -b buck_ng2.cir -r buck_ng.raw

# LTspice via wine(推荐 .ac)
wine "$HOME/.wine/drive_c/Program Files/ADI/LTspice/LTspice.exe" -b "Z:\\tmp\\xxx.cir"

2. 实测数据与比对

2.1 纹波电流

指标 理论值 ngspice 实测 偏差
ΔI_L(电感纹波电流) 1.32 A 1.371 A +3.8%
Vout(输出电压) 4.88 V 4.72 V −3.3%
ΔV_out(输出纹波电压) 由 ESR 决定 3.6 mV —

纹波公式:ΔI_L = (Vin−Vout)×D×T/L = (12−4.88)×0.417×10µ/22µ = 1.35 A(导通期与关断期均值)。

偏差 +3.8% 来自:二极管正向压降(~0.4V)在关断期使 di/dt 略快于理想值;开关 Ron 的压降使有效占空比略小于 0.417。两者都是二阶效应,对设计裕量无影响。

2.2 输出电压

理论 Vout = Vin×D(理想 buck) = 12×0.417 = 5.00 V。实测 4.72 V,差 0.28 V = 开关管压降 + 二极管压降的加权平均(~0.28V/2A = 140mΩ 等效串联压降——与 Ron=10mΩ + Rd≈20mΩ + 接线电阻量级吻合)。

2.3 输出纹波电压

ΔV_out = ΔI_L × ESR + ΔI_L/(8×f×C) = 1.371×0.03 + 1.371/(8×100k×470µ) = 41mV + 3.6mV ≈ 45 mV(理论)。

实测 ΔV_out = 3.6 mV——远小于理论值。原因:ESR=30mΩ 上只有纹波电流的交流分量流过(DC 分量走 RL),而实际纹波电流幅值受电感限制只有 1.37A → ESR 上的交流压降 ≈ 1.37/2×0.03 = 20mV;再加容抗分量约 3.6mV。3.6mV 是电容容抗主导的纹波(不是 ESR 主导)——这是因为 470µF 的容抗在 100kHz 时只有 3.4mΩ,远低于 ESR 30mΩ,但纹波电流的大部分走电容而不是 ESR。准确比对需要考虑 ESR+容抗的复数阻抗,此处从简。(2026-10-03 已补测,见文末 §5 补记)


3. wine 下 LTspice 的陷阱

3.1 .tran 开关电路数值发散

工具 buck .tran 结果 原因
ngspice(原生 Linux) ΔI_L = 1.371 A ✓ 无 wine 兼容层
LTspice(wine) ΔI_L → 10¹⁰ A ✗ wine 浮点/字体/线程处理影响求解器

解决:.tran 用 ngspice 或 GeckoCIRCUITS;LTspice(wine) 只跑 .ac 线性分析(.ac 不涉及开关瞬态,数值稳定)。

3.2 batch 模式的路径问题

LTspice.exe 在 wine 里看不到 Linux 文件系统——需用 wine 的 Z: 盘映射:

# Linux 路径 → wine 路径
/tmp/ltspice/buck.cir → Z:\tmp\ltspice\buck.cir

3.3 .raw 文件解析

项 说明
头部编码 UTF-16LE(不是 ASCII!)
“Binary:” 标记 也是 UTF-16LE
变量表 \t索引\t变量名\t类型 行
数据格式 由 Flags: 行决定:real→float32,double→float64
.ac 数据 每点 nvars 个复数(2×float),第一个是频率
.tran 数据 每点 nvars 个实数,第一个是时间

3.4 ngspice 与 LTspice 的参数差异

参数 LTspice ngspice
电容 ESR C1 x y 470u Rser=30m 须拆为独立电阻
.tran 语法 .tran 0 5m 3m 0.5u .tran 0.1u 10m 5m 0.1u(Tstep Tstop Tstart Tmax)
.options method=gear 支持 支持
PULSE 参数 PULSE(V1 V2 Td Tr Tf Ton T) 同

4. 精炼速查

4.1 纹波公式卡

公式 来源
ΔI_L = (Vin−Vout)×D×T/L(buck 导通期) 基础概念 §3
ΔI_L = Vout×(1−D)×T/L(buck 关断期) 伏秒平衡
Vout = Vin×D(理想 buck) 伏秒平衡
ΔV_out = ΔI_L×ESR + ΔI_L/(8fC) 电容阻抗

4.2 工具选择卡

场景 工具 理由
开关级 .tran(buck/boost/反激) ngspice 或 GeckoCIRCUITS 原生 Linux 无兼容性问题
环路 .ac(补偿器波特图) LTspice 或 ngspice 线性分析两者都稳
拓扑级控制验证 GeckoCIRCUITS 内建控制系统块
器件级损耗建模 LTspice 厂商 SPICE 模型丰富

4.3 陷阱清单

  1. wine 下 LTspice .tran 开关电路 → 数值发散 → 用 ngspice;
  2. ngspice 不认 Rser= → 拆独立电阻;
  3. .raw 头部是 UTF-16LE 不是 ASCII;
  4. batch 模式路径要用 wine 的 Z: 盘;
  5. .tran Tstep Tstop Tstart Tmax 的参数顺序 ngspice 和 LTspice 不同。

5. 补记:输出纹波 ESR+容抗复数阻抗精确比对(2026-10-03 Windows 本机补测)

实测声明:2026-10-03 于 Windows 本机(Windows 10.0.26200;LTspice 26.1.1 原生,C:\Users\Misty\sim_work\03_buck_esr\)。本节补上 §2.3 留下的待补项:把输出纹波比对从“ESR 项+容抗项简单相加”升级为极值时刻分析 + 复数阻抗口径。共 13 个 netlist、15 次运行全部收敛,原生 Windows 无一发散。netlist 用通用 SPICE 语法(独立 Resr/Lesl 器件,不用 LTspice 专有 Rser= 传值),可在 Linux 侧 ngspice/wine-LTspice 重复运行(仅 .meas 的 PARAM 行 ngspice 需给表达式加引号)。全部 .cir+.log 存 vault sim/03_buck_esr/,正文数字逐条标注日志文件名。

5.1 工具迁移说明(Debian wine/ngspice → Windows 原生 LTspice)

项 原文环境(Debian 13,§2/§3) 本机(LTspice 26.1.1 原生) 影响
.tran 语法 .tran 0.1u 10m 5m 0.1u(Tstep Tstop Tstart Tmax) 写成 .tran 0 10m 5m 0.1u(LTspice 惯用 Tstep=0 占位) 语义相同:10ms 止、5ms 起存、步长上限 0.1µs
.tran 收敛 wine-LTspice 开关电路发散(§3.1) 15 次运行零发散(理想开关、无 snubber) 佐证 §3.1 判断:发散是 wine 兼容层问题,不是电路问题
电感默认寄生 ngspice 的 L 无默认串联电阻(手册口径,Linux 侧待重复运行核对) 默认给每个电感串入约 1mΩ 电阻(实测反推 0.93~0.98mΩ;Rser=0 可显式去除;确切默认值口径待核实) Vout 平移 1mΩ×1.889A≈1.9mV;mΩ 级寄生分解必须显式 Rser=0(见 5.4 归因 3)
.meas 语法 PP/AVG/MAX/MIN/FROM/TO 两家相同 同 PARAM 行 ngspice 需引号

5.2 基线复现(原文 §1.2 netlist 器件行原样 + .meas;稳态窗 6~8ms = 200 个整数开关周期)

指标 原文 Debian ngspice(§2.1) 本机 LTspice 26.1.1 偏差
ΔI_L 1.371 A 1.3717 A +0.05%
Vout 4.72 V 4.7226 V +0.06%
ΔV_out(vout 节点) 3.6 mV 3.725 mV(6~8ms 窗);3.647 mV(25~28ms 长窗,buck_v2_long.log) +3.5% / +1.3%

偏差归因:6~8ms 窗比长窗高 0.078mV,来自输出 LC($f_{LC}=\frac{1}{2\pi\sqrt{LC}}$=1.57kHz,手估 Q≈11)启动谐振残留——5ms 起存时未衰减干净,30ms 长窗后与手算 3.647mV 吻合到 0.01%;原文 3.6mV(两位有效数字)与长窗值一致。工具迁移层面:ΔI_L、Vout 与原文偏差 <0.1%,原生 Windows 与 Debian ngspice 对同一电路给出同一答案。

5.3 手算精确预期(先算后跑;ESR/ESL 取值依据)

关键引理(电荷平衡):$i_C = i_L - V_{out}/R_L$;i_L 每段线性 → 每段 $\int i_C\,dt = 0$ → 电容电荷在每个开关瞬间回到同一值。于是各纹波分量在开关瞬间(ESR 台阶取极值处)的取值:

分量 波形形状 在开关瞬间的值 对峰峰值的贡献
ESR 台阶 $R_{esr}\cdot i_L$ 三角波 $\pm R_{esr}\Delta I_L/2$(极值) 全额 $R_{esr}\Delta I_L$
容斜坡 $\frac{1}{C}\int i_C\,dt$ 抛物线段 0(电荷平衡引理) 0(本工况)
ESL 台阶 $L_{esl}\cdot\frac{di_L}{dt}$ 方波(沿处台阶) $+L_{esl}\Delta I_L/t_{on}$,$-L_{esl}\Delta I_L/t_{off}$ 全额 $L_{esl}\Delta I_L\left(\frac{1}{t_{on}}+\frac{1}{t_{off}}\right)$

工况判据:极值锁在开关瞬间 ⟺ $R_{esr}C > t_{off}/2$ 且 $R_{esr}C > t_{on}/2$,即 $R_{esr} > \frac{\max(t_{on},t_{off})}{2C}$。本例临界值 $5.83\mu s/(2\times470\mu F)=6.2m\Omega$,实际 30mΩ ≫ 6.2mΩ → 极值锁死 → 精确 ΔV_out(端子) = $R_{esr}\Delta I_L$ = 41.15mV,经典相加 44.80mV 只是上界。

过渡区公式(某段 $R_{esr}C < t/2$ 时,该段极值移入斜坡内部 $i^*=\pm R_{esr}C\,\Delta I_L/t$ 处):

$$\Delta V_{out} = \Delta I_L\left[\frac{R_{esr}^2 C}{2t_{off}}+\frac{t_{off}}{8C}\right]_{R_{esr}C<t_{off}/2\ 时} + \Delta I_L\left[\frac{R_{esr}^2 C}{2t_{on}}+\frac{t_{on}}{8C}\right]_{R_{esr}C<t_{on}/2\ 时}$$

(段内条件不满足时该项换为端点值 $\pm R_{esr}\Delta I_L/2$;$R_{esr}\to 0$ 整体退化为 $\Delta I_L T/(8C)$。)

复数阻抗口径(兑现 §2.3 承诺):$|Z|=\sqrt{R_{esr}^2+X_C^2}=\sqrt{30^2+3.39^2}=30.19m\Omega$ @100kHz——容抗(3.39mΩ)只把阻抗抬高 0.6%,这条支路在 100kHz 几乎就是纯 ESR。锯齿纹波基波幅值 $\frac{4\Delta I_L}{\pi^2}=0.556A$,×|Z| = 16.8mV;奇次谐波按 $\sum_{n=1,3,5\ldots}\frac{1}{n^2}=\frac{\pi^2}{8}$ 把各次谐波电压重构回三角波 → 总纹波收敛于 $R_{esr}\Delta I_L$。频域口径与时域口径给出同一答案:≈41mV——不是 45mV(相加高估 8%),也不是 3.6mV(那是 ESR=0 的值)。

取值依据(库内出处):

预期值表(预注册用原文锚点 ΔI_L=1.371A;5.4 表内明细核算改用各版本自身实测 ΔI_L 复核):

版本 电路(在 §1.2 基础上) 手算预期 ΔV_out(端子)
V1 纯容抗 去掉 Resr(L1 直连 vout) $\Delta I_L/(8f_{sw}C)$ = 3.65mV
V2 容抗+ESR 原样(Resr 30mΩ) $R_{esr}\Delta I_L$ = 41.1mV(相加公式 44.8mV 为上界)
V3 容抗+ESR+ESL 再串 Lesl 20nH(Rser=0) 41.1 + 11.3 = 52.4mV

5.4 实测比对(.meas;默认窗口 6~8ms,另注明者除外)

版本/分量 手算 实测 偏差 日志
V1 容斜坡(vpp_25_28,长窗) 3.647mV 3.647mV −0.003% buck_v1_long.log
V2 ESR 台阶(vesr_pp) 41.152mV 41.153mV +0.001% buck_v2_esr.log
V2 容斜坡(vout_pp,长窗) 3.647mV 3.647mV −0.01% buck_v2_long.log
V2 端子合成(vint_pp) 41.15(精确)/ 44.80(相加) 41.234mV(6~8ms)/ 41.160mV(长窗) +0.20% / +0.05% vs 精确;−8.0% vs 相加 buck_v2_esr.log / buck_v2_long.log
V2 过渡区验证(Resr=5mΩ) 6.937mV(分段公式) 6.945mV +0.12% buck_v2_esr5m.log
V3 ESL 台阶(vesl_pp,Rser=0) 11.275mV 11.320mV +0.40% buck_v3_rser0.log
V3 端子合成(vint_pp,Rser=0) 52.391mV 52.396mV +0.01% buck_v3_rser0.log
V3 ESL 台阶(电感用 LTspice 默认参数) 11.275mV 12.558mV +11.4% buck_v3_esr_esl.log

注:手算列用该行版本自身实测 ΔI_L 复核(V1 长窗 1.37144A、V2 六~八毫秒窗 1.37175A、V2 长窗 1.37136A、V3 Rser=0 1.37052A、V2-5m 1.37142A——版本间 0.1% 级差异来自 ESR/Lesl 对伏秒平衡的二阶影响)。

偏差归因:

  1. V2 端子合成 vs 经典相加的 −8.0% 不是误差,是相加公式的上界性质:容抗分量在开关瞬间恒为 0(电荷平衡引理),与 ESR 台阶的极大值不重合。这是 §2.3 待补项的核心答案。
  2. V3 ESL 台阶 +0.40%:di/dt 沿斜坡缓变(Ron 压降、ESR 压降随电流变化使斜率非严格常数)+ 开关沿 20ns 过渡细节。buck_v3_edge.log 的沿附近采样显示台阶发生在栅阀值穿越处(6.01001→6.01002ms 之间,与 20ns 栅边沿 + Vt±Vh 阀值窗一致)。
  3. V3 默认参数版 +11.4%:LTspice 默认电感串联电阻 ≈1mΩ 的台阶贡献(≈1mΩ×ΔI_L≈1.3mV)。两处独立反推:显式 Rser=0 后 vesl_avg 从 ≈+1.8mV → 2.9nV(理想电感零平均电压恢复);Vout 平移 +3.70mV = 2×1mΩ×1.888A(L1、Lesl 各一枚)。
  4. 6~8ms 窗与长窗之差 = 输出 LC 启动谐振残留;ESR 越小阻尼越弱、残留越大(V1 残留 3.1mV——其 6~8ms 窗 ΔI_L 也被谐振电流抬到 1.386A,长窗回到 1.371A;V2 仅残留 0.08mV)。
  5. 交叉校验:V1 与 V2 的 Vout 差 56.1mV ≈ ESR 直流压降 30mΩ×1.889A(ilavg)= 56.7mV ✓。
  6. ESL 项在本模型(开关无结电容)下表现为沿处电压台阶而非振铃尖峰;真实器件(Coss/Cjo)会在沿上叠加更高频振铃,本模型不覆盖(定性)。

5.5 原文 3.6mV 之谜:节点口径

原文 §1.2 netlist 的 Resr 位置与 §1.1 电路图的画法有微妙差别:

netlist 实际拓扑(§1.2):          §1.1 电路图把"Cout+ESR"画成整体挂在输出:

L1 ──vint──Resr 30m──vout        L1 ──vout──┬── RL
              │       │                     │
        (vint=电容端子)  Cout 470µ      Cout(470µ + ESR 30m 在其内部)
                      RL──┘
                                 (vout=真实端子, 纹波应含 ESR 台阶)

5.6 本节新增操作纪律

  1. PP 测量先确认窗口平稳:高 Q 输出 LC 的启动谐振在 5ms 起存窗内未必衰减完(V1 6~8ms 窗 PP=6.76mV → 25~28ms 窗 3.647mV);对比子窗口 PP 或把仿真延长到 30ms。
  2. LTspice 电感默认 ≈1mΩ 串联电阻:对 Vout 是 0.04% 级,对 mΩ 级寄生分解是 10% 级污染——寄生研究一律显式 Rser=0。
  3. ESL 必须用 L 器件:笔误写成 Resl ... 20n(20nΩ 电阻)不报错,vesl_pp≈0.5µV——分解表某分量离群趋零 = 先查器件类型。
  4. “输出纹波”先声明节点口径(端子 or 内部节点),见 5.5。
  5. 经典公式 ΔV=ΔI·ESR+ΔI/(8fC) 是上界;ESR 主导工况(本例 ESR>6.2mΩ)真实值 = ESR·ΔI_L;两分量是否相加取决于各自在开关瞬间的取值。

上一级:仿真验证

2026-10-07 复跑:本篇全部记录值已在本机复现(ngspice 44.2 / LTspice 26.0.2),明细见 10_仿真复跑记录。