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.

Digital-control of DC-DC converter ADC sample issue

Hellow

This is Zhi, I am doing the close-loop experiment of phase controlled resonant converter. The high output voltage is divided and isolated  and input to ADC pin, which is from 0 to 1V, lower than 3V. but the sampled value is some times 0 and some times 32768....hope any one knows why the sampled value is like this.. thank u very much. I think my code may have problem, sth not right in epwm start of conversion part...I also posted my code below and hope anyone can help me to point out the fault...thank u so much!!

The first three epwm modules are used to trigger my IGBT... the fourth epwm module is four adc start of conversion..

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include <math.h>
#include <stdio.h>

const float pi=3.1416;
int long step=0;
double corr=0;
//ADC variable definitions
int i=0;
int ii=0;
int k=0;
Uint16 Voltage1[10]={0,0,0,0,0,0,0,0,0,0};
Uint16 Voltage2[10]={0,0,0,0,0,0,0,0,0,0};
int loopexit=0;

//SPRI variable defination
float I_Vin[10]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
float I_Vsum=0.0f;
float I_Vsumlast=0.0f;
float I_Vsq=0.0f;
float I_Vrms=0.0f;
float I_Vref=4;

int j=0;
float eI0=0.0f;
float eI1=0.0f;
float eI2=0.0f;
float eI3=0.0f;
float uI0=3.14f;
float uI1=3.14f;
float uI2=3.14f;
float uI3=3.14f;
float I_phipwm=0.0f;

//SPRC variable initialization
float C_Vin[10]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
float C_Vsum=0.0f;
float C_Vsumold=0.0f;
float C_Vsumold2=0.0f;
float C_Vavg=0.0f;
float C_Vmax=0.0f;
float C_Vmaxold=0.0f;
float C_Vmaxavg=0.0f;
float C_Vavglast=0.0f;
float C_Vref=500.0;
float C_Vrefnew=0.0;
float C_Vrefold=0.0;
int l=0;
float e0=0.0f;
float e1=0.0f;
float e2=0.0f;
float e3=0.0f;
float u0=3.14f;
float u1=3.14f;
float u2=3.14f;
float u3=3.14f;
float C_phipwm=0.0f;

// Prototype statements for functions found within this file.
void InitEPwm1Example(void);
void InitEPwm2Example(void);
void InitEPwm3Example(void);
void InitEPwm4Example(void);
interrupt void adc_isr(void);


void InitEPwm1Example()
{

   EPwm1Regs.TBPRD =3750;                        // Set timer period
   EPwm1Regs.CMPA.half.CMPA =1905;
   EPwm1Regs.CMPB=1845;
   EPwm1Regs.TBPHS.half.TBPHS = 0;           // Phase is 0
   EPwm1Regs.TBCTR = 0x0000;                      // Clear counter


   // Setup TBCLK
   EPwm1Regs.TBCTR = 0;
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
   EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
   EPwm1Regs.TBCTL.bit.SYNCOSEL =TB_CTR_ZERO;
   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

   EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // Load registers every ZERO
   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
   EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

   // Setup compare

   // Set actions
  EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM1A on Zero
   EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;


   EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Set PWM1A on Zero
   EPwm1Regs.AQCTLB.bit.CBD = AQ_SET;

}


void InitEPwm2Example()
{

   EPwm2Regs.TBPRD =3750;                        // Set timer period
   EPwm2Regs.CMPA.half.CMPA =1905;
   EPwm2Regs.CMPB=1845;
   EPwm2Regs.TBPHS.half.TBPHS =2500;        // Phase is 0
   EPwm2Regs.TBCTR = 0x0000;                      // Clear counter
 // Setup compare

   // Setup TBCLK
   EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
   EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;// Disable phase loading
   EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;

   EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
   EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
   EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;          // Slow just to observe on the scope

   EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // Load registers every ZERO
   EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
   EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

   // Set actions
   EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM2A on Zero
   EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;


   EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;           // Set PWM2A on Zero
   EPwm2Regs.AQCTLB.bit.CBD = AQ_SET;

}

