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.

TMS320F28335: EPWM Signals

Part Number: TMS320F28335


Dear Ti members,

I have a code that runs well and the signals are also checked on an oscilloscope which seems perfect. The code is shared below:

Original Code:

 

#include "DSP2833x_Device.h"

// external function prototypes
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void InitCpuTimers(void);
extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);


// Prototype statements for functions found within this file.
void Gpio_select(void);
void Setup_ePWM1(void);
void Setup_ePWM2(void);
void Setup_eCAP1(void);

interrupt void cpu_timer0_isr(void);
interrupt void eCAP1_isr(void);

// Global Variables
Uint32 PWM_Duty = 0;
Uint32 PWM_Period = 0;
Uint32 PWM2_Duty;
Uint32 PWM2_Period;

Uint32 NEW_Duty = 0;
Uint32 NEW_Period = 0;

double ref = 1.0f; // reference voltage for pid... 0.5orig
double A1 = 0;
double TPWM = (1875/2);//3750(40K),3333(45K),3000(50K),2727(55K),2500(60K),2307(65k),2143(70K),2000(75K),1875(80K),1765(85K)
//4285(35K),30K(5000).
double Kp = 0.1f; // Kp=0.5,2.993,1.0,0.5
double Ki = 0.001f;// Ki = 0.01,0,0.1,0.009,0.001
double Kd = 0.0f;//  Kd = 0,0.5,0.01,1.0,0.002
double le = 0.0f; // Last or previous error
double se = 0.0f; // Cummulative error
double max = 0.49f; // max output limits for pid
double min = 0.05f; // min output limits for pid
double de; // difference of error
double e; // Current error
double updated_dutycycle =0;
double pid_out = 0;
double Duty_cycle_ratio = 0;

