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.

TMS320F28374D: Sine Wave Reference - Not the Right Frequency

Part Number: TMS320F28374D

Hello, 

I am creating a reference voltage for an inverter using F2837xD c2000 microcontroller. The count and sampling time variables are adjusted based on the adc sampling frequency. I am using the output of this reference signal to control a full bridge unfolder using GPIO pins. However, the frequency of the output signal is at ~7.8Hz instead of 60 Hz and varies as I vary the sampling frequency. I am not sure what I am missing in my code. I would appreciate any help. Thank you.

I have also attached my code. 

Omega=377;

timeVar=1000;

fs=300e3;

tline=1/60; 

tsample=5*(1/fs);

sample_period=5*333; (using the 100MHz cpu clock frequency)
count_max=1000; (round(tline/tsample));

Vgrid=Vpk*sin(Omega*timeVar*0.000066);

Below is the code. 


// Included Files
// IN ac-dc code
//
#include "F28x_Project.h"
#include <math.h>
#include <stdio.h>



Uint16 switching_period = 333;
Uint16 duty50 = 166;
Uint16 duty_lag = 166;
Uint16 duty_lead = 166;
Uint16 Iin_temp,Iin_avg,Iin_1,Iin_2,Iin_3, Iin_4, Iin_5, Iin_6, Iin_7, Iin_8, Iin_9, Iin_10, Iin_11,Iin_12, Iin_13, Iin_14, Iin_15;
Uint16 Vin_temp,Vin_avg,Vin_1,Vin_2,Vin_3;
int16 Vout_temp =0;
int16 Vsyncp_temp =0;
int16 Vsyncn_temp =0;
Uint16 sample_period=1660;  // Sampling at multiples of switching period
int16 j=0;
int16 k =0;
int16 i=0;

float count = 0;
float Vout_ref = 2482;
float Vout, Vout_err, Vout_err1;
double Vin;
double Iin_ref,Iin,Iin_err,Iin_err1;
double Vsyncp,Vsyncn;
double Vcomp,Vcomp1;
double Phi=0;
double Phi_rad=0;
double halfPhi=0;
double Phi1=0;
int16 rec_lead,rec_lag,rec_leadx,rec_lead1,rec_lag1;

double Phi_satup = 83;
double Phi_satdown = 0;

double delta=58;
double twodelta =116;

double Vgrid=0;
double timeVar=0;

double Vrms=10;

double Vpk;



//
// 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;
EPWM_INFO epwm2_info;
EPWM_INFO epwm3_info;




//
//  Function Prototypes
//
void InitEPwm1Example(void);
void InitEPwm2Example(void);
void InitEPwm3Example(void);
void InitEPwm4Example(void);
void InitEPwm5Example(void);
__interrupt void adca1_isr(void);
void ConfigureADC(void);
void SetupADCEpwm(void);
//void error(void);

//
// Main
//
void main(void)
{
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
    InitSysCtrl();

    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    //InitGpio();

    //
    // Enable PWM1, PWM2 and PWM3
    //
    CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    CpuSysRegs.PCLKCR2.bit.EPWM2=1;
    CpuSysRegs.PCLKCR2.bit.EPWM3=1;
    CpuSysRegs.PCLKCR2.bit.EPWM4=1;
    CpuSysRegs.PCLKCR2.bit.EPWM5=1;

    //
    // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
    // These functions are in the F2837xD_EPwm.c file
    //
    InitEPwmGpio();
    Gpio_setup1();


    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;

    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xD_PieCtrl.c file.
    //
    InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_PieVect.c.
    //
    InitPieVectTable();



    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.ADCA1_INT = &adca1_isr;
    EDIS;   // This is needed to disable write to EALLOW protected registers

    ConfigureADC();

    //
    // For this example, only initialize the ePWM
    //
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    //ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV=0; // added to make sure that the epwmclk =sysclk/1 or 200MHz otherwise it's 100MHz
    EDIS;

    InitEPwm1Example();
    InitEPwm2Example();
    InitEPwm3Example();
    InitEPwm4Example();
    InitEPwm5Example();



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


    SetupADCEpwm();

    //
    // Step 4. User specific code, enable interrupts:
    //
    // Enable CPU INT1 which is connected to adc int1:
    //


    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

    IER |= M_INT1;

    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM


    //
    // Step 5. IDLE loop. Just sit and loop forever (optional):
    //
    for(;;)
    {
        asm ("  NOP");
    }
}

