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

一、问题现象描述

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

使用传统的三相电流重构算法,在高调制率 (大约大于 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 电流的采样波形

相关推荐
蓬荜生灰3 小时前
STM32(12)-- GPIO输入,按键检测
stm32·单片机·嵌入式硬件
DLGXY3 小时前
STM32——ADC、多通道转换(十三)
stm32·单片机·嵌入式硬件
日更嵌入式的打工仔3 小时前
嵌入式MPU、MCU与SoC的本质区别
单片机·嵌入式硬件
__万波__3 小时前
STM32L475看门狗
stm32·单片机·嵌入式硬件
wanglong37134 小时前
51单片机STC8G1K08输出PWM
单片机·嵌入式硬件·51单片机
传感器与混合集成电路14 小时前
210℃与175℃高温存储器选型研究:LHM256MB与LDMF4GA-H架构与可靠性对比(上)
嵌入式硬件·能源
时光找茬15 小时前
【瑞萨AI挑战赛-FPB-RA6E2】+ 从零开始:FPB-RA6E2 开箱测评与 e2 studio 环境配置
c++·单片机·边缘计算
17(无规则自律)15 小时前
【CSAPP 读书笔记】第二章:信息的表示和处理
linux·嵌入式硬件·考研·高考
@good_good_study16 小时前
FreeRTOS内存管理
单片机