//###########################################################################
//                      main code
//###########################################################################
void main(void)
{
    int counter=0;  // binary counter for digital output

    InitSysCtrl();  // Basic Core Init from DSP2833x_SysCtrl.c

    EALLOW;
    SysCtrlRegs.WDCR= 0x00AF;   // Re-enable the watchdog
    EDIS;           // 0x00AF  to NOT disable the Watchdog, Prescaler = 64

    DINT;               // Disable all interrupts

    Gpio_select();      // GPIO9, GPIO11, GPIO34 and GPIO49 as output
                        // to 4 LEDs at Peripheral Explorer Board

    Setup_ePWM1();     // init  ePWM1A,B

    Setup_ePWM2();     // init  ePWM2A,B

         ////// START-UP CODE for 3 seconds STARTS HERE. After 3 secs, it will never run again
                 /// From line 70-100 ///

             EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
             EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
             EPwm1Regs.TBCTL.bit.CTRMODE = 2; // up - down mode
             EPwm1Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up
             EPwm1Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up
             EPwm1Regs.TBPRD = 1500/2; // 1KHz - PWM signal
             EPwm1Regs.CMPA.half.CMPA = 750/2; // 50% duty cycle first
             EPwm1Regs.CMPB = 750/2;
             EPwm1Regs.DBRED = 45; // 10 microseconds delay
             EPwm1Regs.DBFED = 45; // for rising and falling edge
             EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
             EPwm1Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
             EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

             EPwm2Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
             EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
             EPwm2Regs.TBCTL.bit.CTRMODE = 2; // up - down mode
             EPwm2Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up
             EPwm2Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up
             EPwm2Regs.TBPRD = 1500/2; // 1KHz - PWM signal
             EPwm2Regs.CMPA.half.CMPA = 750/2; // 50% duty cycle first
             EPwm2Regs.CMPB = 750/2;
             EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;   // generate a syncout if CTR = 0
             EPwm2Regs.TBCTL.bit.PHSEN = 1;      // enable phase shift for ePWM2
             EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;   // syncin = syncout
             EPwm2Regs.TBPHS.half.TBPHS = 1500/2; // 1/3 phase shift
             EPwm2Regs.DBRED = 45; // 10 microseconds delay
             EPwm2Regs.DBFED = 45; // for rising and falling edge
             EPwm2Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
             EPwm2Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
             EPwm2Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

             /// STARTUP CODE ENDS ////

    Setup_eCAP1();      // init  eCAP1

    InitPieCtrl();      // basic setup of PIE table; from DSP2833x_PieCtrl.c

    InitPieVectTable(); // default ISR's in PIE

    EALLOW;
    PieVectTable.TINT0 = &cpu_timer0_isr;
    PieVectTable.ECAP1_INT= &eCAP1_isr;
    EDIS;

    InitCpuTimers();    // basic setup CPU Timer0, 1 and 2

    ConfigCpuTimer(&CpuTimer0,150,100000);

    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;  // Enable CPU Timer 0 INT
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;  // Enable ECAP1_INT in PIE group 4
    IER |= 0x0009;

    EINT;
    ERTM;

    CpuTimer0Regs.TCR.bit.TSS = 0;  // start timer0

    while(1)
    {

        Duty_cycle_ratio = ((double)((int32)PWM_Duty)) / 283; // This number is a ratio between 0-1
//        Duty_cycle_ratio = ((double)((int32)PWM_Duty)) / TPWM); // This number is a ratio between 0-1
        A1= (Duty_cycle_ratio * 3.0); // Analog Input voltage
        e = (ref - A1);
        se = se + e;
        de = e-le;
        pid_out = (Kp*e) + (Ki*se) + (Kd*de); // Pid equation
//        le = e;

//        if (pid_out > max)
//        {
//            pid_out = max;
//        }
//        else if (pid_out < min)
//       {
//            pid_out = min;
//        }

        updated_dutycycle = (((double)pid_out) + 0.25 );///+0.6,-1.5,0.25
//        updated_dutycycle = (((double)pid_out));
        if (updated_dutycycle > max)
                {
                   updated_dutycycle = max;
                }
        else if (updated_dutycycle < min)
                {
                   updated_dutycycle = min;
                }
        NEW_Duty = (updated_dutycycle) * TPWM;
        le = e;


        while(CpuTimer0.InterruptCount == 0);
            CpuTimer0.InterruptCount = 0;

            EALLOW;
            SysCtrlRegs.WDKEY = 0x55;   // service WD #1
            EDIS;

            counter++;
            if(counter&1) GpioDataRegs.GPASET.bit.GPIO9 = 1;
                else GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
            if(counter&2) GpioDataRegs.GPASET.bit.GPIO11 = 1;
                else GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;
            if(counter&4) GpioDataRegs.GPBSET.bit.GPIO34 = 1;
                else GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
            if(counter&8) GpioDataRegs.GPBSET.bit.GPIO49 = 1;
                else GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;
    }
}

void Gpio_select(void)
{
    EALLOW;
    GpioCtrlRegs.GPAMUX1.all = 0;       // GPIO15 ... GPIO0 = General Puropse I/O

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A active
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // ePWM1B active

    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // ePWM2A active
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // ePWM2B active


    GpioCtrlRegs.GPAMUX2.all = 0;       // GPIO31 ... GPIO16 = General Purpose I/O
    GpioCtrlRegs.GPAPUD.bit.GPIO24= 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO24= 1; // eCAP1 active

    GpioCtrlRegs.GPBMUX1.all = 0;       // GPIO47 ... GPIO32 = General Purpose I/O
    GpioCtrlRegs.GPBMUX2.all = 0;       // GPIO63 ... GPIO48 = General Purpose I/O
    GpioCtrlRegs.GPCMUX1.all = 0;       // GPIO79 ... GPIO64 = General Purpose I/O
    GpioCtrlRegs.GPCMUX2.all = 0;       // GPIO87 ... GPIO80 = General Purpose I/O

    GpioCtrlRegs.GPADIR.all = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO9 = 1;  // peripheral explorer: LED LD1 at GPIO9
    GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // peripheral explorer: LED LD2 at GPIO11

    GpioCtrlRegs.GPBDIR.all = 0;        // GPIO63-32 as inputs
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34
    GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49

    GpioCtrlRegs.GPCDIR.all = 0;        // GPIO87-64 as inputs
    EDIS;
}


