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.

CCS/TMS320F28379D: Problem with interleaving phases

Part Number: TMS320F28379D

Tool/software: Code Composer Studio

Hello

I am having kind of a weird problem. I set up 3 ePWMs (1,2 and 3) and I want to control their duty cycle and their phase shift.
The duty cycle works perfectly and also the phase shift works up to some level but something weird happens when I increase the phase shift of the third channel above a number of 2300 (e.g. 2400 or something in that range, not exactly 2300). The signal in this case just dissapears ( I assume it becomes zero or so but nothing comes out of the PWM)

I would have the three signals to be 120° phase shifted. So for a TBPRD of 2000 in up-down mode, this becomes a phase shift of 2000*2*(1/3) and 2000*2*(2/3) but this does not work.
Below you can find my code, which is adapted from the epwm_updown_aq_cpu01 example, provided by TI.

Does anyone had a similar problem or any advice that you could give me?

Kind regards

//###########################################################################
// $TI Release: F2837xD Support Library v200 $
// $Release Date: Tue Jun 21 13:00:02 CDT 2016 $
// $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################

//
// Included Files
//
#include "F28x_Project.h"

//
// Defines
//
#define EPWM1_TIMER_TBPRD  2000  // Period register

#define EPWM2_TIMER_TBPRD  2000  // Period register

#define EPWM3_TIMER_TBPRD  2000  // Period register

//
// Globals
//
typedef struct
{
    volatile struct EPWM_REGS *EPwmRegHandle;
    Uint16 EPwm_CMPA_Direction;
    Uint16 EPwm_CMPB_Direction;
    Uint16 EPwmTimerIntCount;
    Uint16 EPwmMaxCMPA;
    Uint16 EPwmMinCMPA;
    Uint16 EPwmMaxCMPB;
    Uint16 EPwmMinCMPB;
}EPWM_INFO;

EPWM_INFO epwm1_info; //Wat is dit juist voor iets????
EPWM_INFO epwm2_info;
EPWM_INFO epwm3_info;

double DELTA_1A = 10;
double DELTA_2A = 10;
double DELTA_3A = 10;
int SET_EPWM1_CMPA = 100;
int SET_EPWM2_CMPA = 100;
int SET_EPWM3_CMPA = 100;

int PHASE_1A = 0; //(int)(2000*0);
int PHASE_2A = 0; //667;  //(int)(2000*(1/3));
int PHASE_3A = 0; //1334; //(int)(2000*(2/3));


//
// Function Prototypes
//
void InitEPwm1Example(void);
void InitEPwm2Example(void);
void InitEPwm3Example(void);

//
// Main
//
void main(void)
{

    InitSysCtrl();
    InitGpio();

    PHASE_1A = 0; //(int)(2000*0);
    PHASE_2A = 667;//0; //x7D0; //(int)(2000*2/3);
    PHASE_3A = 3000; //xBB8;//3000;//(int)(2000*2*2/3);

    InitEPwm1Gpio();
    InitEPwm2Gpio();
    InitEPwm3Gpio();

    DINT;

    InitPieCtrl(); // De PIE -> alles wat met interrupts te maken heeft, moet in het begin gewoon geinitialiseerd worden

    IER = 0x0000; // Interrupt Enable Register
    IFR = 0x0000; //Interrupt Flag Register

    InitPieVectTable();

    EALLOW; // This is needed to write to EALLOW protected registers

    EDIS;   // This is needed to disable write to EALLOW protected registers

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    InitEPwm1Example();
    InitEPwm2Example();
    InitEPwm3Example();

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

    while(1)                            // endless loop - wait for an interrupt
    {
        SET_EPWM1_CMPA = (int)(((100-DELTA_1A)/100)*EPWM1_TIMER_TBPRD-1);
        SET_EPWM2_CMPA = (int)(((100-DELTA_2A)/100)*EPWM2_TIMER_TBPRD-1);
        SET_EPWM3_CMPA = (int)(((100-DELTA_3A)/100)*EPWM3_TIMER_TBPRD-1);

        EPwm1Regs.CMPA.bit.CMPA = SET_EPWM1_CMPA; // Set compare A value -OK
        EPwm2Regs.CMPA.bit.CMPA = SET_EPWM2_CMPA; // Set compare A value -OK
        EPwm3Regs.CMPA.bit.CMPA = SET_EPWM3_CMPA; // Set compare A value -OK

        asm(" NOP");

    }
}
//
// InitEPwm1Example - Initialize EPWM1 configuration
//
void InitEPwm1Example()
{
    //
    // Setup TBCLK
    //
    EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period 801 TBCLKs - OK, exacte waarde nadien aanpassen
    EPwm1Regs.TBPHS.bit.TBPHS = PHASE_1A;        // Phase is 0 -OK
    EPwm1Regs.TBCTR = 0x0000;                  // Clear counter -OK, gewoon op nul zetten

    //
    // Set Compare values
    //
    EPwm1Regs.CMPA.bit.CMPA = SET_EPWM1_CMPA;    // Set compare A value -OK
    //EPwm1Regs.CMPB.bit.CMPB = EPWM1_MAX_CMPB;    // Set Compare B value -OK

    //
    // Setup counter mode
    //
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down - why isn't this equak to 01???
    EPwm1Regs.TBCTL.bit.PHSEN = 0;//TB_DISABLE;        // Disable phase loading -OK
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT -OK
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; //-OK
    EPwm1Regs.TBCTL.bit.SYNCOSEL = 0x01; //-OK


    //
    // Setup shadowing - Niet nodig voor ons
    //
    //    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    //    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    //    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
    //    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //
    // Set actions
    //
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM1A on event A, up
                                                  // count
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;          // Clear PWM1A on event A,
                                                  // down count

    EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;            // Set PWM1B on event B, up
                                                  // count
    EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;          // Clear PWM1B on event B,
                                                  // down count

    //
    // Interrupt where we will change the Compare Values - momenteel niet nodig
    //
    //EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
    //EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
    //EPwm1Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event

    //

}