void ConfigureADC(void) // working
{

    EALLOW;

    //
    //write configurations
    //
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 (ADCCLK = 50 MHz -> max limit in data sheet)
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);

    //
    //Set pulse positions to late
    //
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    //
    //power up the ADC
    //
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    AdcaRegs.ADCSOCPRICTL.bit.SOCPRIORITY = 0;  // round robin mode

    //
    //delay for 1ms to allow ADC time to power up
    //
    DELAY_US(1000);

    EDIS;

}

void SetupADCEpwm() // working
{

    //
    //Select the channels to convert and end of conversion flag
    //
    EALLOW;

    //Vin on ADCINA0
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert ADCINA0
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 50; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 13; //trigger on ePWM5 SOCA

    //Iin on ADCINA1
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert ADCINA1
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = 50; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 13; //trigger on ePWM5 SOCA

    //Vout on ADCINA2
    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC2 will convert ADCINA2
    AdcaRegs.ADCSOC2CTL.bit.ACQPS = 50; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 13; //trigger on ePWM5 SOCA

    //Vsync1 on ADCINA3
    AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC2 will convert ADCINA3
    AdcaRegs.ADCSOC3CTL.bit.ACQPS = 50; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 13; //trigger on ePWM5 SOCA

    //Vsync2 on ADCINA3
    AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC2 will convert ADCINA4
    AdcaRegs.ADCSOC4CTL.bit.ACQPS = 50; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 13; //trigger on ePWM5 SOCA

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;


}

