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:使 EPWMy 上的 ePWMx 与每个 ePWM 同步一个频率

Guru**** 2412100 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1161778/tms320f280025c-synchronize-epwmx-on-epwmy-with-one-frequency-per-epwm

器件型号:TMS320F280025C

您好!

我有一个问题、我配置了两个以不同频率运行的 ePWM、我希望它们同相。 我希望 SPWM_U (EPWM1_BASE)上触发 SPWM_for_ADC (EPWM7_BASE)。 我一定忘记了配置、能帮我吗?

谢谢  

Damien

void epwm_init(uint32_t base)
{
    /**Parameters*/
    EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP);
    EPWM_setTimeBaseCounter(base, 0U);
    EPWM_setClockPrescaler(base, EPWM_CLOCK_DIVIDER_4, EPWM_HSCLOCK_DIVIDER_4);
    /**Set up shadowing*/
    EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    /**Set actions
    For boost assembly*/
    EPWM_setActionQualifierAction(base, SPWM_TOP, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(base, SPWM_TOP, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    /**For buck assembly*/
    EPWM_setActionQualifierAction(base, SPWM_BOT, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    EPWM_setActionQualifierAction(base, SPWM_BOT, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
}

void epwm_settings(uint32_t base)
{
    if((base == SPWM_U) ||
       (base == SPWM_V) ||
       (base == SPWM_W))
    {
        //for test
        EPWM_setCounterCompareValue(SPWM_U, EPWM_COUNTER_COMPARE_B, 78);
        EPWM_setCounterCompareValue(SPWM_V, EPWM_COUNTER_COMPARE_B, 78);
        EPWM_setTimeBasePeriod(base, EPWM_TBPRD);
    }
    else if(base == SPWM_FOR_ADC)
    {
        EPWM_setCounterCompareValue(SPWM_FOR_ADC, EPWM_COUNTER_COMPARE_A, 78);//CMPA_EPWM_ADC
        EPWM_setTimeBasePeriod(SPWM_FOR_ADC, 156);//EPWM_TBPRD_ADC
    }
    else if(base == SPWM_REGU)
    {
        EPWM_setTimeBasePeriod(base, EPWM_TBPRD_REGU);
        /**Initialize PWM to regulation interrupt*/
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, CMPA_EPWM_REGU);
        /// Interrupt where we will change the Compare Values
        /// Select INT on Time base counter zero event,
        /// Enable INT, generate INT on 1rd event
        EPWM_setInterruptSource(base, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(base);
        EPWM_setInterruptEventCount(base, 1U);
    }
}

void epwm_set_phase(uint32_t base, uint16_t phi)
{
    /**Configure ePMWs*/
    // Todo comments to explain
    if(phi == 0)
    {
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setPhaseShift(base, phi);
        EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
    }
    else
    {
        uint16_t tbphs = epwm_get_tbphs_from_phi(base, phi);
        EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
        EPWM_enablePhaseShiftLoad(base);
        EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_SYNC);
        EPWM_setPhaseShift(base, tbphs);
        EPWM_setTimeBaseCounter(base, tbphs);
    }
}

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

    我认为同步脉冲的生成有问题?

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

    您好 Damien、

    假设在初始化期间正确调用了这些函数中的每一个、我在这里注意到的第一件事是、如果您希望 ePWM 信号同相、即相移零、那么您的 ePWM_SET_PHASE 函数不知道如何处理该信号。 它似乎假定零漂移仅适用于初级 ePWM、而不是次级 ePWM。  如果这不是问题的根源、 我建议使用 CCS 的调试视图查看时基控制寄存器的内容、并查看其中显示的设置是否与您告知器件的操作相匹配。

    最后、如果以上都不能提供帮助、请告诉我您 在  ePWM 波形中看到的行为、而不是您想要看到的行为。

    希望这对您有所帮助、

    Jason Osborn

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

    您好 Jason、

    我可以更好地解释自己、实际上我已经配置了三个 EPWM 模块:SPWM_U、SPWM_V 和 SPWM_W、它们在相同的频率(40kHz)下工作、每个模块的相位差为120度、这与主器件 SPWM_U (EPWM1_base)有关。 这可以正常工作、但随后我在20kHz 频率下添加了另一个 EPWM、即 SPWM_for_ADC (EPWM7_BASE)、我希望它与 EPWM1_base 同相、并在示波器上直观地看到它们不是。 如果我以相同的频率运行它们、我只会观察它们同相。 我认为存在同步脉冲问题吗? 因为我将脉冲生成设置为0,如果它们的频率不相同,那么 SPWM_for_ADC 的切换将不会在正确的时间完成?

    谢谢

    Damien

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

    在我的代码中、如果我 在手头注释 EPWM_SET_PHASE 函数、它仍然不起作用。 我这样做是为了尽可能地隔离问题。 这是我在 main 中的代码:ePWM_SET_PHASE 函数被注释

        /**
         * ePWM initialization with phase shift
         */
        epwm_init(SPWM_U);               <-
        //epwm_init(SPWM_V);
        //epwm_init(SPWM_W);   
        epwm_init(SPWM_FOR_ADC);         <-
    
        epwm_settings(SPWM_U);           <-
        //epwm_settings(SPWM_V);
        //epwm_settings(SPWM_W);
        epwm_settings(SPWM_FOR_ADC);     <-
    
        //epwm_set_phase(SPWM_U, 0);
        //epwm_set_phase(SPWM_U, EPWM_PHI);
        //epwm_set_phase(SPWM_U, EPWM_PHI << 1);
        //epwm_set_phase(SPWM_FOR_ADC, 0);
    void epwm_init(uint32_t base)
    {
        /**Parameters*/
        EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBaseCounter(base, 0U);
        EPWM_setClockPrescaler(base, EPWM_CLOCK_DIVIDER_4, EPWM_HSCLOCK_DIVIDER_4);
        /**Set up shadowing*/
        EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        /**Set actions
        For boost assembly*/
        EPWM_setActionQualifierAction(base, SPWM_TOP, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(base, SPWM_TOP, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        /**For buck assembly*/
        EPWM_setActionQualifierAction(base, SPWM_BOT, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(base, SPWM_BOT, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    }
    
    void epwm_settings(uint32_t base)
    {
        /// To force command MOS ePWM at a low state.
        if((base == SPWM_U) ||
           (base == SPWM_V) ||
           (base == SPWM_W))
        {
            //for test
            EPWM_setCounterCompareValue(SPWM_U, EPWM_COUNTER_COMPARE_B, 78);
            EPWM_setCounterCompareValue(SPWM_V, EPWM_COUNTER_COMPARE_B, 78);
            EPWM_setTimeBasePeriod(base, EPWM_TBPRD);//EPWM_TBPRD
    
            /*EPWM_setActionQualifierContSWForceAction(SPWM_U, SPWM_BOT, EPWM_AQ_SW_OUTPUT_LOW);
            EPWM_setActionQualifierContSWForceAction(SPWM_V, SPWM_BOT, EPWM_AQ_SW_OUTPUT_LOW);*/
            EPWM_setActionQualifierContSWForceAction(SPWM_W, SPWM_BOT, EPWM_AQ_SW_OUTPUT_LOW);
            EPWM_setActionQualifierContSWForceAction(SPWM_U, SPWM_TOP, EPWM_AQ_SW_OUTPUT_LOW);
            EPWM_setActionQualifierContSWForceAction(SPWM_V, SPWM_TOP, EPWM_AQ_SW_OUTPUT_LOW);
            EPWM_setActionQualifierContSWForceAction(SPWM_W, SPWM_TOP, EPWM_AQ_SW_OUTPUT_LOW);
        }
        else if(base == SPWM_FOR_ADC)
        {
            EPWM_setCounterCompareValue(SPWM_FOR_ADC, EPWM_COUNTER_COMPARE_A, 155);//CMPA_EPWM_ADC
            EPWM_setTimeBasePeriod(SPWM_FOR_ADC, 311);//EPWM_TBPRD_ADC
        }
        else if(base == SPWM_REGU)
        {
            EPWM_setTimeBasePeriod(base, EPWM_TBPRD_REGU);
            /**Initialize PWM to regulation interrupt*/
            EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, CMPA_EPWM_REGU);
            /// Interrupt where we will change the Compare Values
            /// Select INT on Time base counter zero event,
            /// Enable INT, generate INT on 1rd event
            EPWM_setInterruptSource(base, EPWM_INT_TBCTR_ZERO);
            EPWM_enableInterrupt(base);
            EPWM_setInterruptEventCount(base, 1U);
        }
    }
    

    ePWM_SET_PHASE 函数:

    void epwm_set_phase(uint32_t base, uint16_t phi)
    {
        /**Configure ePMWs*/
        // Todo comments to explain
        if(phi == 0)
        {
            EPWM_disablePhaseShiftLoad(base);
            EPWM_setPhaseShift(base, phi);
            EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
        }
        else
        {
            uint16_t tbphs = epwm_get_tbphs_from_phi(base, phi);
            EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
            EPWM_enablePhaseShiftLoad(base);
            EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_SYNC);
            EPWM_setPhaseShift(base, tbphs);
            EPWM_setTimeBaseCounter(base, tbphs);
        }
    }

    谢谢

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

    很抱歉、我无法为您提供 oscillogram、但我看到信号 SPWM_for_ADC、该信号有时会在 ePWM_base (SPWM_U)上提前出现、有时会延迟

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

    您好 Damien、

    更确切地说、当您说您希望20kHz 信号与40kHz 信号同相时、您的意思是什么?

    此致、

    Jason Osborn

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

    我了解您的不确定性、并解释我的用途。 我正在设置数字控制、信号 EPWM1_base、EPWM2_base 和 EPWM4_base 用于控制半导体、我在频率低两倍的信号 ePWM7_BASE 上同步 ADC SOC、以便为我提供更多的控制时间。 但由于该信号 SPWM_for_ADC 在 EPWM1_base 上未同步、因此工作效果不是很好。

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

    我希望这两个信号彼此同步、不会有时间滞后。

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

    您好 Damien、

    为了澄清我的意思、您绝不会声明 EPWM1是 EPWM7的同步源。 如果您以0相移运行您在 EPWM7上编写的 EPWM_SET_PHASE ()函数、它只会设置 EPWM7的 SyncOut 信号。 同样、如果您有机会、请浏览 CCS 的调试功能、并使用"Expressions"窗口查看相关寄存器-它作为调试的第一步非常有用、可以查看未设置的内容!

    此致、

    Jason Osborn

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

    好的, 即使相移为零,我也必须使用此函数?

    ePWM_setSyncInPulseSource (base、ePWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);

    不幸的是、我今晚无法运行我的代码、因为我不在工作。

    如果我错了,请告诉我:在我的情况下,我必须通过 ePWM_enableSyncOutPulseSource (base,ePWM_SYNC_OUT_PULSE_ON_CNTR_ZERO)在 ePWM1上设置 Sync Out 信号,然后通过 ePWM_setSyncInPulseSource (base,ePWM_SYNC_SYNC_RPM1_SYSRC_PULSE)在 EPWM7上设置 Sync In 源代码?

    此致、

    Damien

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

    Damien、

    从理论上讲、不可以、如果这些信号在初始化后从未改变、但我这样做是为了安全。 回顾 EPWM7还必须设置 PHSEN 位、您的总结看起来准确无误。

    如果您继续遇到问题、我首先要确保您的'ePWM_TBPRD'值正确地是您分配给 EPWM7周期的值的两倍。 接下来、我将确保您的 CMPx 值和 AQ 设置已正确配置、从而为您提供所需的行为。 如果您在所有这些之后仍有问题、请提供信号波形和相关寄存器的内容。

    此致、

    Jason Osborn