TI中文支持网
TI专业的中文技术问题咨询交流网站

F280049 EPWM:PWM变频率后第一个PWM周期输出不准确

你好,
调试中遇到一个PWM的问题,PWM变频后(同时也更新了comp值)第一个PMW周期的输出不准确,配置代码如下,ctr=0时从shadow中load period和compare值。帮忙看一下是哪里的问题,谢谢。
    // =============================================== //
    // === Configure Time Base Submodule Registers === //
    // =============================================== //
    //
    // Enable TBPRD shadow load (Default is load on CTR=0)
    // PWM frequency = 1 / period
    // No phase shift
    // Initialize counter to 0
    // Counter continues to increment during emulation stop
    // Configure counter for up-down count mode
    // Set prescalers: clock divider = 1, HS clock divider = 1
    //
    EPWM_setPeriodLoadMode(base, EPWM_PERIOD_SHADOW_LOAD);
    EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);
    EPWM_setTimeBasePeriod(base, LLC_PERIOD_INIT_TICKS);
    EPWM_setTimeBaseCounter(base, 0);
    EPWM_setEmulationMode(base, EPWM_EMULATION_STOP_AFTER_NEXT_TB);
    EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_DOWN);
    EPWM_setClockPrescaler(base, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);

    //
    // === Action Qualifier SubModule for LLC – PH1/2/3, PRI === //
    //
    EPWM_setActionQualifierShadowLoadMode(base, EPWM_ACTION_QUALIFIER_A, EPWM_AQ_LOAD_ON_CNTR_ZERO);
    EPWM_setActionQualifierShadowLoadMode(base, EPWM_ACTION_QUALIFIER_B, EPWM_AQ_LOAD_ON_CNTR_ZERO);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW,  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW,  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);

    //
    // ===================================================== //
    // === Configure Counter Compare Submodule Registers === //
    // ===================================================== //
    //
    // Set initial CMPA value
    // Set initial CMPB value
    // Enable CMPA shadow load on CTR = 0
    // Enable CMPB shadow load on CTR = 0
    //
    EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, LLC_PERIOD_INIT_TICKS >> 1);
    EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, LLC_PERIOD_INIT_TICKS >> 1);

    //
    // =============================================== //
    // === Configure Dead-Band Submodule Registers === //
    // =============================================== //
    //
    // Active high complementary PWMs – Set up the deadband
    // Enable rising edge delay
    // Enable falling edge delay
    // RED polarity is active high
    // FED polarity is active low (inverted)
    // Enable shadow load on CTR = 0 for RED count
    // Enable shadow load on CTR = 0 for FED count
    //
    EPWM_setDeadBandControlShadowLoadMode(base, EPWM_DB_LOAD_ON_CNTR_ZERO);
    EPWM_setRisingEdgeDeadBandDelayInput(base,  EPWM_DB_INPUT_EPWMA);
    EPWM_setFallingEdgeDeadBandDelayInput(base, EPWM_DB_INPUT_EPWMB);
    EPWM_setDeadBandDelayMode(base, EPWM_DB_RED, true);
    EPWM_setDeadBandDelayMode(base, EPWM_DB_FED, true);
    EPWM_setDeadBandDelayPolarity(base, EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH);
    EPWM_setDeadBandDelayPolarity(base, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
    EPWM_setRisingEdgeDelayCountShadowLoadMode(base, EPWM_RED_LOAD_ON_CNTR_ZERO);
    EPWM_setFallingEdgeDelayCountShadowLoadMode(base, EPWM_FED_LOAD_ON_CNTR_ZERO);
    EPWM_setRisingEdgeDelayCount(base,  red);
    EPWM_setFallingEdgeDelayCount(base, fed);
下图是PWM的实际输出,红框内的周期不是所设置的变频周期,比期望的周期时间长:
Green Deng:

一般来说,出现这个问题考虑:
1、PWM的TBCTL的PRDLD寄存器,看是否是Shadow模式
2、比较器模块的动作时间。比如PWM模块的计数器从0开始计时,然后到了上升阶段的CMPA开始动作置1,到了下降阶段的0置零,这样的话,会有小于半个周期的延迟。

Yankai Ma:

回复 Green Deng:

Hi,

用仿真器读取寄存器的值,可以确定PWM的TBCTL寄存器中的PRDLD是Shadow模式。

关于比较器模块动作时间的问题,哪个文档中有介绍半个周期的延迟吗,这是所说的半个周期是值PRD/2吗?有没有规避延迟的方法?

Green Deng:

回复 Yankai Ma:

似乎没有这样的文档,这个是根据PWM计数器的计数原理推测出来的。
我再咨询一下其他同事这个问题,确认一下问题所在并尽量给出解释和解决方案。

Green Deng:

回复 Yankai Ma:

我查看了上面的EPWM配置和输出波形,基于AQ配置,我怀疑当从影子寄存器加载TBPRD时恰好错过了CTR = TBRPD事件,因为此处使用的计数器模式为DOWN模式。 因此,输出不会在整个周期内都保持为低电平,并导致导通时间延长(也就是之前说的会有小于半个周期的延迟)。 是否尝试过使用UP模式?

如果应用程序特别需要DOWN计数模式,那么这里提供的一项建议是如下修改动作限定符配置:

EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW,EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW,EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);

即使TBPRD动态变化,这样设置也应该将输出置为低电平。

Yankai Ma:

回复 Green Deng:

这样修改之后,问题看起来还是存在如下图,图中那个glitch是死区导致的,关掉死区后则会得到和主题帖相同的输出波形。

Green Deng:

回复 Yankai Ma:

你好,有没有尝试up模式?

Yankai Ma:

回复 Green Deng:

早的时候试过UP模式,UP模式下没有DOWN模式的问题,但是UP模式在Phase Shift是能后存在另外一个问题,所以后来改成了DOWN模式,但改为DOWN模式后就遇到了主题帖中的问题。

UP模式下,EPWM1配置为在过零出SYNC输出,EPWM2使能Phase Shift功能,跟随EPWM1并且相位滞后120度,具体问题为,EPWM2的TBCTR的计数值超过TBPRD的值,EPWM2的输出变为恒定电平。具体寄存器截图及输出波形如下(EPWM1A为黄色,EPWM2A为绿色):

Green Deng:

回复 Yankai Ma:

看一下下面几个问题:
1、这里你有使用高分辨率的死区/周期吗?
2、您在上下计数器模式下是否也观察到相同的情况?

赞(0)
未经允许不得转载:TI中文支持网 » F280049 EPWM:PWM变频率后第一个PWM周期输出不准确
分享到: 更多 (0)