interrupt void adca1_isr(void)
{

    Vpk=1.414*Vrms;

    Vgrid=Vpk*sin(Omega*timeVar*0.000016);

    // diode bridge control
    if(Vgrid >=0)
    {
        GpioDataRegs.GPBSET.bit.GPIO48 = 1;
        GpioDataRegs.GPBSET.bit.GPIO51 = 1;
    }
    else
    {
        GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;
        GpioDataRegs.GPBCLEAR.bit.GPIO51 = 1;
    }

    if(Vgrid<0)
    {
        GpioDataRegs.GPBSET.bit.GPIO49 = 1;
        GpioDataRegs.GPBSET.bit.GPIO50 = 1;
    }

    else
    {
        GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;
        GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1;
    }


    timeVar=timeVar+1;

    if (timeVar>1000)
        timeVar=0;

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

//
// InitEPwm1Example - Initialize EPWM1 values
//
void InitEPwm1Example()
{

    //
    // Setup TBCLK
    //
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm1Regs.TBPRD = switching_period-1;       // Set timer period
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down stream module
    EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

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

    //
    // Set Compare values
    //
    EPwm1Regs.CMPA.bit.CMPA = duty50;     // Set compare A value
    EPwm1Regs.CMPB.bit.CMPB = duty50;     // Set Compare B value

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

    //
    // Set dead band
    //
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm1Regs.DBCTL.bit.HALFCYCLE = 1;
    EPwm1Regs.DBRED.bit.DBRED = 25;
    EPwm1Regs.DBFED.bit.DBFED = 25;

}

//
// InitEPwm2Example - Initialize EPWM2 values
//
void InitEPwm2Example()
{

    //
    // Setup TBCLK
    //
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm2Regs.TBPRD = switching_period-1;       // Set timer period
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;    // Disable phase loading
    EPwm2Regs.TBPHS.bit.TBPHS =switching_period-31;        // Phase is 0
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync down stream module
    EPwm2Regs.TBCTR = 0x0000;                  // Clear counter
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;

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

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

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

    //
    // Set dead band
    //
    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm2Regs.DBCTL.bit.HALFCYCLE = 1;
    EPwm2Regs.DBRED.bit.DBRED = 25;
    EPwm2Regs.DBFED.bit.DBFED = 25;

}

//
// InitEPwm3Example - Initialize EPWM3 values
//
void InitEPwm3Example(void)
{
    //
    // Setup TBCLK
    //
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm3Regs.TBPRD = switching_period-1;       // Set timer period
    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;    // Disable phase loading
    EPwm3Regs.TBPHS.bit.TBPHS = 50;        // Phase is 0
    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync down stream module
    EPwm3Regs.TBCTR = 0x0000;                  // Clear counter
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;

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

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

    //
    // Set Actions
    //
    EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM3A on Zero
    EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM3A on event A,
    // up count

    //
    // Set dead band
    //
    EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm3Regs.DBCTL.bit.HALFCYCLE = 1;
    EPwm3Regs.DBRED.bit.DBRED = 30;
    EPwm3Regs.DBFED.bit.DBFED = 30;

}

//
// InitEPwm4Example - Initialize EPWM4 values
//
void InitEPwm4Example(void)
{ //
    // Setup TBCLK
    //
    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm4Regs.TBPRD = switching_period-1;       // Set timer period
    EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;    // Disable phase loading
    EPwm4Regs.TBPHS.bit.TBPHS = 50;        // Phase is 0
    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync down stream module
    EPwm4Regs.TBCTR = 0x0000;                  // Clear counter
    EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
    EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;

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

    //
    // Set Compare values
    //
    EPwm4Regs.CMPA.bit.CMPA = duty50;  // Set compare A value
    EPwm4Regs.CMPB.bit.CMPB = duty50;  // Set Compare B value

    //
    // Set Actions
    //
    EPwm4Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM3A on Zero
    EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM3A on event A,
    // up count

    //
    // Set dead band
    //
    EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm4Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm4Regs.DBCTL.bit.HALFCYCLE = 1;
    EPwm4Regs.DBRED.bit.DBRED = 50;
    EPwm4Regs.DBFED.bit.DBFED = 50;
}

void InitEPwm5Example(void)
{

    EPwm5Regs.TBPRD = sample_period-1;       // Set timer period
    EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW; // Enable shadow mode
    EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
    EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;

    EPwm5Regs.ETSEL.bit.SOCAEN     = 1;        // Enable SOC on A group
    EPwm5Regs.ETSEL.bit.SOCASEL    = 1;        // Select SOC from CPMB while incrementing
    EPwm5Regs.ETPS.bit.SOCAPRD     = 1;        // Generate pulse on 1st event

    EPwm5Regs.CMPA.bit.CMPA = sample_period/2;    // Set compare A value

}


void Gpio_setup1(void)
{

    //
    // Enable an GPIO output on GPIO6, set it high
    //
    EALLOW;

    GpioCtrlRegs.GPBPUD.bit.GPIO48 = 0;   // Enable pullup on GPIO6
    GpioDataRegs.GPBSET.bit.GPIO48 = 1;   // Load output latch
    GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;  // GPIO6 = GPIO6
    GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1;   // GPIO6 = output

    GpioCtrlRegs.GPBPUD.bit.GPIO49 = 0;   // Enable pullup on GPIO6
    GpioDataRegs.GPBSET.bit.GPIO49 = 1;   // Load output latch
    GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0;  // GPIO6 = GPIO6
    GpioCtrlRegs.GPBDIR.bit.GPIO49= 1;   // GPIO6 = output

    GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0;   // Enable pullup on GPIO6
    GpioDataRegs.GPBSET.bit.GPIO50 = 1;   // Load output latch
    GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;  // GPIO6 = GPIO6
    GpioCtrlRegs.GPBDIR.bit.GPIO50 = 1;   // GPIO6 = output

    GpioCtrlRegs.GPBPUD.bit.GPIO51 = 0;   // Enable pullup on GPIO6
    GpioDataRegs.GPBSET.bit.GPIO51 = 1;   // Load output latch
    GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 0;  // GPIO6 = GPIO6
    GpioCtrlRegs.GPBDIR.bit.GPIO51 = 1;   // GPIO6 = output

    EDIS;

 }


void error (void)
{
    ESTOP0;         // Stop here and handle error
}