Other Parts Discussed in Thread: SYSCONFIG
Tool/software:
I’m using EPWM1 and EPWM2 to control a full-bridge circuit, performing only phase shifting without frequency variation. Let’s focus on EPWM1, which controls two complementary switches of one leg. To achieve wide-range phase shifting without pulse loss, I leveraged a new feature of the 28P65 MCU, using CMPC to trigger a global load.
I’m using up-counting mode: the signal goes high at CMPA and low at CMPB, with a 50% duty cycle. CMPC is always set to CMPB + 2, meaning that even if the next control cycle has changed values, the new compare values won’t be loaded until after CMPB executes, specifically at CMPC. CMPA, CMPB, and CMPC all use shadow registers. I am not using the TBPHS register.
Most of the time, this works correctly. However, here’s the abnormal situation:
TBPRD = 6666, CMPA = 4500, CMPB = 2166, CMPC = 2168.
Since my interrupt service routine takes about 10 µs, when the CMPC event occurs very close to the ISR execution time, pulse loss sometimes happens. I suspect this might be because at the CMPC moment, all shadow registers are loaded into the active registers—but simultaneously, the ISR may be writing new values into the shadow registers. Could this cause a conflict? Another possibility is this: if the new CMPC value is slightly greater than the old CMPC value, does that mean a global load could be triggered twice within a single switching cycle? Would that be dangerous?
Here’s my solution: when I detect that CMPB is near 2100, I set CMPC to a fixed value of 3333. After doing this, the pulse loss no longer occurs.
Below is the EPWM1 initialization code generated by SysConfig:
EPWM_enableGlobalLoad(epwm1_Q1Q2_BASE); EPWM_setGlobalLoadTrigger(epwm1_Q1Q2_BASE, EPWM_GL_LOAD_PULSE_CNTR_U_CMPC); EPWM_setGlobalLoadEventPrescale(epwm1_Q1Q2_BASE, 1); EPWM_setClockPrescaler(epwm1_Q1Q2_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); EPWM_setTimeBasePeriod(epwm1_Q1Q2_BASE, 6666); EPWM_setTimeBaseCounter(epwm1_Q1Q2_BASE, 0); EPWM_setTimeBaseCounterMode(epwm1_Q1Q2_BASE, EPWM_COUNTER_MODE_UP); EPWM_enablePhaseShiftLoad(epwm1_Q1Q2_BASE); EPWM_setPhaseShift(epwm1_Q1Q2_BASE, 0); EPWM_setSyncInPulseSource(epwm1_Q1Q2_BASE, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM7); EPWM_setSyncPulseSource(epwm1_Q1Q2_BASE, HRPWM_PWMSYNC_SOURCE_ZERO); EPWM_setCounterCompareValue(epwm1_Q1Q2_BASE, EPWM_COUNTER_COMPARE_A, 1); EPWM_enableGlobalLoadRegisters(epwm1_Q1Q2_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR); EPWM_setCounterCompareShadowLoadMode(epwm1_Q1Q2_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(epwm1_Q1Q2_BASE, EPWM_COUNTER_COMPARE_B, 1); EPWM_enableGlobalLoadRegisters(epwm1_Q1Q2_BASE, EPWM_GL_REGISTER_CMPB_CMPBHR); EPWM_setCounterCompareShadowLoadMode(epwm1_Q1Q2_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(epwm1_Q1Q2_BASE, EPWM_COUNTER_COMPARE_C, 1); EPWM_enableGlobalLoadRegisters(epwm1_Q1Q2_BASE, EPWM_GL_REGISTER_CMPC); EPWM_disableCounterCompareShadowLoadMode(epwm1_Q1Q2_BASE, EPWM_COUNTER_COMPARE_D); EPWM_setActionQualifierContSWForceShadowMode(epwm1_Q1Q2_BASE, EPWM_AQ_SW_IMMEDIATE_LOAD); EPWM_enableGlobalLoadRegisters(epwm1_Q1Q2_BASE, EPWM_GL_REGISTER_AQCTLA_AQCTLA2); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(epwm1_Q1Q2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setDeadBandDelayPolarity(epwm1_Q1Q2_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); EPWM_setDeadBandDelayMode(epwm1_Q1Q2_BASE, EPWM_DB_RED, true); EPWM_setRisingEdgeDelayCountShadowLoadMode(epwm1_Q1Q2_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO); EPWM_disableRisingEdgeDelayCountShadowLoadMode(epwm1_Q1Q2_BASE); EPWM_setRisingEdgeDelayCount(epwm1_Q1Q2_BASE, 40); EPWM_setDeadBandDelayMode(epwm1_Q1Q2_BASE, EPWM_DB_FED, true); EPWM_setFallingEdgeDelayCountShadowLoadMode(epwm1_Q1Q2_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO); EPWM_disableFallingEdgeDelayCountShadowLoadMode(epwm1_Q1Q2_BASE); EPWM_setFallingEdgeDelayCount(epwm1_Q1Q2_BASE, 40); EPWM_setTripZoneAction(epwm1_Q1Q2_BASE, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW); EPWM_setTripZoneAction(epwm1_Q1Q2_BASE, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW); EPWM_enableTripZoneSignals(epwm1_Q1Q2_BASE, EPWM_TZ_SIGNAL_OSHT1); EPWM_configureDiodeEmulationTripLowSources(epwm1_Q1Q2_BASE, EPWM_DE_TRIPL_SRC_INPUTXBAR_OUT1); EPWM_configureDiodeEmulationTripHighSources(epwm1_Q1Q2_BASE, EPWM_DE_TRIPH_SRC_INPUTXBAR_OUT1); EPWM_enableGlobalLoad(epwm2_Q3Q4_BASE); EPWM_setGlobalLoadTrigger(epwm2_Q3Q4_BASE, EPWM_GL_LOAD_PULSE_CNTR_U_CMPC); EPWM_setGlobalLoadEventPrescale(epwm2_Q3Q4_BASE, 1); EPWM_setClockPrescaler(epwm2_Q3Q4_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); EPWM_setTimeBasePeriod(epwm2_Q3Q4_BASE, 6666); EPWM_setTimeBaseCounter(epwm2_Q3Q4_BASE, 0); EPWM_setTimeBaseCounterMode(epwm2_Q3Q4_BASE, EPWM_COUNTER_MODE_UP); EPWM_enablePhaseShiftLoad(epwm2_Q3Q4_BASE); EPWM_setPhaseShift(epwm2_Q3Q4_BASE, 0); EPWM_setSyncInPulseSource(epwm2_Q3Q4_BASE, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM7); EPWM_setSyncPulseSource(epwm2_Q3Q4_BASE, HRPWM_PWMSYNC_SOURCE_ZERO); EPWM_setCounterCompareValue(epwm2_Q3Q4_BASE, EPWM_COUNTER_COMPARE_A, 1); EPWM_enableGlobalLoadRegisters(epwm2_Q3Q4_BASE, EPWM_GL_REGISTER_CMPA_CMPAHR); EPWM_setCounterCompareShadowLoadMode(epwm2_Q3Q4_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(epwm2_Q3Q4_BASE, EPWM_COUNTER_COMPARE_B, 1); EPWM_enableGlobalLoadRegisters(epwm2_Q3Q4_BASE, EPWM_GL_REGISTER_CMPB_CMPBHR); EPWM_setCounterCompareShadowLoadMode(epwm2_Q3Q4_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareValue(epwm2_Q3Q4_BASE, EPWM_COUNTER_COMPARE_C, 1); EPWM_enableGlobalLoadRegisters(epwm2_Q3Q4_BASE, EPWM_GL_REGISTER_CMPC); EPWM_disableCounterCompareShadowLoadMode(epwm2_Q3Q4_BASE, EPWM_COUNTER_COMPARE_D); EPWM_setActionQualifierContSWForceShadowMode(epwm2_Q3Q4_BASE, EPWM_AQ_SW_IMMEDIATE_LOAD); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_enableGlobalLoadRegisters(epwm2_Q3Q4_BASE, EPWM_GL_REGISTER_AQCTLB_AQCTLB2); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(epwm2_Q3Q4_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setRisingEdgeDeadBandDelayInput(epwm2_Q3Q4_BASE, EPWM_DB_INPUT_EPWMB); EPWM_setFallingEdgeDeadBandDelayInput(epwm2_Q3Q4_BASE, EPWM_DB_INPUT_EPWMB); EPWM_setDeadBandDelayPolarity(epwm2_Q3Q4_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); EPWM_setDeadBandDelayMode(epwm2_Q3Q4_BASE, EPWM_DB_RED, true); EPWM_setRisingEdgeDelayCountShadowLoadMode(epwm2_Q3Q4_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO); EPWM_disableRisingEdgeDelayCountShadowLoadMode(epwm2_Q3Q4_BASE); EPWM_setRisingEdgeDelayCount(epwm2_Q3Q4_BASE, 40); EPWM_setDeadBandDelayMode(epwm2_Q3Q4_BASE, EPWM_DB_FED, true); EPWM_setFallingEdgeDelayCountShadowLoadMode(epwm2_Q3Q4_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO); EPWM_disableFallingEdgeDelayCountShadowLoadMode(epwm2_Q3Q4_BASE); EPWM_setFallingEdgeDelayCount(epwm2_Q3Q4_BASE, 40); EPWM_setDeadBandOutputSwapMode(epwm2_Q3Q4_BASE, EPWM_DB_OUTPUT_A, true); EPWM_setDeadBandOutputSwapMode(epwm2_Q3Q4_BASE, EPWM_DB_OUTPUT_B, true); EPWM_setTripZoneAction(epwm2_Q3Q4_BASE, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW); EPWM_setTripZoneAction(epwm2_Q3Q4_BASE, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW); EPWM_enableTripZoneSignals(epwm2_Q3Q4_BASE, EPWM_TZ_SIGNAL_OSHT1); EPWM_configureDiodeEmulationTripLowSources(epwm2_Q3Q4_BASE, EPWM_DE_TRIPL_SRC_INPUTXBAR_OUT1); EPWM_configureDiodeEmulationTripHighSources(epwm2_Q3Q4_BASE, EPWM_DE_TRIPH_SRC_INPUTXBAR_OUT1);