void Setup_eCAP1(void)
{
//---------------------------------------------------------------------
//--- Configure eCAP1 unit for capture
//---------------------------------------------------------------------
    ECap1Regs.ECEINT.all = 0;                   // Disable all eCAP interrupts
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0;           // Disabled loading of capture results
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;         // Stop the counter

    ECap1Regs.TSCTR = 0;                        // Clear the counter
    ECap1Regs.CTRPHS = 0;                       // Clear the counter phase register

    ECap1Regs.ECCTL2.all = 0x0096;              // ECAP control register 2
    // bit 15-11     00000:  reserved
    // bit 10        0:      APWMPOL, don't care
    // bit 9         0:      CAP/APWM, 0 = capture mode, 1 = APWM mode
    // bit 8         0:      SWSYNC, 0 = no action (no s/w synch)
    // bit 7-6       10:     SYNCO_SEL, 10 = disable sync out signal
    // bit 5         0:      SYNCI_EN, 0 = disable Sync-In
    // bit 4         1:      TSCTRSTOP, 1 = enable counter
    // bit 3         0:      RE-ARM, 0 = don't re-arm, 1 = re-arm
    // bit 2-1       11:     STOP_WRAP, 11 = wrap after 4 captures
    // bit 0         0:      CONT/ONESHT, 0 = continuous mode

    ECap1Regs.ECCTL1.all = 0x01C4;              // ECAP control register 1
    // bit 15-14     00:     FREE/SOFT, 00 = stop TSCTR immediately
    // bit 13-9      00000:  PRESCALE, 00000 = divide by 1
    // bit 8         1:      CAPLDEN, 1 = enable capture results load
    // bit 7         1:      CTRRST4, 1 = reset counter on CAP4 event
    // bit 6         1:      CAP4POL, 0 = rising edge, 1 = falling edge
    // bit 5         0:      CTRRST3, 0 = do not reset counter on CAP3 event
    // bit 4         0:      CAP3POL, 0 = rising edge, 1 = falling edge
    // bit 3         0:      CTRRST2, 0 = do not reset counter on CAP2 event
    // bit 2         1:      CAP2POL, 0 = rising edge, 1 = falling edge
    // bit 1         0:      CTRRST1, 0 = do not reset counter on CAP1 event
    // bit 0         0:      CAP1POL, 0 = rising edge, 1 = falling edge

//    ECap1Regs.ECEINT.all = 0x008;              // Enable desired eCAP interrupts
    ECap1Regs.ECEINT.all = 0x028;              // Enable desired eCAP interrupts
    // bit 15-8      0's:    reserved
    // bit 7         0:      CTR=CMP, 0 = compare interrupt disabled
    // bit 6         0:      CTR=PRD, 0 = period interrupt disabled
    // bit 5         0:      CTROVF, 0 = overflow interrupt disabled
    // bit 4         0:      CEVT4, 0 = event 4 interrupt disabled
    // bit 3         1:      CEVT3, 1 = event 3 interrupt enabled
    // bit 2         0:      CEVT2, 0 = event 2 interrupt disabled
    // bit 1         0:      CEVT1, 0 = event 1 interrupt disabled
    // bit 0         0:      reserved

//    ECap1Regs.ECCLR.bit.CTROVF = 1;
//    ECap1Regs.ECCTL2.bit.REARM = 1;
}



interrupt void cpu_timer0_isr(void)
{
    CpuTimer0.InterruptCount++;
    EALLOW;
    SysCtrlRegs.WDKEY = 0xAA;   // service WD #2
    EDIS;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}


