1. 问题背景与现象分析
在OBC(车载充电机)的LLC谐振变换器控制中,llc_ctrl_step()作为电压环的核心PI控制函数,其稳定性直接影响整个系统的性能表现。近期我们在某型号OBC量产测试中发现一个典型问题:当系统进入限流状态(limit_active = true)时,控制频率f_cmd会出现异常的跳变现象。这种跳频在限流与恢复状态切换时尤为明显,具体表现为:
- 频率突变幅度可达5-10kHz(正常slew rate下不应超过1kHz/ms)
- 伴随可闻的高频啸叫声(20kHz以上)
- 导致输出电压出现50-100mV的纹波增大
通过逻辑分析仪抓取的波形显示,问题根源在于限流分支中一个看似无害的赋值操作f_prev = f_t;。这个操作本意是"刷新历史频率",但实际上破坏了PI控制器的状态连续性。
2. 控制逻辑深度解析
2.1 函数架构与数据流
llc_ctrl_step()的完整处理流程包含以下关键环节:
c复制// 伪代码示意
float llc_ctrl_step(float e, bool en, bool limit_active) {
// 参数保护
clamp_params();
// 使能检测
if(!en) return f_nom;
// PI运算
float f_t = pi_controller(e);
// 限幅处理
f_t = clamp(f_t, f_min, f_max);
// 限流特殊处理
if(limit_active) {
f_t = min(f_t, f_limit);
// 问题点:f_prev = f_t; // 导致状态不连续
}
// 抗饱和处理
anti_windup(f_t);
// 频率渐变(slew rate限制)
f_t = slew_limiter(f_t, f_prev);
// 频率量化
f_t = quantize(f_t, f_q_step);
// 更新历史值
f_prev = f_t;
return f_t;
}
2.2 问题机理分析
当系统进入限流状态时,原代码会执行f_prev = f_t的强制更新。这导致两个严重后果:
- slew rate限制失效:下一次控制周期时,
slew_limiter比较的f_prev已被强制更新,失去对频率变化的平滑约束 - PI状态不连续:人为打断控制量的自然过渡过程,相当于给闭环系统注入阶跃扰动
关键发现:限流状态本身已经通过
f_t = min(f_t, f_limit)保证了频率上限,额外的f_prev更新完全是冗余操作
3. 解决方案设计与验证
3.1 修改方案对比
| 方案 | 修改内容 | 优点 | 风险 |
|---|---|---|---|
| 方案A | 完全删除限流分支内的f_prev赋值 |
保持状态连续性 | 需验证所有工况 |
| 方案B | 改为条件赋值if(f_t < f_prev) f_prev=f_t |
保守式修改 | 复杂度增加 |
| 方案C | 增加平滑过渡算法 | 最优平滑性 | 计算量增大 |
最终选择方案A,因为:
- 限幅操作已确保频率不超过
f_limit - 保持原有slew rate限制逻辑不变
- 修改影响范围最小化
3.2 具体实现细节
修改后的限流处理段:
c复制if(limit_active) {
f_t = min(f_t, f_limit);
// 删除原f_prev赋值操作
}
配套需要:
- 在函数入口增加参数有效性检查:
c复制assert(f_max > f_min); assert(f_slew > 0); - 在状态机顶层增加限流标志滤波:
c复制// 10ms时间常数的低通滤波 limit_active_filtered = 0.9*limit_active_filtered + 0.1*limit_active;
3.3 测试验证方案
我们设计了多维度测试用例:
-
阶跃负载测试:
- 从10%突加至100%负载
- 测量频率过渡时间(应<5ms)
- 验证无频率过冲
-
持续限流测试:
python复制# 自动化测试脚本片段 for i in range(1000): set_load(random.uniform(80, 120)) if get_current() > threshold: assert abs(freq_diff) < 100 # Hz -
频谱分析:
- 使用Audio Precision分析输出噪声谱
- 要求20kHz以上成分衰减40dB
4. 工程实践要点
4.1 参数整定建议
-
slew rate选择:
code复制f_slew = 0.2 * f_sw_max (例如:f_sw_max=150kHz → f_slew=30kHz/ms) -
量化步长设置:
c复制// 根据DCO分辨率确定 #define F_Q_STEP (F_REF / (1<<DCO_BITS))
4.2 常见问题排查
-
修改后频率响应变慢:
- 检查PI参数是否匹配新的动态特性
- 适当增大
kp(通常增加20-30%)
-
仍出现轻微啸叫:
- 确认PWM死区时间设置合理
- 检查谐振电容ESR参数
-
限流恢复时的振荡:
c复制// 可增加恢复时的软启动 if(limit_active_transition) { f_t = lerp(f_prev, f_t, 0.1); // 10%渐变 }
4.3 硬件关联注意事项
-
当频率>120kHz时:
- 检查MOSFET开关损耗
- 确认磁性元件不会饱和
-
布局布线要求:
- 电流采样走线长度<3cm
- 地回路面积最小化
5. 扩展优化方向
-
自适应slew rate:
c复制// 根据误差大小动态调整 float dynamic_slew = base_slew * (1 + K*abs(e)); -
频率前馈补偿:
c复制// 增加输入电压补偿项 f_t += K_vin*(vin - vin_nom); -
数字抗混叠:
c复制// 增加IIR滤波 f_cmd = 0.9*f_cmd + 0.1*f_raw;
在实际项目中,我们通过这组修改将频率跳变幅度从±8kHz降低到±200Hz以内,系统THD改善了15dB。这个案例告诉我们,看似简单的状态变量管理,可能对系统稳定性产生深远影响。建议在类似的控制算法中,对所有状态变量的修改点都进行严格的连续性分析。
