关键词:双有源桥(DAB)、三重移相(TPS)、电流有效值优化、嵌入式控制、C2000、STM32


前言:为什么我们要"折腾"调制策略?

做数字电源的工程师都知道,双有源桥(DAB)是个好东西:双向能量流动、天然的软开关(ZVS)潜力、高功率密度。传统的单移相(SPS)控制非常简单,一个移相角 DssD_{ss}Dss 走天下。

但是,SPS 有个致命伤:

当输入输出电压不匹配(M≠1M \neq 1M=1)或者轻载时,电感电流有效值(IrmsI_{rms}Irms)会急剧增大。电流大了意味着什么?意味着 MOSFET 的导通损耗(I2RI^2RI2R)飙升,变压器发热,效率断崖式下跌。

为了解决这个问题,学术界提出了三重移相(TPS/DRM),增加了两个自由度(Dp0,Ds0D_{p0}, D_{s0}Dp0,Ds0)。然而,大多数论文推导极其复杂,满篇的 KKT 条件和四阶方程,让人望而生畏。

这篇博客的目的,就是把复杂的数学包装撕掉,告诉你作为一个嵌入式软件工程师,如何在 MCU(如 TI C2000 或 STM32)上,用最简单的 if-else 逻辑和查表法,实现 DAB 的电感电流有效值最优化调制。


在这里插入图片描述

一、核心思想:把负载切成三段

论文通过复杂的数学推导(GOC 全局优化条件),最终得出了一个对我们写代码非常友好的结论:

不需要实时解复杂的优化方程。只需要在不同的功率区间,采用固定的简化策略即可。

这个功率区间由电压传输比 MMM控制量 DcD_cDc 决定。

1.1 两个关键变量

在写代码前,你必须先算好这两个全局变量:

① 电压传输比 MMM

M=N⋅VrefVinM = \frac{N \cdot V_{ref}}{V_{in}}M=VinNVref

符号 含义 来源
NNN 变压器匝比 硬件常量
VrefV_{ref}Vref 输出电压设定值 系统参数
VinV_{in}Vin 输入电压采样值 ADC 实时采样

物理意义MMM 决定了系统是工作在降压(M<1M<1M<1)还是升压(M>1M>1M>1)状态。

② 控制量 DcD_cDc

属性 说明
来源 电压环 PI 控制器的输出
范围 通常归一化到 [0,1.5][0, 1.5][0,1.5]
物理意义 代表当前的功率需求。DcD_cDc 越大,负载越重

一句话理解 DcD_cDc:它就是电压环 PI 控制器输出的"归一化占空比指令",反映了"当前负载有多重"。

1.2 三段式最优策略(核心结论)

无论 MMM 是多少,最优策略都可以归纳为以下三种:

工况 判断条件 核心动作 一句话解释
重载 HLS Dc≥1D_c \ge 1Dc1 退化为 SPS
(Dp0=0,Ds0=0D_{p0}=0, D_{s0}=0Dp0=0,Ds0=0)
功率太大,复杂的调制反而增加损耗,老老实实用传统单移相
中载 MLS M≤Dc<1M \le D_c < 1MDc<1M<1M<1M<1
1/M≤Dc<11/M \le D_c < 11/MDc<1M>1M>1M>1
固定一边
(Ds0=0D_{s0}=0Ds0=0Dp0=0D_{p0}=0Dp0=0)
牺牲一点点自由度,换取电流的大幅降低,性价比最高
轻载 LLS Dc<MD_c < MDc<MM<1M<1M<1
Dc<1/MD_c < 1/MDc<1/MM>1M>1M>1
消除环流
(满足特定等式)
轻载时主要敌人是环流(不做功的电流),通过特定组合消除它

二、公式速查表(直接复制用)

下面的表格总结了所有你需要用到的公式。公式已经过工程简化,去掉了复杂的推导过程。

2.1 降压工况 M<1M < 1M<1(如电池放电、正向传输)