interrupt void eCAP1_isr(void)
{

    ECap1Regs.ECCLR.bit.INT = 1;                // Clear the ECAP1 interrupt flag
    ECap1Regs.ECCLR.bit.CEVT3 = 1;              // Clear the CEVT3 flag
    if (ECap1Regs.ECFLG.bit.CTROVF == 1) //  flag checking
    {
        ECap1Regs.ECCLR.bit.CTROVF = 1;
        ECap1Regs.ECCTL2.bit.REARM = 1;
    } else
        {
            // Calculate the PWM duty period (rising edge to falling edge)
            PWM_Duty = (int32)ECap1Regs.CAP2 - (int32)ECap1Regs.CAP1;

            // Calculate the PWM period (rising edge to rising edge)
            PWM_Period = (int32)ECap1Regs.CAP3 - (int32)ECap1Regs.CAP1;

//            ECap1Regs.ECCLR.bit.CTROVF = 1;
//            ECap1Regs.ECCTL2.bit.REARM = 1;

            EPwm1Regs.TBPRD = TPWM;
            EPwm2Regs.TBPRD = TPWM;
            EPwm1Regs.CMPA.half.CMPA = ((int32)NEW_Duty); // 50% duty cycle first
            EPwm1Regs.CMPB = ((int32)NEW_Duty);
            EPwm2Regs.CMPA.half.CMPA = ((int32)NEW_Duty); // 50% duty cycle first
            EPwm2Regs.CMPB = ((int32)NEW_Duty);
            EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;   // generate a syncout if CTR = 0
            EPwm2Regs.TBCTL.bit.PHSEN = 1;      // enable phase shift for ePWM2
            EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;   // syncin = syncout
            EPwm2Regs.TBPHS.half.TBPHS = TPWM; // 1/3 phase shift
            }

            PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; // Must acknowledge the PIE group 4

}

void Setup_ePWM1(void)
{
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
    EPwm1Regs.TBCTL.bit.CTRMODE = 2; // up - down mode

    EPwm1Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up, clear ePWM1A on CMPA down
    EPwm1Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up, clear ePWM1B on CMPB down

    EPwm1Regs.DBRED = 55; // 10 microseconds delay
    EPwm1Regs.DBFED = 55; // for rising and falling edge
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
    EPwm1Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
    EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

}

void Setup_ePWM2(void)
{
    EPwm2Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
    EPwm2Regs.TBCTL.bit.CTRMODE = 2; // up - down mode

    EPwm2Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up, clear ePWM1A on CMPA down
    EPwm2Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up, clear ePWM1B on CMPB down

    EPwm2Regs.DBRED = 55; // 10 microseconds delay
    EPwm2Regs.DBFED = 55; // for rising and falling edge
    EPwm2Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
    EPwm2Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
    EPwm2Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

}

//===========================================================================
// End of SourceCode.
//===========================================================================

This code is run at double TPWM = (1875/2)...(Skip the startup ePWMcode). I would like to run the whole code for different TPWM values (3750/2,3333/2,3000/2,2727/2,2500/2,2307/2,2143/2,2000/2) with a delay of 1 min for each TPWM step value (3750/2,3333/2,3000/2,2727/2,2500/2,2307/2,2143/2,2000/2). I have made changes for delays like using arrays and the loop function (Line 20, 48-50,135-137,191-195,200-203) for different TPWM vaues but it is not working and also I don't see any changes in results on an oscilloscope. The purpose is to change TPWM values as mentioned above after 1 minute delay in between. Please see the changes in the code:

Changes in Code: 

#include "DSP2833x_Device.h"

// external function prototypes
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void InitCpuTimers(void);
extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);



// Prototype statements for functions found within this file.
void Gpio_select(void);
void Setup_ePWM1(void);
void Setup_ePWM2(void);
void Setup_eCAP1(void);

interrupt void cpu_timer0_isr(void);
interrupt void eCAP1_isr(void);
void delay_minutes(float minutes);

// Global Variables
Uint32 PWM_Duty = 0;
Uint32 PWM_Period = 0;
Uint32 PWM2_Duty;
Uint32 PWM2_Period;