void InitEPwm3Example()
{

   EPwm3Regs.TBPRD =3750;                         // Set timer period
    EPwm3Regs.CMPA.half.CMPA =1905;
   EPwm3Regs.CMPB=1845;
   EPwm3Regs.TBPHS.half.TBPHS =1250;            // Phase is 0
   EPwm3Regs.TBCTR = 0;                       // Clear counter
     // Setup compare

 

   // Setup TBCLK
   EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
   EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
   EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;

   EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
   EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
   EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;          // Slow so we can observe on the scope

   EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // Load registers every ZERO
   EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
   EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;


   // Set actions
   EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;              // Set PWM3A on Zero
   EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;

   EPwm3Regs.AQCTLB.bit.CAU = AQ_CLEAR;            // Set PWM3A on Zero
   EPwm3Regs.AQCTLB.bit.CAD = AQ_SET;


}

void InitEPwm4Example()
{
    EPwm4Regs.TBPRD =178;                         // Set timer period
    EPwm4Regs.CMPA.half.CMPA =89;
    EPwm4Regs.TBPHS.half.TBPHS =0;            // Phase is 0
    EPwm4Regs.TBCTR = 0;                       // Clear counter

    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;        // Disable phase loading
    EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW;

    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
    EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;          // Slow so we can observe on the scope

    EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // Load registers every ZERO
    EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    EPwm4Regs.AQCTLA.bit.CAU = AQ_SET;              // Set PWM3A on Zero
    EPwm4Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    EPwm4Regs.AQCTLB.bit.CAU = AQ_CLEAR;            // Set PWM3A on Zero
    EPwm4Regs.AQCTLB.bit.CAD = AQ_SET;
    EPwm4Regs.ETSEL.bit.SOCAEN=1;
    EPwm4Regs.ETSEL.bit.SOCASEL=4;
    EPwm4Regs.ETPS.bit.SOCAPRD=1;
}

//SPRI RMS calculation
void I_calcRMS(void)
{
 I_Vsumlast=I_Vsum;
 I_Vsum=0.0;
 for(j=0;j<=9;j++)
 {
  I_Vsq=I_Vin[j]*I_Vin[j];
  I_Vsum=I_Vsum+I_Vsq;
 }
 I_Vrms=sqrt(I_Vsum/10.0);
}
//SPRI Control calculation
void I_control(void)
{
 eI0=I_Vref-I_Vrms;
 uI0=-0.0009538*eI0+0.0006462*eI1+uI1;
 if (uI0<0){
  uI0=0;
 }
 else if(uI0>pi){
  uI0=pi;
 }
 eI1=eI0;
 uI1=uI0;
}
void C_calcAVG(void)
{
 C_Vsumold=C_Vsum;
 C_Vsum=0.0;
 for(l=0;l<=9;l++)
 {
  C_Vsum=C_Vsum+C_Vin[l];
 }
 C_Vavg=(C_Vsum)/10.0;
}
void C_controlcalc(void)
{
 e0=(C_Vref-C_Vavg)/157;
 u0=-0.000607*e0+0.0007046*e1-0.0006328*e2+0.0003516*e3+1.286*u1-0.3061*u2+0.02041*u3;
 if(u0<0)
 {
  u0=0;
 }
 else if(u0>pi)
 {
  u0=pi;
 }
 e3=e2;
 e2=e1;
 e1=e0;
 u3=u2;
 u2=u1;
 u1=u0;
}
void adjustPWM(void)
{
 I_phipwm=floor(1193.66*uI0);
 C_phipwm=floor(1193.66*u0);
 EPwm2Regs.TBPHS.half.TBPHS=I_phipwm;
 EPwm3Regs.TBPHS.half.TBPHS=C_phipwm;
}
void readADC(void){
 i=0;
 ii=0;
 AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
 //EPwm4Regs.ETSEL.bit.SOCAEN = 1;        // Enable SOC on A group
 //EPwm4Regs.ETSEL.bit.SOCASEL = 4;       // Select SOC from from CPMA on upcount
 //EPwm4Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event
 EPwm4Regs.CMPA.half.CMPA=89;   // Set compare A value
 //EPwm4Regs.TBPRD =178;              // Set period for ePWM1
 //EPwm4Regs.TBCTL.bit.CTRMODE =TB_COUNT_UPDOWN;    // count up and start
 //InitEPwm4Example();
 for(;;){
  if(i==10){
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;
   EPwm4Regs.CMPA.half.CMPA=180;
   break;
  }
 }
}

