2. 数字电源核心架构:控制环路、PWM生成、ADC采样与反馈
好,咱们进入第二章。这一章是整个数字电源的骨架,搞懂了它,后面那些同步整流、环路补偿、效率优化才有落脚点。我见过不少工程师,一上来就调PID参数,结果连PWM分辨率够不够、ADC采样时序对不对都没搞清楚——那调试过程基本就是碰运气。
数字电源的核心架构,说白了就是三件事:采样、计算、输出。ADC把模拟量变成数字,控制器算出差值,DPWM把数字结果变回脉冲去驱动开关管。听起来简单,但每一步都有坑。
2.1 数字电源控制环路:从模拟到数字的思维转变
先看这张整体架构图,我习惯把它叫作“数字闭环三件套”。
这张图里,我特意把参考电压 Vref画在了控制器旁边。为什么?因为数字电源的Vref不是硬件电阻分压,而是存在寄存器里的一个数字。你想改输出电压?改寄存器就行,不用换电阻。这就是数字化的第一个好处。
核心区别一句话:模拟环路靠RC网络调零极点,数字环路靠算法算误差。前者是物理器件,后者是数学运算。
2.2 PWM生成原理:DPWM到底怎么工作的?
数字PWM(DPWM)和模拟PWM最大的不同,在于时间基准。模拟PWM靠比较器+锯齿波,DPWM靠计数器+比较寄存器。
我举个例子。假设开关频率100kHz,周期10μs。你用200MHz的系统时钟,那么一个周期内就有2000个时钟节拍。DPWM的核心就是:
- 时基计数器:从0数到1999,然后归零
- 占空比寄存器:存一个数,比如800
- 比较器:计数值 < 800时输出高,否则输出低
这样占空比就是800/2000 = 40%。分辨率呢?2000步,约11bit。够用吗?
我的经验:对于12V输入、1.2V输出的Buck,如果DPWM分辨率低于10bit,输出纹波会明显看到台阶。我曾经在一个项目里用了8bit DPWM,结果满载时纹波比设计值大了30%。后来换成11bit,问题解决。
DPWM的常见拓扑有三种:
| 类型 | 原理 | 分辨率 | 适用场景 |
|---|---|---|---|
| 计数器型 | 单计数器+比较器 | 8~12bit | 低成本、低频 |
| 延迟线型 | 多级延迟单元 | 12~16bit | 高频、高精度 |
| 混合型 | 计数器+延迟线 | 16bit+ | 高端服务器电源 |
你想想看,为什么高频电源需要延迟线型?因为频率高了,周期短了,计数器能数的步数就少了。比如1MHz开关频率,周期1μs,200MHz时钟只能数200步——才7.6bit分辨率,纹波会大到没法看。延迟线型可以在一个时钟周期内插出几十个精细台阶,把分辨率拉回来。
2.3 ADC采样与反馈:时序比精度更重要
ADC采样这块,我踩过的坑最多。很多初学者只盯着ADC的ENOB(有效位数),却忽略了采样时刻。
数字电源里,ADC采样有个黄金法则:在开关噪声最小的窗口采样。什么时候噪声最小?通常是下管导通、电感电流续流的那段区间。如果你在开关管切换瞬间采样,那采回来的电压可能比实际值高50mV以上。
⚠️ 我曾经犯过的错:在一个48V转12V的DC-DC项目里,ADC采样时刻正好落在上管关断的瞬间。结果采样值波动达到±80mV,环路怎么调都不稳。后来把采样窗口往后挪了1.5μs,问题立刻消失。记住:采样时序错了,再好的ADC也白搭。
采样方式上,主流有三种:
- 单次采样:每个开关周期采一次,简单但抗噪差
- 多次平均:一个周期内采多次,取平均,精度高但延迟大
- 同步采样:与PWM同步触发,在固定相位采样,最常用
我个人习惯用同步采样。配置好PWM的触发信号,让ADC在PWM计数器的特定值处启动转换。这样每次采样的相位都固定,环路模型也更容易建立。
2.4 数字控制器 vs 模拟控制器:到底差在哪?
这个问题我经常被问到。直接上对比表:
| 对比维度 | 模拟控制器 | 数字控制器 |
|---|---|---|
| 补偿方式 | RC网络、运放 | PID算法、IIR滤波器 |
| 灵活性 | 改参数要换电阻电容 | 改寄存器就行 |
| 温度漂移 | 明显(电容老化) | 几乎为零 |
| 延迟 | 纳秒级 | 微秒级(ADC+计算) |
| 可编程性 | 无 | 可在线更新 |
| 多环路控制 | 复杂、硬件成本高 | 软件实现,几乎零成本 |
说白了,模拟控制器像一把固定扳手,只能拧一种规格的螺丝。数字控制器像一把可调扳手,换个数字就能适应不同场景。
但数字控制器也有短板——延迟。ADC转换时间、计算时间、DPWM更新延迟,加起来可能有好几微秒。对于500kHz以上的开关频率,这个延迟会明显影响相位裕度。怎么解决?
- 用更快的ADC:SAR型ADC,1μs内完成转换
- 流水线计算:本周期采样的值,用于计算下一周期的占空比
- 预测控制:根据历史数据预估当前周期的输出
我的建议:如果你刚开始做数字电源,先别追求太高的开关频率。100kHz~300kHz是个很好的起点,延迟影响小,调试也容易。等把环路调明白了,再往高频走。
2.5 一个简单的数字控制器代码框架
下面是一个典型的数字PID控制器实现。注意,这不是完整的工程代码,只是展示核心逻辑。
// 数字PID控制器 - 位置式算法
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float integral; // 积分累加值
float prev_error; // 上一次误差
float out_max; // 输出上限
float out_min; // 输出下限
} PID_Controller;
float PID_Update(PID_Controller *pid, float setpoint, float feedback) {
float error = setpoint - feedback;
// 比例项
float p_out = pid->Kp * error;
// 积分项(带抗饱和)
pid->integral += pid->Ki * error;
if (pid->integral > pid->out_max) pid->integral = pid->out_max;
if (pid->integral < pid->out_min) pid->integral = pid->out_min;
// 微分项
float d_out = pid->Kd * (error - pid->prev_error);
pid->prev_error = error;
// 合成输出
float output = p_out + pid->integral + d_out;
// 输出限幅
if (output > pid->out_max) output = pid->out_max;
if (output < pid->out_min) output = pid->out_min;
return output;
}
这段代码里,我特别加了积分抗饱和。为什么?因为数字控制器的积分项是累加的,如果输出饱和了还在累加,等误差反转时,积分项需要很长时间才能退回来——这就是所谓的“积分饱和”。模拟控制器也有这个问题,但数字控制器更明显,因为积分是纯数学累加,没有物理泄放路径。
调试小技巧:刚开始调PID时,先把Ki和Kd设成0,只调Kp。等输出能稳定在目标值附近了,再加Ki消除静差。最后加Kd改善动态响应。别一上来就三个系数一起调,那样你根本不知道哪个参数在起作用。