Uint32 NEW_Duty = 0;
Uint32 NEW_Period = 0;

double ref = 1.0f; // reference voltage for pid... 0.5orig
double A1 = 0;
double TPWM = (1875/2);//3750(40K),3333(45K),3000(50K),2727(55K),2500(60K),2307(65k),2143(70K),2000(75K),1875(80K),1765(85K)
//4285(35K),30K(5000).
double Kp = 0.1f; // Kp=0.5,2.993,1.0,0.5
double Ki = 0.001f;// Ki = 0.01,0,0.1,0.009,0.001
double Kd = 0.0f;//  Kd = 0,0.5,0.01,1.0,0.002
double le = 0.0f; // Last or previous error
double se = 0.0f; // Cummulative error
double max = 0.49f; // max output limits for pid
double min = 0.05f; // min output limits for pid
double de; // difference of error
double e; // Current error
double updated_dutycycle =0;
double pid_out = 0;
double Duty_cycle_ratio = 0;

Uint32 TPWM_values[] = {3750/2, 3333/2, 3000/2, 2727/2, 2500/2, 2307/2, 2143/2, 2000/2};
Uint32 num_TPWM_values = sizeof(TPWM_values) / sizeof(TPWM_values[0]);
Uint32 k;

//###########################################################################
//                      main code
//###########################################################################
void main(void)
{
    int counter=0;  // binary counter for digital output

    InitSysCtrl();  // Basic Core Init from DSP2833x_SysCtrl.c

    EALLOW;
    SysCtrlRegs.WDCR= 0x00AF;   // Re-enable the watchdog
    EDIS;           // 0x00AF  to NOT disable the Watchdog, Prescaler = 64

    DINT;               // Disable all interrupts

    Gpio_select();      // GPIO9, GPIO11, GPIO34 and GPIO49 as output
                        // to 4 LEDs at Peripheral Explorer Board

    Setup_ePWM1();     // init  ePWM1A,B

    Setup_ePWM2();     // init  ePWM2A,B

         ////// START-UP CODE for 3 seconds STARTS HERE. After 3 secs, it will never run again
                 /// From line 70-100 ///

             EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
             EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
             EPwm1Regs.TBCTL.bit.CTRMODE = 2; // up - down mode
             EPwm1Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up
             EPwm1Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up
             EPwm1Regs.TBPRD = 1500/2; // 1KHz - PWM signal
             EPwm1Regs.CMPA.half.CMPA = 750/2; // 50% duty cycle first
             EPwm1Regs.CMPB = 750/2;
             EPwm1Regs.DBRED = 45; // 10 microseconds delay
             EPwm1Regs.DBFED = 45; // for rising and falling edge
             EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
             EPwm1Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
             EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

             EPwm2Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
             EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
             EPwm2Regs.TBCTL.bit.CTRMODE = 2; // up - down mode
             EPwm2Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up
             EPwm2Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up
             EPwm2Regs.TBPRD = 1500/2; // 1KHz - PWM signal
             EPwm2Regs.CMPA.half.CMPA = 750/2; // 50% duty cycle first
             EPwm2Regs.CMPB = 750/2;
             EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;   // generate a syncout if CTR = 0
             EPwm2Regs.TBCTL.bit.PHSEN = 1;      // enable phase shift for ePWM2
             EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;   // syncin = syncout
             EPwm2Regs.TBPHS.half.TBPHS = 1500/2; // 1/3 phase shift
             EPwm2Regs.DBRED = 45; // 10 microseconds delay
             EPwm2Regs.DBFED = 45; // for rising and falling edge
             EPwm2Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
             EPwm2Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
             EPwm2Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

             /// STARTUP CODE ENDS ////

    Setup_eCAP1();      // init  eCAP1

    InitPieCtrl();      // basic setup of PIE table; from DSP2833x_PieCtrl.c

    InitPieVectTable(); // default ISR's in PIE

    EALLOW;
    PieVectTable.TINT0 = &cpu_timer0_isr;
    PieVectTable.ECAP1_INT= &eCAP1_isr;
    EDIS;

    InitCpuTimers();    // basic setup CPU Timer0, 1 and 2

    ConfigCpuTimer(&CpuTimer0,150,100000);

    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;  // Enable CPU Timer 0 INT
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;  // Enable ECAP1_INT in PIE group 4
    IER |= 0x0009;

    EINT;
    ERTM;

    CpuTimer0Regs.TCR.bit.TSS = 0;  // start timer0

    for (k = 0; k < num_TPWM_values; k++)
        {
            TPWM = TPWM_values[k];

             while(1)
            {

                  Duty_cycle_ratio = ((double)((int32)PWM_Duty)) / 283; // This number is a ratio between 0-1
//                Duty_cycle_ratio = ((double)((int32)PWM_Duty)) / TPWM); // This number is a ratio between 0-1
                  A1= (Duty_cycle_ratio * 3.0); // Analog Input voltage
                  e = (ref - A1);
                  se = se + e;
                  de = e-le;
                  pid_out = (Kp*e) + (Ki*se) + (Kd*de); // Pid equation
//                le = e;

//                if (pid_out > max)
//                  {
//                    pid_out = max;
//                  }
//                else if (pid_out < min)
//                  {
//                    pid_out = min;
//                  }

                  updated_dutycycle = (((double)pid_out) + 0.25 );///+0.6,-1.5,0.25
//                updated_dutycycle = (((double)pid_out));
                  if (updated_dutycycle > max)
                     {
                       updated_dutycycle = max;
                     }
                  else if (updated_dutycycle < min)
                     {
                       updated_dutycycle = min;
                     }
                  NEW_Duty = (updated_dutycycle) * TPWM;
                  le = e;


                  while(CpuTimer0.InterruptCount == 0);
                  CpuTimer0.InterruptCount = 0;

                  EALLOW;
                  SysCtrlRegs.WDKEY = 0x55;   // service WD #1
                  EDIS;

                  counter++;
                  if(counter&1) GpioDataRegs.GPASET.bit.GPIO9 = 1;
                  else GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
                  if(counter&2) GpioDataRegs.GPASET.bit.GPIO11 = 1;
                  else GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;
                  if(counter&4) GpioDataRegs.GPBSET.bit.GPIO34 = 1;
                  else GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
                  if(counter&8) GpioDataRegs.GPBSET.bit.GPIO49 = 1;
                  else GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;

                  if (CpuTimer0.InterruptCount >= 60000000) // Check if 1 minute has elapsed
                              {
                                  CpuTimer0.InterruptCount = 0;
                                  break;
                              }
                }
        }
}

