永磁同步电机下桥三电阻采样方式的电机电流重构方法

一、问题现象描述

在某些应用场景如空调,电动自行车,水泵等,因为成本的关系,通常使用基于下桥的三相电阻采样方案,此时只有下桥开通时才有电流流过检流电阻,因此只有在下桥开通时才能采样到有效电流。

使用传统的三相电流重构算法,在高调制率 (大约大于 80%) 时因下桥开通时间太短,所以无法采到有效三相电流,从而导致电机无法正常运行。
母线为 5A 电流的采样波形

此时通常通过限制调制率 (也就是将三项的 PWM 峰值控制在一定范围内) 的方法来保证电机可靠运行,但这样会限制母线电压利用率,从而影响电机运行效率。

二、相位选择处理

2.1 原理解析

下图为下桥三相 PWM 控制输出波形:

较为简单常用的办法是:

当 T1 <= T2 和 T3 时,只采样 U 相和 V 相电流,那么 W 相电流也就等于:

  • = W 相电流
  • = U 相电流
  • = V 相电流

当 T2 <= T1 和 T3 时,只采样 U 相和 W 相电流,那么 V 相电流也就等于:

当 T3 <= T1 和 T2 时,只采样 V 相和 W 相电流,那么 U 相电流也就等于:

2.2 代码演示

t_SVPWM_GenRegS.s32_DutyA 是 A 相上管的开管时间。

上管开管时间越长,下管开管时间越短,所以我们取上管开管最长的相不采集,使用互补计算,全部代码如下:

cpp 复制代码
f_MC_ADC_Channel_Change()
{
    uint8_t adc_sample = 0;

    if ((t_SVPWM_GenRegS.s32_DutyA <= t_SVPWM_GenRegS.s32_DutyC) && (t_SVPWM_GenRegS.s32_DutyA >= t_SVPWM_GenRegS.s32_DutyB))
    {
        adc_sample = 2;
    }
    else if ((t_SVPWM_GenRegS.s32_DutyB <= t_SVPWM_GenRegS.s32_DutyA) && (t_SVPWM_GenRegS.s32_DutyB >= t_SVPWM_GenRegS.s32_DutyC))
    {
        adc_sample = 3;
    }
    else if ((t_SVPWM_GenRegS.s32_DutyC <= t_SVPWM_GenRegS.s32_DutyA) && (t_SVPWM_GenRegS.s32_DutyC >= t_SVPWM_GenRegS.s32_DutyB))
    {
        adc_sample = 1;
    }

    if (adc_sample < 10)
    {
        switch (adc_sample)
        {
        case 1:
            s32_Temp_Phae_Cur_C = 0 - s32_Temp_Phae_Cur_A - s32_Temp_Phae_Cur_B;
            break;
        case 2:
            s32_Temp_Phae_Cur_A = 0 - s32_Temp_Phae_Cur_C - s32_Temp_Phae_Cur_B;
            break;
        case 3:
            s32_Temp_Phae_Cur_B = 0 - s32_Temp_Phae_Cur_A - s32_Temp_Phae_Cur_C;
            break;
        }
    }
}

2.3 效果演示

在使用相位选择的逻辑后,我们的采样波形略好一点,但仍然不是正弦波。
母线为 5A 电流的采样波形

三、采样窗口时间选择

3.1 中心对齐模式

我们使用中心对齐模式进行 PWM 波形的输出。

在凌欧的芯片中,PWM 中心对齐模式是从负数开始计数的。

假设 m_EPWM_PERIOD 是PWM 定时器在中心对齐模式下的半周期计数值,那么我们整个就是就是这样的规律:

    • EPWM_PERIOD (起始点) → 0 (中心点) → + EPWM_PERIOD (结束点)

3.2 采样窗口选择

在选择每个PWM 周期的采样窗口 (采样时刻) 时,并不是下管打开的时候就是最佳的采样时刻。

而是应该避开:

  • 刚发生 PWM 翻转 (dv/dt、di/dt)
  • 死区刚结束 / 管子刚导通
  • 电流振铃还没消

一个采样窗口是 某一相导通且电流稳定的最小连续时间。

这个时间至少要包含,振铃时间、死区/开管时间、ADC采样保持时间。当我们

3.1 三项完整窗口采样

如果我们有一个完整的采样窗口,也就是:

  • = PWM 周期计数
  • = 三项中最大的计数
  • = 窗口时间 (振铃、死区和开关管时间)

很显然,我们最佳的采样的时间是 PWM 周期中的起始点,这里举例开关管的振铃最小,因为我们是中心对齐模式,所以在公式上,我们采样窗口就是:

也就是每个 PWM 周期的起点采样,采样时刻如下图所示:

3.2 三项半个窗口采样

如果我们 PWM 在开始不足一个采样窗口,但是大于半个窗口:

  • = PWM 周期计数
  • = 三项中最大的计数
  • = 窗口时间 (振铃、死区和开关管时间)

此时我们的采样方式计算为:

