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);
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
}