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.

problem with ADC using ePWM interrupt in 28335

To whom this may concern:

Thank you so much for your time and discuss with the problem that I have. I have run into a problem when using ePWM interrupt with ADC sampling in 28335.  I have attached my code in the post . As a summary, I have used only one timer counter and one interrupt in my code, all relate to epwm1 timer counter and interrupt. Due to my algorithm, I need to change the compare value of EPwm1Regs.CMPA.half.CMPA  each iteration.  The switching frequency for my PWM signal sent to converter-inverter is 20 KHz.  As a reference, the PWM control signal itself is working, but when I combine the code with ADC sampling into the code, the ADC is not working. Please take a look at the code below:

void main(void)

{

  // Step 1. Initialize System Control:

   InitSysCtrl();

 EALLOW;

   #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT

     #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz

   #endif

   #if (CPU_FRQ_100MHZ)

     #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz

   #endif

   EDIS;

   EALLOW;

   SysCtrlRegs.HISPCP.all = ADC_MODCLK;

   EDIS;

// Step 2. Initalize GPIO:

   InitEPwm1Gpio();

   InitEPwm2Gpio();

   InitEPwm3Gpio();

   InitEPwm4Gpio(); 

// Step 3. Clear all interrupts and initialize PIE vector table:

// Disable CPU interrupts

   DINT;

// Initialize the PIE control registers to their default state.初始化pie控制

   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).

   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.EPWM1_INT = &epwm1_timer_isr;//

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

// Step 4. Initialize all the Device Peripherals:

   InitAdc();

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;//Disable TBCLK within the ePWM

   EDIS;

   InitEPwm1Example();

   InitEPwm2Example();

   InitEPwm3Example();

   InitEPwm4Example();

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM//使能ePWM的TBCLK

   EDIS;

// Step 5. User specific code, enable interrupts

// Initalize counters and variables:

   ConversionCount = 0;

   Out_VDCIntegr = 0;

   Out_VDCIntegr_Q21 = 0;

   IndCurErr = 0;// error for inductor current

   VDCErr=0;// error for DC-link voltage

   Out_VDCVolRsnt_3=0;

   Out_VDCVolRsnt_1_3=0;

   Out_VDCVolRsnt_2_3=0;

   EPwm1TimerIntCount = 0;

// Enable CPU INT3 which is connected to EPWM1-3 INT:

   IER |= M_INT3;

// IER |= M_INT1;                                       // Enable CPU Interrupt 1

// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3

   PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

   PieCtrlRegs.PIEIER3.bit.INTx2 = 1;

   PieCtrlRegs.PIEIER3.bit.INTx3 = 1;

   // Enable ADCINT1 in PIE

//   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;   // Enable INT 1.1 in the PIE

// Enable global Interrupts and higher priority real-time debug events:

   EINT;   // Enable Global interrupt INTM

   ERTM;   // Enable Global realtime interrupt DBGM

   // Configure ADC

   AdcConfig();

// wait for ADC to interrpt

// Step 6. IDLE loop. Just sit and loop forever (optional):

   for(;;)

   {

       asm("          NOP");

        }

}

void AdcConfig(void)

{

   EALLOW;        

   AdcRegs.ADCMAXCONV.all=0x0002;            //ConversionCount=8dui;33:4dui    

   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup conv from ADCINA0 & ADCINB0

   AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup conv from ADCINA1 & ADCINB1

   AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//ePWM SOCA enable bit for SEQ1

   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;//1;//SEQ1 interrupt enable.

   EDIS;

}

void InitEPwm1Example()

{

   EPwm1Regs.TBPRD = PWM1_TIMER_TBPRD;                       // Set timer period

   EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0

   EPwm1Regs.TBCTR = 0x0000;                      // Clear counter

   // Setup TBCLK= SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4

   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up AND DOWN

   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading

   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT   000:/1; 001:/2; 010:/4;011:/6

  //HSPCLKDIV High Speed Time-base Clock Prescale Bits 

   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;          //TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)

  //CLKDIV Time-base Clock Prescale Bits

   EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // Load registers every ZERO(保证ADC采样完整)

   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

   EPwm1Regs.CMPCTL.bit.LOADAMODE =CC_CTR_ZERO;

   EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO ;

   // Setup compare

   EPwm1Regs.CMPA.half.CMPA = 0;             //   struct CMPA_HRPWM_REG  half;     

   // Set actions

   EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // active high

   EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;

   EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;          // Set PWM1A on Zero

   EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;

   // Active Low PWMs - Setup Deadband

   EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

   EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LOC;

   EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;

   EPwm1Regs.DBRED = EPWM1_MAX_DB; //Initialized to be zero, will be changed in the main program

   EPwm1Regs.DBFED = EPWM1_MAX_DB; //Initialized to be zero, will be changed in the main program

   EPwm1_DB_Direction = DB_UP;

   // Interrupt where we will change the Deadband

   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

// use EPWM1A as the interrupt for ADC_soc

   EPwm1Regs.ETSEL.bit.SOCAEN = 1;             // Enable SOC on A group

   EPwm1Regs.ETSEL.bit.SOCASEL      = ET_CTR_ZERO;   // Select SOC from from CPMA on upcount

  // EPwm1Regs.ETPS.bit.SOCAPRD      = ET_1ST;           // Generate pulse on 1st event

   EPwm1Regs.ETPS.bit.SOCAPRD       = ET_3RD;         // Generate pulse on 2nd event

}

 