void delay_minutes(float minutes)
{
    for (k = 0; k < (minutes * 60000000); k++);
}

void Gpio_select(void)
{
    EALLOW;
    GpioCtrlRegs.GPAMUX1.all = 0;       // GPIO15 ... GPIO0 = General Puropse I/O

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A active
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // ePWM1B active

    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // ePWM2A active
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // ePWM2B active


    GpioCtrlRegs.GPAMUX2.all = 0;       // GPIO31 ... GPIO16 = General Purpose I/O
    GpioCtrlRegs.GPAPUD.bit.GPIO24= 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO24= 1; // eCAP1 active

    GpioCtrlRegs.GPBMUX1.all = 0;       // GPIO47 ... GPIO32 = General Purpose I/O
    GpioCtrlRegs.GPBMUX2.all = 0;       // GPIO63 ... GPIO48 = General Purpose I/O
    GpioCtrlRegs.GPCMUX1.all = 0;       // GPIO79 ... GPIO64 = General Purpose I/O
    GpioCtrlRegs.GPCMUX2.all = 0;       // GPIO87 ... GPIO80 = General Purpose I/O

    GpioCtrlRegs.GPADIR.all = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO9 = 1;  // peripheral explorer: LED LD1 at GPIO9
    GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // peripheral explorer: LED LD2 at GPIO11

    GpioCtrlRegs.GPBDIR.all = 0;        // GPIO63-32 as inputs
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34
    GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49

    GpioCtrlRegs.GPCDIR.all = 0;        // GPIO87-64 as inputs
    EDIS;
}


