Other Parts Discussed in Thread: C2000WARE
Greetings,
I am having an issue with my EPWM peripheral at high duty cycles (>0.92). The way I have the peripheral configured works well until I approach duty cycles > 0.92. At this point, occasionally a pulse that should be generated is missed. You can see this in the images below. Yellow is the PWM waveform and blue is a timing signal for the ISR, where the CMPA value is updated in the ISR. The blue waveform is set high at the start of the ISR (PWM counter = period, up down count mode), and is set low at the end of the ISR (The ISR takes just under 3 us).
1. Any ideas as to why there are occasional misses?
Here is how I have my peripheral configured: 60 kHz switching frequency, shadow load mode, up down count mode, shadow to active load on counter zero, action qualifier sets pin low during compare match during up count, action qualifier sets pin high during compare match during down count, 200 ns deadband. The ISR occurs at period match.
Here is the configuration code:
EPWM_setPeriodLoadMode(pwmHandle[base], EPWM_PERIOD_SHADOW_LOAD); EPWM_setTimeBasePeriod(pwmHandle[base], INV_PWM_TICKS / 2); EPWM_setPhaseShift(pwmHandle[base], 0); EPWM_setTimeBaseCounter(pwmHandle[base], 0); EPWM_setTimeBaseCounterMode(pwmHandle[base], EPWM_COUNTER_MODE_UP_DOWN); EPWM_setClockPrescaler(pwmHandle[base], EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); EPWM_disablePhaseShiftLoad(pwmHandle[base]); // sync "down-stream" EPWM_setSyncOutPulseMode(pwmHandle[base], EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // Counter Compare Submodule Registers // set duty 0% initially EPWM_setCounterCompareValue(pwmHandle[base], EPWM_COUNTER_COMPARE_A, 0); EPWM_setCounterCompareShadowLoadMode(pwmHandle[base], EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); // Action Qualifier SubModule Registers // Time base counter up equals COMPA and set output pins to low // Time base counter down equals COMPA and set output pins to high EPWM_setActionQualifierActionComplete(pwmHandle[base], EPWM_AQ_OUTPUT_A, (EPWM_ActionQualifierEventAction)(EPWM_AQ_OUTPUT_LOW_UP_CMPA | EPWM_AQ_OUTPUT_HIGH_DOWN_CMPA)); // Active high complementary PWMs - Set up the deadband EPWM_setRisingEdgeDeadBandDelayInput(pwmHandle[base], EPWM_DB_INPUT_EPWMA); EPWM_setFallingEdgeDeadBandDelayInput(pwmHandle[base], EPWM_DB_INPUT_EPWMA); EPWM_setDeadBandDelayMode(pwmHandle[base], EPWM_DB_RED, true); EPWM_setDeadBandDelayMode(pwmHandle[base], EPWM_DB_FED, true); EPWM_setDeadBandDelayPolarity(pwmHandle[base], EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH); EPWM_setDeadBandDelayPolarity(pwmHandle[base], EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); // for redcount, fedcount = 200, dead time = 2us -> 10 ns/count EPWM_setRisingEdgeDelayCount(pwmHandle[base], DT_DELAY_COUNT); EPWM_setFallingEdgeDelayCount(pwmHandle[base], DT_DELAY_COUNT);
EPWM_setInterruptSource(EPWM1_BASE, EPWM_INT_TBCTR_PERIOD);
This is for a three phase motor control application. So the ISR performs the field oriented control calculations, and then updates the shadow register with the next duty cycle value.
2. Shouldn't the shadow register retain it's value and load to the active register each time the PWM counter hits zero? If I perform my ISR at period count, for a 60 kHz PWM (16.67 us period) that means I have 8 us to perform the calcuations and update the shadow register before the counter reaches the zero count, at which point the shadow register value is loaded to the active register.
The result is a large amount of current distortion at high duty cycles when operating the motor. I'm trying to get the motor to operate in overmodulation, but with this bug there is to much current distortion which leads to instability and a loss of control.
Thanks.