This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F280025C:3个 ePWM 之间的相移有问题

Guru**** 2348500 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1054743/tms320f280025c-problem-with-phase-shift-between-3-epwms

器件型号:TMS320F280025C

大家好!  

配置3个 ePWM 之间的相移以驱动3个升压功率级时遇到问题。

我希望每个 ePWM 具有120°相移(相位是输入用户)。 我将 EPWM1配置为主器件、将 EPWM2和 EPWM3配置为从器件。 但在我的示波器上、我看到每相60°、而不是120°。  请你解释一下。 为什么它不能正常工作?

谢谢。

void epwm_init(uint32_t base)
{
    float PWM_TBPRD_1;
    float PWM_TBPRD_2;
    float PWM_TBPRD_3;
    float PWM_CMPA_1;
    float PWM_CMPA_2;
    float PWM_CMPA_3;
    EPWM_ClockDivider PWM_PARAM_PRESCALER;
    EPWM_HSClockDivider PWM_PARAM_HIGHSPEEDPRESCALER;
    float TBCLK;

    if(base == myEPWM1_BASE)
    {
        get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);

        // Parameters
        EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_1);
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, (uint16_t)PWM_CMPA_1);
        EPWM_setPhaseShift(base, 0U);
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setTimeBaseCounter(base, 0U);
        EPWM_enableSyncOutPulseSource(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
    }

    else if (base == myEPWM2_BASE)
    {
        get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);

        // Parameters
        EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_2);
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_2);
        EPWM_setPhaseShift(base, 0U);
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setTimeBaseCounter(base, 0U);
        EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);

        set_phase(base, PHI);

    }

    else if(base == myEPWM3_BASE)
    {
        get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);

        // Parameters
        EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_3);
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_3);

        EPWM_setPhaseShift(base, 0U);
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setTimeBaseCounter(base, 0U);

        EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
        //EPWM_enableSyncOutPulseSource(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
        set_phase(base, PHI);

    }

    //EPWM_setTimeBaseCounter(base, 0U);
    EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP_DOWN);

    EPWM_setClockPrescaler(base, PWM_PARAM_PRESCALER, PWM_PARAM_HIGHSPEEDPRESCALER);

    // Set up shadowing
    EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);

    // Set actions
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);

    // Trip zone
    // Configure ePWM1x to output low on TZx TRIP
    EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
    EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);
    // Trigger event when DCBH is high
    EPWM_setTripZoneDigitalCompareEventCondition(base, EPWM_TZ_DC_OUTPUT_B1, EPWM_TZ_EVENT_DCXH_HIGH);
    // Configure DCBH to use TRIP4 as an input
    EPWM_enableDigitalCompareTripCombinationInput(base, EPWM_DC_COMBINATIONAL_TRIPIN4, EPWM_DC_TYPE_DCBH);
    // Enable DCB as OST
    EPWM_enableTripZoneSignals(base, EPWM_TZ_SIGNAL_DCBEVT1);
    // Configure the DCB path to be unfiltered and asynchronous
    EPWM_setDigitalCompareEventSource(base, EPWM_DC_MODULE_B, EPWM_DC_EVENT_1, EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);

    // Clear trip flags
    EPWM_clearTripZoneFlag(base, EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_OST);

    // Calculate delays
    get_delays_FED_RED(myEPWM1_BASE, &TBCLK);
    get_delays_FED_RED(myEPWM2_BASE, &TBCLK);
    get_delays_FED_RED(myEPWM3_BASE, &TBCLK);
}
void set_phase(uint32_t base, uint16_t phi)
{
    uint16_t phase;

    if(base == myEPWM2_BASE)
    {
        phase = ((float)phi * HWREGH(base + EPWM_O_TBPRD) / 360);
    }

    if(base == myEPWM3_BASE)
    {
        phase = ((float)phi * HWREGH(base + EPWM_O_TBPRD) * 2 / 360); 
    }

    //EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_SYNC);
    EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
    EPWM_forceSyncPulse(base);

    EPWM_setPhaseShift(base, phase);
    EPWM_setTimeBaseCounter(base, phase);
    EPWM_enablePhaseShiftLoad(base);
}