void Setup_eCAP1(void)
{
//---------------------------------------------------------------------
//--- Configure eCAP1 unit for capture
//---------------------------------------------------------------------
    ECap1Regs.ECEINT.all = 0;                   // Disable all eCAP interrupts
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0;           // Disabled loading of capture results
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;         // Stop the counter

    ECap1Regs.TSCTR = 0;                        // Clear the counter
    ECap1Regs.CTRPHS = 0;                       // Clear the counter phase register

    ECap1Regs.ECCTL2.all = 0x0096;              // ECAP control register 2
    // bit 15-11     00000:  reserved
    // bit 10        0:      APWMPOL, don't care
    // bit 9         0:      CAP/APWM, 0 = capture mode, 1 = APWM mode
    // bit 8         0:      SWSYNC, 0 = no action (no s/w synch)
    // bit 7-6       10:     SYNCO_SEL, 10 = disable sync out signal
    // bit 5         0:      SYNCI_EN, 0 = disable Sync-In
    // bit 4         1:      TSCTRSTOP, 1 = enable counter
    // bit 3         0:      RE-ARM, 0 = don't re-arm, 1 = re-arm
    // bit 2-1       11:     STOP_WRAP, 11 = wrap after 4 captures
    // bit 0         0:      CONT/ONESHT, 0 = continuous mode

    ECap1Regs.ECCTL1.all = 0x01C4;              // ECAP control register 1
    // bit 15-14     00:     FREE/SOFT, 00 = stop TSCTR immediately
    // bit 13-9      00000:  PRESCALE, 00000 = divide by 1
    // bit 8         1:      CAPLDEN, 1 = enable capture results load
    // bit 7         1:      CTRRST4, 1 = reset counter on CAP4 event
    // bit 6         1:      CAP4POL, 0 = rising edge, 1 = falling edge
    // bit 5         0:      CTRRST3, 0 = do not reset counter on CAP3 event
    // bit 4         0:      CAP3POL, 0 = rising edge, 1 = falling edge
    // bit 3         0:      CTRRST2, 0 = do not reset counter on CAP2 event
    // bit 2         1:      CAP2POL, 0 = rising edge, 1 = falling edge
    // bit 1         0:      CTRRST1, 0 = do not reset counter on CAP1 event
    // bit 0         0:      CAP1POL, 0 = rising edge, 1 = falling edge

//    ECap1Regs.ECEINT.all = 0x008;              // Enable desired eCAP interrupts
    ECap1Regs.ECEINT.all = 0x028;              // Enable desired eCAP interrupts
    // bit 15-8      0's:    reserved
    // bit 7         0:      CTR=CMP, 0 = compare interrupt disabled
    // bit 6         0:      CTR=PRD, 0 = period interrupt disabled
    // bit 5         0:      CTROVF, 0 = overflow interrupt disabled
    // bit 4         0:      CEVT4, 0 = event 4 interrupt disabled
    // bit 3         1:      CEVT3, 1 = event 3 interrupt enabled
    // bit 2         0:      CEVT2, 0 = event 2 interrupt disabled
    // bit 1         0:      CEVT1, 0 = event 1 interrupt disabled
    // bit 0         0:      reserved

//    ECap1Regs.ECCLR.bit.CTROVF = 1;
//    ECap1Regs.ECCTL2.bit.REARM = 1;
}



interrupt void cpu_timer0_isr(void)
{
    CpuTimer0.InterruptCount++;
    EALLOW;
    SysCtrlRegs.WDKEY = 0xAA;   // service WD #2
    EDIS;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}