工况 判断条件 Dp0D_{p0}Dp0 Ds0D_{s0}Ds0 DssD_{ss}Dss 论文式号
重载 Dc≥1D_c \ge 1Dc1 000 000 12M∗[(2Dc−3)∗(1−1−M2)+M]\dfrac{1}{2M}*[(2D_c-3)*(1-\sqrt{1-M^2})+ M]2M1[(2Dc3)(11M2 )+M] (3-21)
中载 M≤Dc<1M \le D_c < 1MDc<1 1−Dc1-D_c1Dc 000 Dp0−1+M+MDp0+(1−M)2+M2(1−Dp02)2M\dfrac{D_{p0}-1 +M+ MD_{p0} + \sqrt{(1-M)^2+ M^2(1-D_{p0}^2)}}{2M}2MDp01+M+MDp0+(1M)2+M2(1Dp02) (3-19)
轻载 Dc<MD_c < MDc<M 1−Dc1 - D_c1Dc(示例映射) 1−1−Dp0M1 - \dfrac{1 - D_{p0}}{M}1M1Dp0 (1−M)(1−Dp0)M\dfrac{(1-M)(1-D_{p0})}{M}M(1M)(1Dp0) (3-13)

中载公式辅助函数(M<1M<1M<1):

float calc_MLS_lt1(float Dp0, float M) {
    float t1 = (Dp0 - 1.0f + M + Dp0 * M) / (2.0f * M);
    float sq = (1.0f - M)*(1.0f - M) + M*M*(Dp0*Dp0 - 1.0f);
    if (sq < 0) sq = 0;
    return t1 + sqrtf(sq) / (2.0f * M);
}

2.2 升压工况 M>1M > 1M>1(如电池充电、反向传输)

工况 判断条件 Dp0D_{p0}Dp0 Ds0D_{s0}Ds0 DssD_{ss}Dss 论文式号
重载 Dc≥1D_c \ge 1Dc1 000 000 12∗[(2Dc−3)∗(M−M2−1)+1]\dfrac{1}{2}*[(2D_c-3)*(M-\sqrt{M^2-1})+ 1]21[(2Dc3)(MM21 )+1] (3-27)
中载 1/M≤Dc<11/M \le D_c < 11/MDc<1 000 1−Dc1-D_c1Dc(示例映射) 1−Ds0−M+MDs0+Ds02−1+M2(1−Ds0)22\dfrac{1 - D_{s0} - M + M D_{s0} + \sqrt{D_{s0}^2 - 1 + M^2(1-D_{s0})^2}}{2}21Ds0M+MDs0+Ds021+M2(1Ds0)2 (3-25)
轻载 Dc<1/MD_c < 1/MDc<1/M 1−Dc1-D_c1Dc 1−M(1−Ds0)1-M(1-D_{s0})1M(1Ds0) 000 (3-23)

中载公式辅助函数(M>1M>1M>1):

float calc_MLS_gt1(float Ds0, float M) {
    float t1 = (1.0f - Ds0 - M + M * Ds0) / 2.0f;
    float sq = Ds0*Ds0 - 1.0f + M*M*(1.0f - Ds0)*(1.0f - Ds0);
    if (sq < 0) sq = 0;
    return t1 + sqrtf(sq) / 2.0f;
}

2.3 升压/降压对偶关系(验证用)

对象 M<1M < 1M<1 M>1M > 1M>1 替换规则
电压比 MMM 1/M1/M1/M M↔1/MM \leftrightarrow 1/MM1/M
原/副边角 Dp0D_{p0}Dp0 Ds0D_{s0}Ds0 Dp0↔Ds0D_{p0} \leftrightarrow D_{s0}Dp0Ds0
轻载最大范围 M=0.5M=0.5M=0.5Pn,t∈[0,0.5]P_{n,t}\in[0,0.5]Pn,t[0,0.5] M=2M=2M=2Pn,t∈[0,0.5]P_{n,t}\in[0,0.5]Pn,t[0,0.5] 完全对称
中载公式 式 (3-19) 含 Dp0D_{p0}Dp0 式 (3-25) 含 Ds0D_{s0}Ds0 互换后形式一致

