第四章 Mathcad/Matlab建模:功率级传递函数推导、补偿器传递函数、闭环传递函数仿真
做数字电源环路设计,最怕什么?
怕你焊好板子,一上电就振荡。或者更糟——静态看起来稳,动态一加载就崩。
我个人习惯是:上电前,先把传递函数算清楚。这不是学院派作风,这是实战保命手段。今天我们就来聊聊怎么用 Mathcad 或 Matlab 把功率级、补偿器、闭环传递函数一步步建出来。
核心观点:建模不是为了算一个精确的数值,而是为了看清系统的趋势和裕量。你算出来的穿越频率可能和实测差 10%~20%,但相位裕度的趋势一定是对的。
4.1 功率级传递函数推导
先看功率级。以 Buck 变换器为例,它的控制到输出传递函数长这样:
Gvd(s) = Vin * (1 + s*Rc*C) / (1 + s*(Rl+Rc)*C + s²*L*C)
嗯,这里要注意:Rc 是电容 ESR,Rl 是电感 DCR。很多新手直接忽略这两个电阻,结果仿真和实测差一大截。
我在项目中遇到过一件事:一个 12V 转 3.3V 的 Buck,电感 DCR 只有 5mΩ,电容 ESR 约 10mΩ。我一开始偷懒没加,算出来的穿越频率是 45kHz。实测一测,只有 32kHz。为什么?因为 ESR 和 DCR 引入了一个零点,把增益曲线抬高了。加上之后,模型和实测就吻合了。
所以我的建议是:别偷懒,把寄生参数加进去。哪怕只是估算值,也比没有强。
在 Mathcad 里,我习惯这样写:
Vin := 12
L := 10e-6
C := 100e-6
Rl := 0.005
Rc := 0.010
Rload := 3.3
Gvd(s) := Vin * (1 + s*Rc*C) / (1 + s*(Rl+Rc)*C + s²*L*C)
然后直接画 Bode 图。看一眼低频增益、谐振峰、高频滚降,心里就有底了。
小技巧:在 Matlab 里可以用 tf() 函数直接建传递函数模型,然后用 bode() 画图。我个人更喜欢 Mathcad,因为公式写出来就是数学符号,调试时一目了然。
4.2 补偿器传递函数
功率级搞定了,接下来是补偿器。数字电源里最常用的是 IIR 型 PID,也就是双极点双零点补偿。
它的 s 域传递函数:
C(s) = Kp + Ki/s + Kd*s
但实际工程中,我们用的是带限幅的 PID,或者更常见的 Type III 补偿器:
C(s) = K * (1 + s/ωz1) * (1 + s/ωz2) / [s * (1 + s/ωp1) * (1 + s/ωp2)]
为什么用 Type III?因为 Buck 的功率级在 LC 谐振处有一个双极点,相位掉得厉害。Type III 的两个零点可以补偿这个相位跌落,两个极点则用来抑制高频噪声。
我曾经踩过一个坑:把零点频率设得太高,结果相位裕度只有 20°。加载时输出掉了 200mV 才回来。后来我把零点往 LC 谐振频率附近移,相位裕度拉到 55°,动态响应就好多了。
所以我的经验是:零点放在 LC 谐振频率的 0.5~0.8 倍,极点放在开关频率的 1/2~1/3。这样既保证相位裕度,又不会引入太多噪声。
在 Matlab 里建补偿器模型:
K = 1000;
wz1 = 2*pi*2000;
wz2 = 2*pi*2000;
wp1 = 2*pi*50000;
wp2 = 2*pi*100000;
s = tf('s');
C = K * (1 + s/wz1) * (1 + s/wz2) / (s * (1 + s/wp1) * (1 + s/wp2));
注意:数字补偿器最终要离散化。s 域模型只是起点,后面还要用双线性变换(Tustin)转成 z 域。但 s 域分析能帮你快速确定零极点位置,省去大量试错时间。
4.3 闭环传递函数仿真
功率级和补偿器都有了,闭环传递函数就是它们的乘积再反馈:
开环传递函数:T(s) = Gvd(s) * C(s)
闭环传递函数:Gcl(s) = T(s) / (1 + T(s))
仿真闭环传递函数,我一般做三件事:
- 看 Bode 图——确认穿越频率和相位裕度
- 看阶跃响应——看超调量和调节时间
- 看输入扰动抑制——看低频增益够不够
在 Mathcad 里,我习惯把这三个图放在一个工作表里,参数调完立刻刷新。你想想看,调一个电阻值,所有曲线同时更新,那种感觉真的很爽。
下面是我常用的一段 Matlab 仿真代码:
% 功率级参数
Vin = 12; L = 10e-6; C = 100e-6;
Rl = 0.005; Rc = 0.01; Rload = 3.3;
% 功率级传递函数
s = tf('s');
Gvd = Vin * (1 + s*Rc*C) / (1 + s*(Rl+Rc)*C + s^2*L*C);
% 补偿器传递函数
K = 800;
wz = 2*pi*2500;
wp = 2*pi*60000;
C = K * (1 + s/wz)^2 / (s * (1 + s/wp)^2);
% 开环和闭环
T = Gvd * C;
Gcl = T / (1 + T);
% 画图
figure(1);
bode(T); grid;
title('开环传递函数 Bode 图');
figure(2);
step(Gcl); grid;
title('闭环阶跃响应');
跑完这段代码,你会看到开环 Bode 图上穿越频率在 10kHz 左右,相位裕度 50° 以上。阶跃响应超调小于 10%,调节时间在 100μs 以内。嗯,这个结果就可以拿去打样了。
避坑指南:我曾经在仿真时把负载电阻设成 3.3Ω,结果阶跃响应看起来完美。实际板子接的是 1Ω 负载,一加载就振荡。为什么?因为负载变重,功率级的 Q 值变了。所以仿真时一定要扫一下负载范围,看看最恶劣情况下的裕量。
4.4 知识体系总览
为了让你对整个建模流程有个全局感,我画了一张图:
4.5 常见问题与避坑
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 仿真穿越频率和实测差 30% 以上 | 寄生参数没加,或电感电容值偏差大 | 用 LCR 表实测后更新模型参数 |
| 相位裕度仿真 60°,实测只有 30° | 数字控制延迟(ADC 采样+计算延迟)没考虑 | 在模型中加一个 e^(-sTd) 延迟环节 |
| 阶跃响应仿真完美,实测振荡 | 补偿器饱和限幅没建模 | 在仿真中加入 PWM 占空比限幅 |
| 轻载稳定,重载振荡 | 功率级 Q 值随负载变化 | 扫负载范围,找最恶劣工况 |
重要提醒:仿真只是工具,不是真理。我见过太多人把仿真调到完美,结果板子一上电就炸。为什么?因为仿真模型永远无法 100% 反映真实世界的寄生、延迟、噪声。所以我的原则是:仿真给趋势,实测给结论。两者对得上,才能放心量产。