interrupt void eCAP1_isr(void)
{

    ECap1Regs.ECCLR.bit.INT = 1;                // Clear the ECAP1 interrupt flag
    ECap1Regs.ECCLR.bit.CEVT3 = 1;              // Clear the CEVT3 flag
    if (ECap1Regs.ECFLG.bit.CTROVF == 1) //  flag checking
    {
        ECap1Regs.ECCLR.bit.CTROVF = 1;
        ECap1Regs.ECCTL2.bit.REARM = 1;
    } else
        {
            // Calculate the PWM duty period (rising edge to falling edge)
            PWM_Duty = (int32)ECap1Regs.CAP2 - (int32)ECap1Regs.CAP1;

            // Calculate the PWM period (rising edge to rising edge)
            PWM_Period = (int32)ECap1Regs.CAP3 - (int32)ECap1Regs.CAP1;

//            ECap1Regs.ECCLR.bit.CTROVF = 1;
//            ECap1Regs.ECCTL2.bit.REARM = 1;

            EPwm1Regs.TBPRD = TPWM;
            EPwm2Regs.TBPRD = TPWM;
            EPwm1Regs.CMPA.half.CMPA = ((int32)NEW_Duty); // 50% duty cycle first
            EPwm1Regs.CMPB = ((int32)NEW_Duty);
            EPwm2Regs.CMPA.half.CMPA = ((int32)NEW_Duty); // 50% duty cycle first
            EPwm2Regs.CMPB = ((int32)NEW_Duty);
            EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;   // generate a syncout if CTR = 0
            EPwm2Regs.TBCTL.bit.PHSEN = 1;      // enable phase shift for ePWM2
            EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;   // syncin = syncout
            EPwm2Regs.TBPHS.half.TBPHS = TPWM; // 1/3 phase shift
        }

            PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; // Must acknowledge the PIE group 4

}

void Setup_ePWM1(void)
{
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
    EPwm1Regs.TBCTL.bit.CTRMODE = 2; // up - down mode

    EPwm1Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up, clear ePWM1A on CMPA down
    EPwm1Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up, clear ePWM1B on CMPB down

    EPwm1Regs.DBRED = 55; // 10 microseconds delay
    EPwm1Regs.DBFED = 55; // for rising and falling edge
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
    EPwm1Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
    EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

}

void Setup_ePWM2(void)
{
    EPwm2Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 2
    EPwm2Regs.TBCTL.bit.CTRMODE = 2; // up - down mode

    EPwm2Regs.AQCTLA.all = 0x0060; // set ePWM1A on CMPA up, clear ePWM1A on CMPA down
    EPwm2Regs.AQCTLB.all = 0x0600; // set ePWM1B on CMPB up, clear ePWM1B on CMPB down

    EPwm2Regs.DBRED = 55; // 10 microseconds delay
    EPwm2Regs.DBFED = 55; // for rising and falling edge
    EPwm2Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
    EPwm2Regs.DBCTL.bit.POLSEL = 2; // S3=1 inverted signal at ePWM1B
    EPwm2Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A = source for RED & FED

}

//===========================================================================
// End of SourceCode.
//===========================================================================

Please suggest and rectify in the change code for my requirements. 

Thanks 

Kind Regards

Arsalan

  • Hi Arsalan,

    So to clarify, are you trying to adjust your TBPRD value at regular intervals (e.g. 1 minute in between each TBPRD update) or are the time intervals proportional to the period of the PWM? Are you already trying to use a CPUTIMER interrupt to update the TBPRD value of the PWM at the desired cadence?

    When you say that the code is not working, could you elaborate? Are you able to run the program but do not see the desired output?

    To debug this, I'd say the first step (to sanity check) is to be sure you have the correct/expected PWM output without even adjusting the TBPRD (you can try commenting out the other parts of the code). Once you verify this looks ok, then we can try to add in a method of updating TBPRD. Step through the code and follow any calculations to see if they are being made correctly, and simultaneously watch the PWM and other registers in the CCS Registers window and any variable values to also watch if they are being changed. Do you see any missing or incorrect behaviors when you do this?

    Best Regards,

    Allison