//ADC interrupt
interrupt void adc_isr(void){
 Voltage1[i]=AdcRegs.ADCRESULT0>>4;
 Voltage2[i]=AdcRegs.ADCRESULT1>>4;
 if(i>=1 && Voltage2[i]==0 && Voltage2[i-1]==0){
  i=0;
 }
 else{
  i++;
 }
 //Reinitialize for next ADC sequence
 AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
 AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;
 PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
 return;
}

void main(void)
{

 InitSysCtrl();
// For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
// These functions are in the DSP2833x_EPwm.c file
   InitEPwm1Gpio();
   InitEPwm2Gpio();
   InitEPwm3Gpio();
   InitEPwm4Gpio();// Disable CPU interrupts and clear all CPU interrupt flags:
   //IER = 0x0000;
   //IFR = 0x0000;


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

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

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

//ADC initialization& configuration
 EALLOW;
 #if (CPU_FRQ_150MHZ)
 #define ADC_MODCLK 0x3
 #endif
 #if (CPU_FRQ_100MHZ)
 #define ADC_MODCLK 0x2
 #endif
   EDIS;
   EALLOW;
   SysCtrlRegs.HISPCP.all=ADC_MODCLK;
   EDIS;
   DINT;  //Disable cup interrupt
   InitPieCtrl();
   IER=0x0000;
   IFR=0x0000;
   InitPieVectTable();
   EALLOW;
   PieVectTable.ADCINT=&adc_isr;
   EDIS;
   InitAdc();
   PieCtrlRegs.PIEIER1.bit.INTx6=1;
   IER |=M_INT1;
   EINT;
   ERTM;
   //AdcRegs.ADCTRL3.bit.SMODE_SEL=0x1;
   //AdcRegs.ADCTRL1.bit.SEQ_CASC=0x1;
   AdcRegs.ADCMAXCONV.all=0x0001;
   AdcRegs.ADCCHSELSEQ1.bit.CONV00=0x3;
   AdcRegs.ADCCHSELSEQ1.bit.CONV01=0x1;
   AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;


// Step 6. IDLE loop. Just sit and loop forever (optional):
   for(;;)
   {
    readADC();
    for(ii=0;ii<=9;ii++)
    {
     I_Vin[ii]=Voltage2[ii]*0.104;
     C_Vin[ii]=Voltage1[ii]*10.3-2600.0;
    }
    I_calcRMS();
    I_control();
    C_calcAVG();
    C_controlcalc();
    adjustPWM();
   }

}

  • Where are you evaluating if the converted voltage is good?  I would recommend you run this code, then just stop it at some point and look directly at the last conversions in the ADC result registers.

  • Hi Zhi,

    About the sampled values you can restrict by using following:

    Voltage1 =((AdcRegs.ADCRESULT0>>4) );

    here you'll be limiting sampled values ranging from 0 for 0V and 4096 for 3V. You can use DC supply to verify this. Also if no input is applied ie kept floating the ADC sampled values may vary randomly. So check this first before going for a close-loop check. ADC values should stable and a bit accurate for such kind of implementation.

    Regards,

    Gautam