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.

TMS320F2800157: Application issues of chips

Part Number: TMS320F2800157
Other Parts Discussed in Thread: C2000WARE

When I use TIME0 interrupt and PWM interrupt according to the routine, there is a sudden change in PWM interrupt cycle, from 100us to 86us, resulting in a 10KHz PWM interrupt before a 20KHz time0 interrupt. The waveform is as follows. Can you help me see what the situation is and what good suggestions are there?

  • Hi Tony,

    When are your interrupts being generating, is your ePWM interrupt being generated every PRD or ZRO using the event trigger submodule?

    Are you changing your PWM period at all during run time?

    How are you scoping out these interrupts? Can you share a snippet of the code that generates this issue?

    Best,

    Ryan Ma

  • The EPWM interrupt is generated by the event triggered submodule in ZREO, and the PWM cycle is not changed during operation.

    Allow Time0 interrupt interrupt during PWM interrupt execution

    20K interrupt and 10K interrupt, 10K allows 20K interrupt interrupt;

    When both interrupts are triggered using PWM, such as using PWM1 to trigger a 20K interrupt and PWM2 to trigger a 10K interrupt, there will be no sudden change in the 10K interrupt cycle;

    When using TIME0 to trigger a 20K interrupt and PWM2 to trigger a 10K interrupt, there will be a sudden change in the 10k interrupt cycle

    In both cases, only the triggering source of the 20K interrupt is different, and the other conditions are the same

    In addition, the TIME0 start counting function and enabling PWM peripheral clock function are performed simultaneously

  • Supplement the relevant code section

  • Hi Tony,

    I have performed a test case in which using ePWM1 at 10kHz, and ePWM2 at 20kHz. I also have configured Timer0 to generate ISR every 20kHz.

    The reason behind this is the priority scheme of the PIE where TIMER0 is in group1 and will always have priority over the ePWM ISRs thus the TIMER ISR should be serviced first before any ePWM ISR's.

    If you're planning to use two ISR's, I believe using two PWM's with same PWM frequency will allow you to generate what you're looking for instead of using the TIMER0 ISR.

    //
    // Globals
    //
    uint16_t cpuTimer0IntCount;
    uint16_t cpuTimer1IntCount;
    uint16_t cpuTimer2IntCount;
    bool PWM_ONLY_ISR = true;
    
    void INT_myEPWM0_ISR(void){
        // Channel 1 on scope
        GPIO_writePin(myGPIO1, 1);
        EPWM_clearEventTriggerInterruptFlag(myEPWM0_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
        GPIO_writePin(myGPIO1, 0);
    }
    
    
    void INT_myEPWM1_ISR(void){
        // Channel 2 on scope
        GPIO_writePin(myGPIO0, 1);
        EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
        GPIO_writePin(myGPIO0, 0);
    }
    __interrupt void cpuTimer0ISR(void)
    {
        // Channel 3 on scope
        GPIO_writePin(myGPIO2, 1);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
        GPIO_writePin(myGPIO2, 0);
    }
    
    void main(void)
    {
        //
        // Initializes device clock and peripherals
        //
        Device_init();
    
        //
        // Initializes PIE and clears PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initializes the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // PinMux and Peripheral Initialization
        //
        Board_init();
        EPWM_setTimeBaseCounter(myEPWM0_BASE, 0);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
        CPUTimer_startTimer(CPUTIMER0_BASE);
        //
        // C2000Ware Library initialization
        //
        C2000Ware_libraries_init();
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Reset interrupt counter
        //
        cpuTimer0IntCount = 0;
        cpuTimer1IntCount = 0;
        cpuTimer2IntCount = 0;
    
        //
        // IDLE loop. Just sit and loop forever (optional)
        //
        while (1)
        {
        }
    }
    void Board_init()
    {
        EALLOW;
    
        PinMux_init();
        SYSCTL_init();
        SYNC_init();
        CPUTIMER_init();
        EPWM_init();
        GPIO_init();
        INTERRUPT_init();
    
        EDIS;
    }
    
    //*****************************************************************************
    //
    // PINMUX Configurations
    //
    //*****************************************************************************
    void PinMux_init()
    {
        //
        // PinMux for modules assigned to CPU1
        //
    
        //
        // EPWM1 -> myEPWM0 Pinmux
        //
        //
        // EPWM2 -> myEPWM1 Pinmux
        //
        // GPIO5 -> myGPIO0 Pinmux
        GPIO_setPinConfig(GPIO_5_GPIO5);
        // GPIO1 -> myGPIO1 Pinmux
        GPIO_setPinConfig(GPIO_1_GPIO1);
        // GPIO6 -> myGPIO2 Pinmux
        GPIO_setPinConfig(GPIO_6_GPIO6);
    
    }
    
    //*****************************************************************************
    //
    // CPUTIMER Configurations
    //
    //*****************************************************************************
    void CPUTIMER_init(){
        CPUTIMER0_BASE_init();
    }
    
    void CPUTIMER0_BASE_init(){
        CPUTimer_setEmulationMode(CPUTIMER0_BASE_BASE, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
        CPUTimer_setPreScaler(CPUTIMER0_BASE_BASE, 0U);
        CPUTimer_setPeriod(CPUTIMER0_BASE_BASE, 6000U);
        CPUTimer_enableInterrupt(CPUTIMER0_BASE_BASE);
        CPUTimer_stopTimer(CPUTIMER0_BASE_BASE);
    
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE_BASE);
    }
    
    //*****************************************************************************
    //
    // EPWM Configurations
    //
    //*****************************************************************************
    void EPWM_init(){
        EPWM_setClockPrescaler(myEPWM0_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
        EPWM_setTimeBasePeriod(myEPWM0_BASE, 6000);
        EPWM_setTimeBaseCounter(myEPWM0_BASE, 0);
        EPWM_setTimeBaseCounterMode(myEPWM0_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(myEPWM0_BASE);
        EPWM_setPhaseShift(myEPWM0_BASE, 0);
        EPWM_setCounterCompareValue(myEPWM0_BASE, EPWM_COUNTER_COMPARE_A, 0);
        EPWM_setCounterCompareShadowLoadMode(myEPWM0_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareValue(myEPWM0_BASE, EPWM_COUNTER_COMPARE_B, 0);
        EPWM_setCounterCompareShadowLoadMode(myEPWM0_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(myEPWM0_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM0_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);
        EPWM_setFallingEdgeDelayCountShadowLoadMode(myEPWM0_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);
        EPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM0_BASE);
        EPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM0_BASE);
        EPWM_enableInterrupt(myEPWM0_BASE);
        EPWM_setInterruptSource(myEPWM0_BASE, EPWM_INT_TBCTR_PERIOD);
        EPWM_setInterruptEventCount(myEPWM0_BASE, 1);
        EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
        EPWM_setTimeBasePeriod(myEPWM1_BASE, 3000);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0);
        EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
        EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
        EPWM_setPhaseShift(myEPWM1_BASE, 0);
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 0);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, 0);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
        EPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);
        EPWM_setFallingEdgeDelayCountShadowLoadMode(myEPWM1_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);
        EPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);
        EPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);
        EPWM_enableInterrupt(myEPWM1_BASE);
        EPWM_setInterruptSource(myEPWM1_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_setInterruptEventCount(myEPWM1_BASE, 1);
    }
    
    //*****************************************************************************
    //
    // GPIO Configurations
    //
    //*****************************************************************************
    void GPIO_init(){
        myGPIO0_init();
        myGPIO1_init();
        myGPIO2_init();
    }
    
    void myGPIO0_init(){
        GPIO_writePin(myGPIO0, 0);
        GPIO_setPadConfig(myGPIO0, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(myGPIO0, GPIO_QUAL_SYNC);
        GPIO_setDirectionMode(myGPIO0, GPIO_DIR_MODE_OUT);
    }
    void myGPIO1_init(){
        GPIO_writePin(myGPIO1, 0);
        GPIO_setPadConfig(myGPIO1, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(myGPIO1, GPIO_QUAL_SYNC);
        GPIO_setDirectionMode(myGPIO1, GPIO_DIR_MODE_OUT);
    }
    void myGPIO2_init(){
        GPIO_writePin(myGPIO2, 0);
        GPIO_setPadConfig(myGPIO2, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(myGPIO2, GPIO_QUAL_SYNC);
        GPIO_setDirectionMode(myGPIO2, GPIO_DIR_MODE_OUT);
    }
    
    //*****************************************************************************
    //
    // INTERRUPT Configurations
    //
    //*****************************************************************************
    void INTERRUPT_init(){
    
        // Interrupt Setings for INT_CPUTIMER0_BASE
        Interrupt_register(INT_CPUTIMER0_BASE, &cpuTimer0ISR);
        Interrupt_enable(INT_CPUTIMER0_BASE);
    
        // Interrupt Setings for INT_myEPWM0
        Interrupt_register(INT_myEPWM0, &INT_myEPWM0_ISR);
        Interrupt_enable(INT_myEPWM0);
    
        // Interrupt Setings for INT_myEPWM1
        Interrupt_register(INT_myEPWM1, &INT_myEPWM1_ISR);
        Interrupt_enable(INT_myEPWM1);
    }
    //*****************************************************************************
    //
    // SYNC Scheme Configurations
    //
    //*****************************************************************************
    void SYNC_init(){
        SysCtl_setSyncOutputConfig(SYSCTL_SYNC_OUT_SRC_EPWM1SYNCOUT);
        //
        // SOCA
        //
        SysCtl_enableExtADCSOCSource(0);
        //
        // SOCB
        //
        SysCtl_enableExtADCSOCSource(0);
    }
    //*****************************************************************************
    //
    // SYSCTL Configurations
    //
    //*****************************************************************************
    void SYSCTL_init(){
        //
        // sysctl initialization
        //
        SysCtl_setStandbyQualificationPeriod(2);
        SysCtl_configureType(SYSCTL_ECAPTYPE, 0, 0);
        SysCtl_selectErrPinPolarity(0);
    
        SysCtl_disableMCD();
    
    
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRCAL);
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM4);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM5);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM6);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM7);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP3);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CB);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCANA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCC);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS1);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS2);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS3);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS4);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_LINA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_PMBUSA);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DCC0);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPG1);
    
    
    
    }
    

    Here is the scope shots:

    Best,

    Ryan Ma

  • Hi Tony,

    Were you able to run the following test case? Does this test case reflect what you are trying to achieve?

    I am unable to reproduce the issue you are seeing. Could you provide some stripped down code related to the issue?

    Best,

    Ryan Ma

  • Hi Tony,

    To add to Ryan's points: there's a couple additional ways to get this to work as you're expecting.

    1. You can allow the Timer0 interrupt to have other interrupts "nest" within it. See guide here: https://software-dl.ti.com/C2000/docs/c28x_interrupt_nesting/html/index.html This basically allows you to stop the Timer interrupt while it's running, enable other interrupts to run inside it, and then come back to finish the Timer interrupt. This is typically what people do when there's a really critical interrupt like EPWM. Update every other ISR to allow EPWM interrupts to happen inside of them and then set EINT. Follow the instructions carefully in that guide because there's some warnings in there that are important.

    2. You can re-order the priority of the interrupts in software, using the example "interrupt_ex3_sw_prioritization.c" from C2000Ware as a guide. This is also a really good option.

    3. You can make the Timer interrupt a lot faster so it doesn't block the EPWM interrupt. This one is less likely to be okay because it means you need to push processing in the Timer interrupt to a lower priority task, and that might not be acceptable for your application.

    Regards,

    Vince

  • Hi Tony,

    Taken from the other thread:

    Explanation 1: During the timer interrupt, an update or reload of the PWM module may have been triggered, resulting in a change in the status of the PWM timer. This will cause the PWM cycle to shorten or generate additional pulses

    The ePWM will not reload a new setting once it has been initialized. If you are updating the ePWM configurations during the timer interrupt then that would explain this short PWM cycle.

    Explanation 2: During the timer interrupt process, delays may occur in order to perform the operations required by the PWM module. This causes the trigger time of the PWM interrupt to be earlier than the timer interrupt, thereby shortening the cycle of the PWM interrupt.

    During your timer interrupt are you doing anything to change the ePWM registers? The pulse width of the PWM seem to change and the period. Are you writing to the TBPRD or CMPA / CMPB registers? Is the light blue waveform the PWM output?

    Because ePWM is lower priority than the timer ISR, the ePWM ISR has to wait for the timer ISR to finish in order to clear the event trigger interrupt status flag. 

    Could you give some more details on how you're generating your ePWM ISR? I believe the shortening of the PWM period, if you're outputting the PWM pulse, would be because the ePWM ISR is dependent on the timer ISR in some manner and causing some ePWM configuration changes.

    Best,

    Ryan Ma

  • During program operation, no changes were made to the registers of EPWM,

    The PWM interrupt function is generated by the event triggered submodule, when CTR=0

    Under the same conditions, there is no problem of cycle reduction when PWM1 and PWM2 are used together; The problem of PWM interruption cycle reduction only occurs when the timer and PWM are combined. In these two working conditions, only the interruption trigger source is different, and the rest are the same

    The key is whether there are any avoidance methods for this situation, and whether the F280039 chip has the same problem. Thank you!

  • Hi Tony,

    Could you please provide the code that generates this issue? I have been unsuccessful in replicating the issue. 

    The PWM interrupt on CTR == ZRO will be delayed if the TIMER0 interrupt overlaps with the PWM interrupt. However the period of the ePWM should not change. You should be able to verify this with outputting the ePWM signals and measuring the frequency. If the PWM output frequency stays the same, and only the interrupt frequency changes, then it is an interrupt priority issue. Please refer to Vince's suggestions on how to avoid this.

    Best,

    Ryan Ma