4. 基于电流极性的死区补偿:三相电流极性判断、补偿电压计算、实现流程

死区补偿这个话题,说实话,很多做FOC的工程师都绕不过去。我记得刚入行那会儿,调一个电机驱动板,空载波形看着挺漂亮,一带负载就出现明显的电流畸变,转矩脉动大得吓人。折腾了两天,最后发现是死区效应在作祟。从那以后,我对死区补偿这块就特别上心。

今天咱们聊的这种方法——基于电流极性的死区补偿,是工程中最常用、也最直观的一种。说白了,就是根据三相电流的方向,判断当前该补多少电压,然后把这个电压加回去。

4.1 死区效应是怎么产生的?

先简单回顾一下。死区时间,是上下桥臂开关管切换时,为了防止直通而插入的一段“同时关断”的时间。在这段时间里,电流通过续流二极管续流。

问题出在哪呢?

  • 死区时间内,输出电压不受PWM控制,而是由电流方向决定。
  • 电流从负载流向母线(正电流)时,下管续流二极管导通,输出被拉到负母线。
  • 电流从母线流向负载(负电流)时,上管续流二极管导通,输出被拉到正母线。

结果就是:实际输出电压和理想PWM指令之间,产生了一个偏差。这个偏差和电流方向有关,和死区时间有关,也和开关频率有关。

核心结论:死区效应导致的电压误差,方向与电流极性相反,大小等于 Vdc * Tdead * fsw(母线电压 × 死区时间 × 开关频率)。

嗯,这里要注意:这个公式是理想情况,实际中还要考虑管压降、导通电阻等因素。但作为补偿的基准,完全够用。

4.2 三相电流极性判断

补偿的第一步,就是判断电流极性。听起来简单,做起来有不少坑。

直接采样法:

最直接的办法,就是用ADC采样三相电流,然后判断正负。但实际中,电流信号往往有噪声,尤其是在过零点附近,一个抖动就会导致极性误判。

我个人的习惯做法:

  1. 加滞回比较:设置一个阈值(比如额定电流的1%~2%),电流绝对值小于这个阈值时,保持上一次的极性判断结果。
  2. 软件滤波:对采样值做一阶低通滤波,截止频率设到几百赫兹就行,不影响动态响应。
  3. 结合PWM同步:在PWM的特定时刻(比如下管导通中点)采样,这时候电流纹波最小,信噪比最高。

避坑指南:我曾经在一个项目里,直接用原始ADC值判断极性,结果在电流过零时,补偿电压来回跳变,导致电机在低速时发出“嗡嗡”的噪声。后来加了滞回,问题立刻解决。

代码示例:电流极性判断(带滞回)

// 电流极性判断,带滞回
typedef enum {
    POLARITY_POSITIVE = 1,
    POLARITY_NEGATIVE = -1,
    POLARITY_ZERO = 0
} Polarity_t;

Polarity_t Current_Polarity_Detect(float current, float threshold) {
    static Polarity_t last_polarity = POLARITY_ZERO;
    
    if (current > threshold) {
        last_polarity = POLARITY_POSITIVE;
    } else if (current < -threshold) {
        last_polarity = POLARITY_NEGATIVE;
    }
    // 在阈值范围内,保持上一次结果
    return last_polarity;
}

4.3 补偿电压计算

知道了电流极性,补偿电压就好算了。基本公式如下:

补偿电压 = 极性符号 × 死区补偿幅值

其中:

  • 极性符号:电流为正时取+1,为负时取-1。
  • 死区补偿幅值Vcomp = Vdc * Tdead * fsw

但实际工程中,我建议你考虑两个修正因素:

修正因素 说明 典型值
管压降 IGBT或MOSFET导通时的饱和压降,以及续流二极管的压降 0.7V~2V(视器件而定)
导通电阻 开关管导通电阻引起的压降,与电流大小成正比 几毫欧到几十毫欧

修正后的补偿电压:

Vcomp = Vdc * Tdead * fsw + Vf + I * Rds_on