也就是下图这个区域:

3.3 两项完整窗口采样

如果三项半个窗口都不满足,我们只能在两项窗口区采集。

3.4 全部代码

我们把两种采样方式融合到一个函数中:

cpp 复制代码
f_MC_ADC_Channel_Change()
{
    uint8_t adc_sample = 0;

    if ((t_SVPWM_GenRegS.s32_DutyA <= t_SVPWM_GenRegS.s32_DutyC) && (t_SVPWM_GenRegS.s32_DutyA >= t_SVPWM_GenRegS.s32_DutyB))
    {
        adc_sample = 2;
    }
    else if ((t_SVPWM_GenRegS.s32_DutyB <= t_SVPWM_GenRegS.s32_DutyA) && (t_SVPWM_GenRegS.s32_DutyB >= t_SVPWM_GenRegS.s32_DutyC))
    {
        adc_sample = 3;
    }
    else if ((t_SVPWM_GenRegS.s32_DutyC <= t_SVPWM_GenRegS.s32_DutyA) && (t_SVPWM_GenRegS.s32_DutyC >= t_SVPWM_GenRegS.s32_DutyB))
    {
        adc_sample = 1;
    }

    if (adc_sample < 10)
    {
        switch (adc_sample)
        {
        case 1:
            s32_Temp_Phae_Cur_C = 0 - s32_Temp_Phae_Cur_A - s32_Temp_Phae_Cur_B;
            break;
        case 2:
            s32_Temp_Phae_Cur_A = 0 - s32_Temp_Phae_Cur_C - s32_Temp_Phae_Cur_B;
            break;
        case 3:
            s32_Temp_Phae_Cur_B = 0 - s32_Temp_Phae_Cur_A - s32_Temp_Phae_Cur_C;
            break;
        }
    }

#define RINGING_TIME 2 // 振铃
#define TON_TIME 2     // 死区加开管时间
#define SAMPLE_TIME 1  // 采样+关管时间

    if ((m_EPWM_PERIOD - tmax) > ((RINGING_TIME + TON_TIME) * PWM_1US)) 
    {
        temp = 1 - m_EPWM_PERIOD;
        MCPWM_TMR0 = (u16)(temp);
    }
    else if ((m_EPWM_PERIOD - tmax) > (((RINGING_TIME + TON_TIME) + SAMPLE_TIME) / 2 * PWM_1US))
    {
        temp = ((RINGING_TIME + TON_TIME) * PWM_1US + tmax - m_EPWM_PERIOD * 2 + 1);
        if (temp < 1 - m_EPWM_PERIOD)
            temp = 1 - m_EPWM_PERIOD;
    }
    else
    {
        if ((tmax - tmin) > (((RINGING_TIME + TON_TIME) + SAMPLE_TIME) * PWM_1US /* - 30*/)) 
        {
            temp = ((-tmax) + ((RINGING_TIME + TON_TIME) * PWM_1US));
            t1 = temp;
            if (temp < 1 - m_EPWM_PERIOD)
                temp = 1 - m_EPWM_PERIOD;
            MCPWM_TMR0 = (uint16_t)temp;
        }
        else // 无法采样
        {
            temp = 1 - m_EPWM_PERIOD;
            MCPWM_TMR0 = (u16)(temp);
            adc_sample += 0x10;
        }
    }
}

3.5 效果演示

可见,较为完整的还原出了正弦波:
母线为 5A 电流的采样波形

相关推荐
半空扫地僧一枚5 分钟前
10期:转速模式 (Speed Mode) 和 扭矩模式 (Torque Mode)
单片机·嵌入式硬件·汽车
爱上珍珠的贝壳3 小时前
ESP32-S3-CAM:接MAX98357A+喇叭播放音频
嵌入式硬件·音频·esp32-s3·喇叭·max98357a
敬畏_上帝3 小时前
PCtolLCD2002完美版下载以及教程
单片机·嵌入式硬件
学嵌入式的小杨同学4 小时前
STM32 进阶封神之路(五):库函数移植全解析 —— 从底层原理到移植实操(含环境适配 + 报错解决)
vscode·单片机·嵌入式硬件·代理模式·智能硬件·pcb工艺·嵌入式实时数据库
天月风沙4 小时前
幻尔总线舵机测试板BusLinker V2.5 控制代码
单片机·嵌入式硬件·机器人·舵机
somi75 小时前
51单片机-01-基础概念
单片机·嵌入式硬件·学习·51单片机
✎ ﹏梦醒͜ღ҉繁华落℘5 小时前
单片机基础知识 -- TFT-LCD
单片机·嵌入式硬件
Hello_Embed5 小时前
LVGL 入门(一):环境搭建与源码获取
笔记·stm32·单片机·嵌入式·lvgl
v先v关v住v获v取6 小时前
CC1031载货汽车后轮制动器设计6张cad+设计说明书+三维图
科技·单片机·51单片机
孤芳剑影6 小时前
Cadence Allegro 如何修改板框大小
嵌入式硬件