Damien

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可以看到另一个函数、用于根据所需的频率和占空比计算 TBPRD 和 CMPA。 很抱歉我的英语水平! 如果我正确理解 TBPHS 最大值= TBPRD 最大值并且我确定这些值。 TBPRD 和 CMPA 正确。  

    例如、如果我希望 PWM1和 PWM2之间的相移为90°、PWM1和 PWM3之间的相移为180°

    => TBPHS (主器件 PWM1)= 0

    => TBPHS (从器件 PWM2)=((相位= 90°)* TBPRD)/ 360;在我的案例中 TBPRD = 156、因此 TBPHS = 39

    => TBPHS (从器件 PWM3)=((相位= 180°)* TBPRD)/360在我的案例中 TBPRD = 156、因此 TBPHS = 78

    可以帮帮我吗? 我的错在哪里?  

    谢谢

    Damien

    void set_phase(uint32_t base, uint16_t phi)
    {
        uint16_t phase;
    
        if(base == myEPWM2_BASE)
        {
            phase = ((float)phi * HWREGH(base + EPWM_O_TBPRD) / 360);
        }
    
        if(base == myEPWM3_BASE)
        {
            phase = ((float)phi * HWREGH(base + EPWM_O_TBPRD) * 2 / 360);
        }
    
        //EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_SYNC);
        EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_forceSyncPulse(base);
    
        EPWM_setPhaseShift(base, phase);
        EPWM_setTimeBaseCounter(base, phase);
        EPWM_enablePhaseShiftLoad(base);
    }
    *TBPRD_boost_3 = PWM_Freq_TBCLK / (PWM_FREQ * 2);
    *CMPA_boost_3 = ((float) (100 - duty_boost_3) / 100) * (*TBPRD_boost_3);

    void epwm_init(uint32_t base)
    {
        float PWM_TBPRD_1;
        float PWM_TBPRD_2;
        float PWM_TBPRD_3;
        float PWM_CMPA_1;
        float PWM_CMPA_2;
        float PWM_CMPA_3;
        EPWM_ClockDivider PWM_PARAM_PRESCALER;
        EPWM_HSClockDivider PWM_PARAM_HIGHSPEEDPRESCALER;
        float TBCLK;
    
        if(base == myEPWM1_BASE)
        {
            get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
    
            // Parameters
            EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_1);
            EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, (uint16_t)PWM_CMPA_1);
            EPWM_setPhaseShift(base, 0U);
            EPWM_disablePhaseShiftLoad(base);
            EPWM_setTimeBaseCounter(base, 0U);
            EPWM_enableSyncOutPulseSource(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
        }
    
        else if (base == myEPWM2_BASE)
        {
            get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
    
            // Parameters
            EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_2);
            EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_2);
            EPWM_setPhaseShift(base, 0U);
            EPWM_disablePhaseShiftLoad(base);
            EPWM_setTimeBaseCounter(base, 0U);
            EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
    
            set_phase(base, PHI);
    
        }
    
        else if(base == myEPWM3_BASE)
        {
            get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
    
            // Parameters
            EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_3);
            EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_3);
    
            EPWM_setPhaseShift(base, 0U);
            EPWM_disablePhaseShiftLoad(base);
            EPWM_setTimeBaseCounter(base, 0U);
    
            EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
    
            set_phase(base, PHI);
    
        }
    
        //EPWM_setTimeBaseCounter(base, 0U);
        EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP_DOWN);
    
        EPWM_setClockPrescaler(base, PWM_PARAM_PRESCALER, PWM_PARAM_HIGHSPEEDPRESCALER);
    
        // Set up shadowing
        EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        // Set actions
        EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    
        // Trip zone
        // Configure ePWM1x to output low on TZx TRIP
        EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
        EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);
        // Trigger event when DCBH is high
        EPWM_setTripZoneDigitalCompareEventCondition(base, EPWM_TZ_DC_OUTPUT_B1, EPWM_TZ_EVENT_DCXH_HIGH);
        // Configure DCBH to use TRIP4 as an input
        EPWM_enableDigitalCompareTripCombinationInput(base, EPWM_DC_COMBINATIONAL_TRIPIN4, EPWM_DC_TYPE_DCBH);
        // Enable DCB as OST
        EPWM_enableTripZoneSignals(base, EPWM_TZ_SIGNAL_DCBEVT1);
        // Configure the DCB path to be unfiltered and asynchronous
        EPWM_setDigitalCompareEventSource(base, EPWM_DC_MODULE_B, EPWM_DC_EVENT_1, EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);
    
        // Clear trip flags
        EPWM_clearTripZoneFlag(base, EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_OST);
    
        // Calculate delays
        get_delays_FED_RED(myEPWM1_BASE, &TBCLK);
        get_delays_FED_RED(myEPWM2_BASE, &TBCLK);
        get_delays_FED_RED(myEPWM3_BASE, &TBCLK);
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、如果您使用向上/向下计数模式、则 PWM 周期将是配置的周期值的两倍。 因此、您需要相应地调整相移。
    请注意、您还可以在相位同步期间设置计数器方向(使用 PHSDIR 位)。
    因此、对于需要240deg 的相位、您必须使用 PHSDIR 反转方向。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 

    感谢您的回复。 如果我理解正确,我们必须反转方向,因为 TBPHS 的值将超过最大 TBPRD ? 是否可以通过 driverlib 函数来反转方向? 还是仅按位字段?

    谢谢  

    Damien

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     您可以使用 driverlib 函数 PWM_setPhaseDir 来设置同步时的相位方向。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我找不到您的函数、但找到了该函数"ePWM_setCountModeAfterSync (myEPWM3_base、ePWM_COUNT_MODE_UP_After_SYNC)"。 当我希望 ePWM2°180°、而在 ePWM3上自然相位> 180°时、它不起作用

    您能不能向我解释一下、在向上 和向下计数模式下、如何在 EPWM2和 EPWM3上实现更大的相位?

    谢谢

    Damien

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可以看到屏幕截图。 为什么当我设置相位= 120°时、ePWM2在 ePWM1和 ePWM3的正确相移情况下正常? 能不能更详细地解释一下?

    谢谢

    我的代码:  

    void set_phase(uint32_t base, uint16_t phi)
    {
        uint16_t phase;
    
        if(base == myEPWM2_BASE)
        {
            //EPWM_setCountModeAfterSync(base, EPWM_COUNT_MODE_UP_AFTER_SYNC);
            phase = ((float)phi * HWREGH(base + EPWM_O_TBPRD) * 2 / 360); // *2 to adapt scale on UP and DOWN Count mode
        }
    
        if(base == myEPWM3_BASE)
        {
            //EPWM_setCountModeAfterSync(base, EPWM_COUNT_MODE_UP_AFTER_SYNC);
            phase = ((float)phi * 2 * HWREGH(base + EPWM_O_TBPRD) * 2 / 360);
        }
    
        EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
        EPWM_forceSyncPulse(base);
    
        EPWM_setPhaseShift(base, phase);
        EPWM_setTimeBaseCounter(base, phase);
        EPWM_enablePhaseShiftLoad(base);
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    对于 PWM3、您需要设置 PHSDIR。 该函数应该设置该位、但会将其注释掉。

      //ePWM_setCountModeAfterSync (base、ePWM_COUNT_MODE_UP_After_SYNC);

    这决定了计数器在 EPWM3的 SYNC 之后计数的方向。 请根据所需的相移设置所需的方向和相位。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好  

    很抱歉、我迟到了响应、最后我将 TBCTR 寄存器设置为向上计数模式、因为它在同步后不能在计数模式下工作。

    我继续进行我的项目、稍后我将回到这个问题。

    谢谢!

    Damien

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    谢谢你。 我们现在将关闭此主题、如果您再次看到任何问题、您可以稍后启动新主题。