//
// InitEPwm2Example - Initialize EPWM2 configuration
//
void InitEPwm2Example()
{
    //
    // Setup TBCLK
    //
    EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD;         // Set timer period 801 TBCLKs
    EPwm2Regs.TBPHS.bit.TBPHS = PHASE_2A; //0x0000;          // Phase is 0
    EPwm2Regs.TBCTR = 0x0000;                    // Clear counter

    //
    // Set Compare values
    //
    EPwm2Regs.CMPA.bit.CMPA = SET_EPWM2_CMPA;    // Set compare A value
    //EPwm2Regs.CMPB.bit.CMPB = EPWM2_MIN_CMPB;    // Set Compare B value

    //
    // Setup counter mode
    //
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
    EPwm2Regs.TBCTL.bit.PHSEN = 1;//TB_DISABLE;        // Disable phase loading
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = 0x01; //-OK

    //
    // Setup shadowing
    //
    //EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    //EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    //EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
    //EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //
    // Set actions
    //
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;         // Set PWM2A on event A, up
                                               // count
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;       // Clear PWM2A on event B, down
                                               // count

    EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;       // Clear PWM2B on zero
    EPwm2Regs.AQCTLB.bit.PRD = AQ_SET;         // Set PWM2B on period

    //
    // Interrupt where we will change the Compare Values
    //
    //EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;    // Select INT on Zero event
    //EPwm2Regs.ETSEL.bit.INTEN = 1;               // Enable INT
    //EPwm2Regs.ETPS.bit.INTPRD = ET_3RD;          // Generate INT on 3rd event
}

//
// InitEPwm3Example - Initialize EPWM3 configuration
//
void InitEPwm3Example(void)
{

    EPwm3Regs.TBPRD = EPWM3_TIMER_TBPRD;           // Set timer period

    //
    // Setup TBCLK
    //
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down and down
    EPwm3Regs.TBCTL.bit.PHSEN = 1;//TB_DISABLE;        // Disable phase loading
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm3Regs.TBCTL.bit.SYNCOSEL = 0x01; //-OK

    EPwm3Regs.TBPHS.bit.TBPHS = PHASE_3A; //0x0000;            // Phase is 0
    EPwm3Regs.TBCTR = 0x0000;                      // Clear counter


    //
    // Setup shadow register load on ZERO
    //
    //EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    //EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    //EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    //EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //
    // Set Compare values
    //
    EPwm3Regs.CMPA.bit.CMPA = SET_EPWM1_CMPA;   // Set compare A value
    //EPwm3Regs.CMPB.bit.CMPB = EPWM3_MAX_CMPB;   // Set Compare B value

    //
    // Set Actions
    //
    EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;         // Set PWM3A on period
    EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;       // Clear PWM3A on event B, down
                                               // count

    EPwm3Regs.AQCTLB.bit.PRD = AQ_CLEAR;       // Clear PWM3A on period
    EPwm3Regs.AQCTLB.bit.CAU = AQ_SET;         // Set PWM3A on event A, up
                                               // count
}

//
// End of file
//