// Interrupt routines uses in this example:

interrupt void epwm1_timer_isr(void)

{

   EPwm1TimerIntCount++;

  Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;

  ConversionCount++;

  Voltage1[ConversionCount] = AdcRegs.ADCRESULT1 >>4;

  ConversionCount++;

  // If 40 conversions have been logged, start over

  if(ConversionCount == 1024)

  {

     ConversionCount = 0;

  }

  else ConversionCount++;

   Temp1 = (int32) AdcRegs.ADCRESULT0;

   //VDC = (Temp1>>12)*VDCVOLLIMIT;

   VDC = (Temp1/4096)*VDCVOLLIMIT;

   Temp1 = (int32) AdcRegs.ADCRESULT1;

   //IndCur =(Temp1>>12)*IndCURLIMIT;

   IndCur =(Temp1/4096)*IndCURLIMIT;

  // Reinitialize for next ADC sequence

  AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1

  AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit

VDCVolControl();

       IndCurControl();

PWAM_Control();

  if(a>b && a>c && b>c) //a>b>c

  {

    EPwm4Regs.CMPA.half.CMPA = (int)(3750*Db); //boost duty ratio

    EPwm1Regs.CMPA.half.CMPA = 3750;

    EPwm3Regs.CMPA.half.CMPA = 0;

EPwm2Regs.CMPA.half.CMPA = (int)(3750*Di); //inverter duty ratio,open loop

  }

  if(a>b && a>c && c>b) //a>c>b

  {

EPwm4Regs.CMPA.half.CMPA = (int)(3750*Db); //boost duty ratio

    EPwm1Regs.CMPA.half.CMPA = 3750;

    EPwm2Regs.CMPA.half.CMPA = 0;

    EPwm3Regs.CMPA.half.CMPA = (int)(3750*Di); //inverter duty ratio,open loop

  }

  if(b>a && b>c && a>c) //b>a>c

  {

 EPwm4Regs.CMPA.half.CMPA = (int)(3750*Db); //boost duty ratio

    EPwm2Regs.CMPA.half.CMPA = 3750;

    EPwm3Regs.CMPA.half.CMPA = 0;

EPwm1Regs.CMPA.half.CMPA = (int)(3750*Di); //inverter duty ratio,open loop

  }

  if(b>c && b>a && c>a) //b>c>a

  {

 

    EPwm4Regs.CMPA.half.CMPA = (int)(3750*Db); //boost duty ratio

    EPwm2Regs.CMPA.half.CMPA = 3750;

    EPwm1Regs.CMPA.half.CMPA = 0;

       EPwm3Regs.CMPA.half.CMPA = (int)(3750*Di); //inverter duty ratio,open loop

  }

  if(c>b && c>a && b>a) //c>b>a

  {

 

    EPwm4Regs.CMPA.half.CMPA = (int)(3750*Db); //boost duty ratio

    EPwm3Regs.CMPA.half.CMPA = 3750;

   EPwm1Regs.CMPA.half.CMPA = 0;

   EPwm2Regs.CMPA.half.CMPA = (int)(3750*Di); //inverter duty ratio,open loop

  }

  if(c>b && c>a && a>b) //c>a>b

  {

    EPwm4Regs.CMPA.half.CMPA = (int)(3750*Db); //boost duty ratio

    EPwm3Regs.CMPA.half.CMPA = 3750;

    EPwm2Regs.CMPA.half.CMPA = 0;

    EPwm1Regs.CMPA.half.CMPA = (int)(3750*Di); //inverter duty ratio,open loop

}

   // Clear INT flag for this timer

   EPwm1Regs.ETCLR.bit.INT = 1;

   // Acknowledge this interrupt to receive more interrupts from group 3

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

 Could someone help me take a look at this code and give me some hint on that.

Thank you so much,

yang