其中Vf是续流二极管压降,Rds_on是导通电阻,I是当前相电流。

注意:管压降和导通电阻的修正,在低压大电流场合(比如48V系统)特别重要。母线电压越低,死区补偿的占比越大,忽略这些因素会导致补偿不足或过补。

4.4 实现流程

整个实现流程,我画了一张图,方便你理解:

基于电流极性的死区补偿实现流程 1. 采样三相电流 2. 软件滤波 + 滞回比较 3. 判断电流极性 4. 计算补偿电压 5. 叠加到PWM占空比 ADC同步采样 消除噪声干扰 带滞回,防抖动 Vcomp = Vdc*Tdead*fsw + 修正 在SVPWM输出前叠加

流程看起来不复杂,但每一步都有细节。我展开说一下:

4.5 实现中的关键细节

1. 补偿时机

补偿电压应该在SVPWM计算之后、占空比更新之前叠加。具体来说:

  • 先算出三相的占空比(Ta, Tb, Tc)
  • 根据电流极性,算出每相需要补偿的占空比增量
  • 叠加后,再写入PWM比较寄存器

2. 补偿限幅

叠加后的占空比不能超过0~1的范围。我曾经遇到过,补偿量太大导致占空比溢出,电机反而失控。所以一定要做限幅处理:

// 补偿后限幅
Ta_comp = Ta + delta_Ta;
if (Ta_comp > 1.0f) Ta_comp = 1.0f;
if (Ta_comp < 0.0f) Ta_comp = 0.0f;

3. 低速时的特殊处理

电机转速很低时,反电动势很小,死区效应的影响相对更大。这时候补偿要更精确。我的做法是:

  • 在低速段(比如低于额定转速的5%),适当增大滞回阈值,防止极性频繁跳变
  • 同时,补偿幅值可以稍微降低一点(比如乘以0.9),避免过补导致电流振荡

经验之谈:死区补偿不是越精确越好。有时候,稍微欠补一点,系统的稳定性反而更好。我见过有人把补偿算得特别准,结果电流波形上出现了高频振荡。后来把补偿系数从1.0降到0.85,问题就消失了。

4.6 完整代码框架

最后,给出一段完整的死区补偿实现框架,你可以直接参考:

// 死区补偿主函数
void DeadTime_Compensation(float Ia, float Ib, float Ic, 
                           float *Ta, float *Tb, float *Tc) {
    // 1. 电流极性判断(带滞回)
    Polarity_t Pa = Current_Polarity_Detect(Ia, 0.02f);
    Polarity_t Pb = Current_Polarity_Detect(Ib, 0.02f);
    Polarity_t Pc = Current_Polarity_Detect(Ic, 0.02f);
    
    // 2. 计算补偿占空比增量
    float Vdc = Get_Bus_Voltage();
    float Tdead = 2e-6f;  // 2us死区
    float fsw = 10e3f;    // 10kHz开关频率
    float Vcomp = Vdc * Tdead * fsw;
    float delta_D = Vcomp / Vdc;  // 转换为占空比增量
    
    // 3. 叠加补偿(注意极性)
    *Ta += (float)Pa * delta_D;
    *Tb += (float)Pb * delta_D;
    *Tc += (float)Pc * delta_D;
    
    // 4. 限幅
    *Ta = CLAMP(*Ta, 0.0f, 1.0f);
    *Tb = CLAMP(*Tb, 0.0f, 1.0f);
    *Tc = CLAMP(*Tc, 0.0f, 1.0f);
}

好了,基于电流极性的死区补偿,核心内容就这些。说白了就是三步:判断极性、算补偿量、叠加上去。但每一步都有工程上的坑,希望我今天分享的这些经验,能帮你少走一些弯路。

最后提醒一句:调试死区补偿时,最好先用电流探头观察相电流波形。补偿到位的话,电流过零点附近的畸变会明显改善,转矩脉动也会减小。如果发现补偿后波形反而变差了,先检查极性判断是否正确,再检查补偿幅值是否合适。


公众号:蓝海资料掘金营,微信deep3321