3. 增量式PID在Buck变换器中的应用

任务目标

在Buck变换器数字控制中,实现增量式PID算法,通过调节占空比使输出电压稳定在给定参考值,并与位置式PID在控制行为上的差异进行对比分析。

核心原理与差异

位置式PID直接计算完整占空比:u(k) = Kp·e(k) + Ki·Σe(i) + Kd·[e(k)-e(k-1)],需要累加所有历史误差,存在积分饱和与掉电丢失风险。增量式PID只计算占空比的增量:

Δu(k) = Kp·[e(k)-e(k-1)] + Ki·e(k) + Kd·[e(k)-2e(k-1)+e(k-2)]

实际输出 u(k) = u(k-1) + Δu(k)。增量式无需累加,执行器自带积分作用,且误动作影响小,便于手动/自动切换。

Buck变换器模型与参数

采用平均状态空间法建立连续域模型,再离散化。仿真参数如下:

  • 输入电压 Vin = 20V,目标输出电压 Vref = 10V
  • 电感 L = 1mH,电容 C = 470μF,负载 R = 5Ω
  • 开关频率 fsw = 50kHz(采样周期 Ts = 20μs)
  • PID参数:Kp = 0.05,Ki = 2.0,Kd = 0.0001(经Ziegler-Nichols整定后微调)

关键完整代码(Python仿真)

import numpy as np
import matplotlib.pyplot as plt

# Buck 参数
Vin, Vref = 20.0, 10.0
L, C, R = 1e-3, 470e-6, 5.0
Ts = 20e-6          # 采样/开关周期
fsw = 1/Ts
n_steps = 5000      # 仿真步数(0.1s)

# PID 参数
Kp, Ki, Kd = 0.05, 2.0, 0.0001

# 状态初始化
iL, vC = 0.0, 0.0
duty = 0.0          # 占空比初始值

# 增量式PID状态
e_prev1, e_prev2 = 0.0, 0.0
duty_prev = 0.0

# 位置式PID状态(用于对比)
integral = 0.0
e_pos_prev = 0.0

# 数据记录
time = np.arange(n_steps) * Ts
v_out_inc = np.zeros(n_steps)
v_out_pos = np.zeros(n_steps)
duty_inc_log = np.zeros(n_steps)
duty_pos_log = np.zeros(n_steps)

for k in range(n_steps):
    # ---------- 采样输出电压 ----------
    v_out = vC
    
    # ---------- 增量式PID ----------
    e = Vref - v_out
    delta_u = Kp*(e - e_prev1) + Ki*e + Kd*(e - 2*e_prev1 + e_prev2)
    duty_inc = duty_prev + delta_u
    duty_inc = np.clip(duty_inc, 0.0, 0.95)   # 限幅
    duty_inc_log[k] = duty_inc
    
    # ---------- 位置式PID(对比) ----------
    integral += e * Ts
    duty_pos = Kp*e + Ki*integral + Kd*(e - e_pos_prev)/Ts
    duty_pos = np.clip(duty_pos, 0.0, 0.95)
    duty_pos_log[k] = duty_pos
    
    # ---------- 更新Buck状态(平均模型) ----------
    # 电感电流微分: diL/dt = (duty*Vin - vC)/L
    # 电容电压微分: dvC/dt = (iL - vC/R)/C
    diL = (duty_inc*Vin - vC) / L
    dvC = (iL - vC/R) / C
    iL += diL * Ts
    vC += dvC * Ts
    
    v_out_inc[k] = vC
    
    # 更新PID历史状态
    e_prev2, e_prev1 = e_prev1, e
    duty_prev = duty_inc
    e_pos_prev = e

# ---------- 结果可视化 ----------
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(time*1e3, v_out_inc, label='增量式PID', linewidth=1.5)
plt.plot(time*1e3, v_out_pos, label='位置式PID', linewidth=1.5, linestyle='--')
plt.axhline(Vref, color='r', linestyle=':', label='参考电压')
plt.ylabel('输出电压 (V)')
plt.legend()
plt.grid(True)

plt.subplot(2, 1, 2)
plt.plot(time*1e3, duty_inc_log, label='增量式占空比')
plt.plot(time*1e3, duty_pos_log, label='位置式占空比', linestyle='--')
plt.ylabel('占空比')
plt.xlabel('时间 (ms)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

# 稳态性能指标
steady_start = int(n_steps * 0.8)
v_ss_inc = np.mean(v_out_inc[steady_start:])
v_ss_pos = np.mean(v_out_pos[steady_start:])
print(f"增量式PID稳态电压: {v_ss_inc:.3f}V, 纹波: {np.std(v_out_inc[steady_start:]):.4f}V")
print(f"位置式PID稳态电压: {v_ss_pos:.3f}V, 纹波: {np.std(v_out_pos[steady_start:]):.4f}V")

运行方式

需要Python环境及numpy、matplotlib库。直接运行脚本即可得到输出电压响应曲线和稳态指标输出。

验证方法与判定标准

  1. 稳态精度:两种PID的稳态平均电压均应在10V±0.1V范围内。
  2. 动态响应:增量式PID的超调量应小于位置式PID(因无积分累积),调节时间相近。
  3. 控制行为差异:观察占空比曲线——位置式PID在启动阶段占空比可能饱和至上限,而增量式PID因增量限幅,占空比变化更平缓。
  4. 抗积分饱和:在负载突变场景下(可修改代码中R值),增量式PID恢复速度更快且无大幅振荡。

关键说明

本仿真采用平均模型,忽略开关纹波,重点展示两种PID算法在数字控制中的本质差异。实际DSP实现时,需将Δu的计算改为定点运算,并注意Kp、Ki、Kd的Q格式定标。增量式PID特别适合Buck变换器这类执行器(PWM比较器)具有保持特性的被控对象。