你好,
调试中遇到一个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:
Hi,
用仿真器读取寄存器的值,可以确定PWM的TBCTL寄存器中的PRDLD是Shadow模式。
关于比较器模块动作时间的问题,哪个文档中有介绍半个周期的延迟吗,这是所说的半个周期是值PRD/2吗?有没有规避延迟的方法?
,
Green Deng:
似乎没有这样的文档,这个是根据PWM计数器的计数原理推测出来的。
我再咨询一下其他同事这个问题,确认一下问题所在并尽量给出解释和解决方案。
,
Green Deng:
我查看了上面的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:
这样修改之后,问题看起来还是存在如下图,图中那个glitch是死区导致的,关掉死区后则会得到和主题帖相同的输出波形。
,
Green Deng:
你好,有没有尝试up模式?
,
Yankai Ma:
早的时候试过UP模式,UP模式下没有DOWN模式的问题,但是UP模式在Phase Shift是能后存在另外一个问题,所以后来改成了DOWN模式,但改为DOWN模式后就遇到了主题帖中的问题。
UP模式下,EPWM1配置为在过零出SYNC输出,EPWM2使能Phase Shift功能,跟随EPWM1并且相位滞后120度,具体问题为,EPWM2的TBCTR的计数值超过TBPRD的值,EPWM2的输出变为恒定电平。具体寄存器截图及输出波形如下(EPWM1A为黄色,EPWM2A为绿色):
,
Green Deng:
看一下下面几个问题:
1、这里你有使用高分辨率的死区/周期吗?
2、您在上下计数器模式下是否也观察到相同的情况?