:所有公式中的占空比均归一化到 [0,1][0,1][0,1]DssD_{ss}Dss 建议限幅到 [0,0.5][0, 0.5][0,0.5]。中载公式含根号项,实现时需保证根号内非负(正常工作域内自然满足,但代码里加个 max(0, x) 保护更安全)。


三、嵌入式代码逻辑框架

下面是一个基于 C 语言的完整伪代码结构,展示了如何在中断服务函数(ISR)中实现该算法。

// ============================================================
// 全局变量
// ============================================================
float M, Dc;
float Dss, Dp0, Ds0;

// ============================================================
// 辅助函数:限幅
// ============================================================
float clamp(float x, float lo, float hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

// ============================================================
// 重载区 Dss 计算(SPS 模式,轻重载统一)
// ============================================================
float calc_Dss_HLS(float Dc, float M) {
    float Dss =(1/2*M)*((2*Dc-3)*(1-sqrt(1-M*M))+M);
    return clamp(Dss, 0.0f, 0.5f);
}

// ============================================================
// 主控制函数(在 PWM 中断或定时器中调用)
// ============================================================
void DAB_Control_Loop(void) {
    // ---------- 1. 采样与计算 ----------
    float Vin = ADC_Read(VC_IN);          // 输入电压采样
    float Vout = ADC_Read(VC_OUT);        // 输出电压采样
    M = (N * Vout_Target) / Vin;         // 电压传输比

    // ---------- 2. 电压环 PI 计算 Dc ----------
    float error = Vout_Target - Vout;
    Dc = PI_Controller(error);
    Dc = clamp(Dc, 0.0f, 1.5f);         // 限制 Dc 范围

    // ---------- 3. 模式判断与计算 ----------
    if (M < 1.0f) {
        // ===== 降压模式 =====
        if (Dc >= 1.0f) {
            // 重载 HLS: 式(3-21),退化为 SPS
            Dp0 = 0; Ds0 = 0;
            Dss = calc_Dss_HLS(Dc, M);
        } else if (Dc >= M) {
            // 中载 MLS: 式(3-19),固定 Ds0=0
            Ds0 = 0;
            Dp0 = Dc;                    // 示例映射,可标定
            Dss = calc_MLS_lt1(Dp0, M);
        } else {
            // 轻载 LLS: 式(3-13),消除环流
            Dp0 = 1.0f - Dc;            // 示例映射,可标定
            Ds0 = 1.0f - (1.0f - Dp0) / M;
            Dss = Dp0 - Ds0;             // 满足 Dss + Ds0 = Dp0
        }
    } else {
        // ===== 升压模式 =====
        float invM = 1.0f / M;
        if (Dc >= 1.0f) {
            // 重载 HLS: 式(3-27),退化为 SPS
            Dp0 = 0; Ds0 = 0;
            Dss = calc_Dss_HLS(Dc, M);
        } else if (Dc >= invM) {
            // 中载 MLS: 式(3-25),固定 Dp0=0
            Dp0 = 0;
            Ds0 = Dc * invM;             // 示例映射,可标定
            Dss = calc_MLS_gt1(Ds0, M);
        } else {
            // 轻载 LLS: 式(3-23),消除环流
            Dss = 0;
            Ds0 = Dc * M;                // 示例映射,可标定
            Dp0 = 1.0f - M * (1.0f - Ds0);
        }
    }

    // ---------- 4. 最终限幅保护 ----------
    Dss = clamp(Dss, 0.0f, 0.5f);
    Dp0 = clamp(Dp0, 0.0f, 1.0f);
    Ds0 = clamp(Ds0, 0.0f, 1.0f);

    // ---------- 5. 更新 PWM ----------
    Update_PWM(Dss, Dp0, Ds0);
}

四、工况判断流程图

                    ┌──────────────────┐
                    │   采样 Vin, Vout   │
                    └────────┬─────────┘
                             ▼
                    ┌──────────────────┐
                    │   计算 M = N·Vref/Vin │
                    └────────┬─────────┘
                             ▼
                    ┌──────────────────┐
                    │   电压环 PI → Dc   │
                    └────────┬─────────┘
                             ▼
              ┌─────────────┴─────────────┐
              ▼                               ▼
        M < 1 ? ─── 是                     否 ──── M ≥ 1
              │                               │
              ▼                               ▼
    ┌─────────────────┐               ┌──────────────────┐
    │ Dc ≥ 1 ?       │               │ Dc ≥ 1 ?         │
    └──┬───────┬─────┘               └──┬───────┬───────┘
       ▼       ▼                          ▼       ▼
     是        否                        是        否
       │       │                          │       │
       ▼       ▼                          ▼       ▼
    重载     Dc ≥ M ?                  重载    Dc ≥ 1/M ?
    SPS      │                          SPS     │
             ▼                                   ▼
          是   否                               是   否
           │    │                                │    │
           ▼    ▼                                ▼    ▼
        中载  轻载                             中载  轻载
        MLS   LLS                               MLS   LLS
    (Ds0=0)  (消环流)                      (Dp0=0)  (消环流)

五、调试与标定技巧

5.1 分步验证 checklist

步骤 操作 预期结果
1 设定 M=1M=1M=1(输入输出电压经匝比匹配) 全范围应走重载分支,输出标准 SPS 方波
2 观察重载波形 Dp0=Ds0=0D_{p0}=D_{s0}=0Dp0=Ds0=0DssD_{ss}Dss 随负载平滑变化,电流波形正弦度好
3 逐步减小负载进入中载区 Ds0D_{s0}Ds0(或 Dp0D_{p0}Dp0)变为 0,电流有效值明显下降
4 进入轻载区 出现零电流区间(ZCS),环流被抑制

5.2 边界滞环防抖

Dc=MD_c = MDc=MDc=1/MD_c = 1/MDc=1/M 的边界处,负载的微小抖动可能导致模式频繁切换。建议加入 0.02~0.05 的滞环:

#define HYST 0.02f

// 降压模式边界
if (mode_last == LIGHT && Dc > M + HYST)  switch_to_medium();
if (mode_last == MEDIUM && Dc < M - HYST) switch_to_light();

// 升压模式边界
if (mode_last == LIGHT && Dc > invM + HYST) switch_to_medium();
if (mode_last == MEDIUM && Dc < invM - HYST) switch_to_light();

5.3 性能优化:查表法替代开根号

如果你的 MCU 算力有限(比如主频较低的 STM32F1),中载区的开根号运算可能会成为瓶颈。此时可以离线将中载公式的计算结果制成二维查找表

# Python 离线生成查找表
import numpy as np

M_range = np.linspace(0.3, 0.9, 20)    # M 采样点
Dp0_range = np.linspace(0.0, 1.0, 50)  # Dp0 采样点

lut = np.zeros((20, 50))
for i, M in enumerate(M_range):
    for j, Dp0 in enumerate(Dp0_range):
        sq = Ds0**2 - 1.0f + M**2*(1.0f - Ds0)**2
        if sq < 0: sq = 0
        Dss =( (Dp0 - 1.0f + M + Dp0 * M) + np.sqrt(sq)) / (2*M)
        lut[i, j] = Dss

# 导出为 C 数组
print("const float lut_Dss[20][50] = {")
for i in range(20):
    print("  { " + ", ".join(f"{v:.6f}" for v in lut[i]) + " },")
print("};")

在 MCU 中用双线性插值查表,速度比实时开根号快一个数量级。

5.4 示波器观测要点

观测信号 正常表现 异常表现
vp(t)v_p(t)vp(t) 原边电压 三电平波形(轻载/中载)或两电平(重载) 波形畸变、占空比异常
iL(t)i_L(t)iL(t) 电感电流 轻载有零电流区间,中载梯形波,重载接近正弦 电流尖峰过大、有直流偏置
vp×iLv_p \times i_Lvp×iL 瞬时功率 正负面积比反映传输功率方向 大量负面积 = 环流严重

六、总结

DAB 的电流有效值最优化调制听起来很高大上,但对于嵌入式工程师来说,落地其实很简单:

步骤 动作 一句话
1 MMM 定方向:降压还是升压
2 DcD_cDc 定档位:轻载、中载还是重载
3 查表/套公式 重载必 SPS,中载固定一边,轻载消环流
4 限幅保护 防异常,保安全
5 写 PWM 完事

核心口诀:

MMM 定方向,DcD_cDc 定档位。重载一律用 SPS,中载固定一边调,轻载消除环流最省电。

把复杂的数学留给论文,把简洁的代码留给工程。希望这篇博客能帮助你在项目中快速实现高效的 DAB 控制。


附录:完整公式汇总表

A.1 降压工况 M<1M < 1M<1

(1−M)(1−Dp0)M\dfrac{(1-M)(1-D_{p0})}{M}M(1M)(1Dp0)

工况 完整公式 约束条件
轻载 (3-13) {Dss,opt=(1−M)(1−Dp0)MDs0,opt=1−1−Dp0,optM\begin{cases} D_{ss,opt} = \dfrac{(1-M)(1-D_{p0})}{M} \\ D_{s0,opt} = 1 - \dfrac{1 - D_{p0,opt}}{M} \end{cases} Dss,opt=M(1M)(1Dp0)Ds0,opt=1M1Dp0,opt Dp0∈[1−M,1]D_{p0} \in [1-M, 1]Dp0[1M,1]
中载 (3-19) {Ds0,opt=0Dss,opt=Dp0−1+M+MDp0+(1−M)2+M2(1−Dp02)2M\begin{cases} D_{s0,opt} = 0 \\ D_{ss,opt} = \dfrac{D_{p0}-1 +M+ MD_{p0} + \sqrt{(1-M)^2+ M^2(1-D_{p0}^2)}}{2M}\end{cases} Ds0,opt=0Dss,opt=2MDp01+M+MDp0+(1M)2+M2(1Dp02) Dp0∈[0,1−M]D_{p0} \in [0, 1-M]Dp0[0,1M]
重载 (3-21) {Dp0,opt=0Ds0,opt=0\begin{cases} D_{p0,opt} = 0 \\ D_{s0,opt} = 0 \end{cases}{Dp0,opt=0Ds0,opt=0(仅 DssD_{ss}Dss 有效,SPS 调制) Dss∈[0.25,0.5]D_{ss} \in [0.25, 0.5]Dss[0.25,0.5]

A.2 升压工况 M>1M > 1M>1

工况 完整公式 约束条件
轻载 (3-23) {Dss,opt=0Dp0,opt=1−M(1−Ds0,opt)\begin{cases} D_{ss,opt} = 0 \\ D_{p0,opt} = 1 - M(1 - D_{s0,opt}) \end{cases}{Dss,opt=0Dp0,opt=1M(1Ds0,opt) Ds0∈[1−1/M,1]D_{s0} \in [1-1/M, 1]Ds0[11/M,1]
中载 (3-25) {Dp0,opt=0Dss,opt=1−Ds0−M+MDs0+Ds02−1+M2(1−Ds0)22\begin{cases} D_{p0,opt} = 0 \\ D_{ss,opt} = \dfrac{1 - D_{s0} - M + M D_{s0} + \sqrt{D_{s0}^2 - 1 + M^2(1-D_{s0})^2}}{2}\end{cases} Dp0,opt=0Dss,opt=21Ds0M+MDs0+Ds021+M2(1Ds0)2 Ds0∈[0,1−1/M]D_{s0} \in [0, 1-1/M]Ds0[0,11/M]
重载 (3-27) {Dp0,opt=0Ds0,opt=0\begin{cases} D_{p0,opt} = 0 \\ D_{s0,opt} = 0 \end{cases}{Dp0,opt=0Ds0,opt=0(仅 DssD_{ss}Dss 有效,SPS 调制) Dss∈[0.25,0.5]D_{ss} \in [0.25, 0.5]Dss[0.25,0.5]

如果这篇博客对你有帮助,欢迎点赞/收藏/转发。有任何问题或建议,欢迎在评论区交流!

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