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.

CCS/TMS320F28035: Start ADC between PWM fronts

Part Number: TMS320F28035

Tool/software: Code Composer Studio

Hello. I am creating driver for BLDC motor. It's works, but I want to add current measurement from single-shunt. Now I start ADC every 1ms, so resualts are noisy. I think if I start conversation after some time from pwm click, I will achieve better results.

Can I achieve it?

Here is my code, where epwm and adc:

AdcRegs.ADCCTL1.bit.INTPULSEPOS	= 1;	//ADCINT1 trips after AdcResults latch
	AdcRegs.INTSEL1N2.bit.INT1E     = 1;	//Enabled ADCINT1
	AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;	//Disable ADCINT1 Continuous mode
	AdcRegs.INTSEL1N2.bit.INT1SEL	= 1;	//setup EOC0 to trigger ADCINT1 to fire

	AdcRegs.ADCSOC0CTL.bit.CHSEL 	= 1;	//(??????? ?????? ????)set SOC0 channel select to ADCINA5 (which is internally connected to the temperature sensor)
    AdcRegs.ADCSOC1CTL.bit.CHSEL 	= 1;	//(??????? ?????? ????)set SOC1 channel select to ADCINA5 (which is internally connected to the temperature sensor)  errata workaround
	AdcRegs.ADCSOC2CTL.bit.CHSEL 	= 5;	//temp0 mcu
	AdcRegs.ADCSOC3CTL.bit.CHSEL 	= 8;	//temp1 
	AdcRegs.ADCSOC4CTL.bit.CHSEL 	= 9;	//temp2 sensor
	AdcRegs.ADCSOC5CTL.bit.CHSEL	= 2;	//voltage sensor
	
	AdcRegs.ADCSOC0CTL.bit.TRIGSEL 	= 0;	//set SOC1 start trigger on EPWM1A
	AdcRegs.ADCSOC1CTL.bit.TRIGSEL 	= 0;	//set SOC0 start trigger on EPWM1A errata workaround
	AdcRegs.ADCSOC2CTL.bit.TRIGSEL 	= 0;	//set SOC0 start trigger on EPWM1A errata workaround
	AdcRegs.ADCSOC3CTL.bit.TRIGSEL 	= 0;
	AdcRegs.ADCSOC4CTL.bit.TRIGSEL 	= 0;

	AdcRegs.ADCSOC0CTL.bit.ACQPS 	= 36;	//set SOC0 S/H Window to 37 ADC Clock Cycles, (36 ACQPS plus 1)
	AdcRegs.ADCSOC1CTL.bit.ACQPS 	= 36;	//set SOC1 S/H Window to 37 ADC Clock Cycles, (36 ACQPS plus 1) errata workaround
	AdcRegs.ADCSOC2CTL.bit.ACQPS 	= 36;	//set SOC1 S/H Window to 37 ADC Clock Cycles, (36 ACQPS plus 1) errata workaround
	AdcRegs.ADCSOC3CTL.bit.ACQPS 	= 36;
	AdcRegs.ADCSOC4CTL.bit.ACQPS 	= 36;

void InitEPwm1Example()
{
   // Setup TBCLK
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
   EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period
   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
   EPwm1Regs.TBPHS.half.TBPHS = 0x0000;       // Phase is 0
   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.half.CMPA = 0.5 * EPWM1_TIMER_TBPRD;    // Set compare A value
   EPwm1Regs.CMPB = 0.5 * EPWM1_TIMER_TBPRD;              // 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

   //EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;            // Set PWM1B on Zero
   //EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // Clear PWM1B on event B, up count

   // Active Low PWMs - Setup Deadband
   EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
   EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
   EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
   EPwm1Regs.DBRED = EPWM1_MIN_DB;
   EPwm1Regs.DBFED = EPWM1_MIN_DB;

   // Interrupt where we will change the Compare Values
   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


   // Information this example uses to keep track
   // of the direction the CMPA/CMPB values are
   // moving, the min and max allowed values and
   // a pointer to the correct ePWM registers
   epwm1_info.EPwmTimerIntCount = 0;             // Zero the interrupt counter
   epwm1_info.EPwmRegHandle = &EPwm1Regs;        // Set the pointer to the ePWM module

   epwm1_info.EPwmx = 0;
}

  • Hello

    I think you should make two changes in this code:

    1) According to document SPRUGE5, page 33 ADCTRIG must be set to "0x05" - that means "ADCSOCA signal of ePWM1".

    2) Then, you should set ePWM to generate "ADCSOCA" pulse. Take a look at SPRUGE9 documentation, p. 134: you should set "ETSEL.bit.SOCASEL" to choose generate ADCSOCA signal at desired moment (CTR=ZRO or CTR=PRD), then you should set "ETSEL.bit.SOCAEN = 1" to "globally" enable this signal. Don't forget to set "ETPS.bit.SOCAPRD" to non-zero vallue. Otherwise the signal will never be generated.

    3) I also recommend you to disable EPWM interrupt and leave only ADCEOC interrupt. Beacuse now you will have ADC interrupts on the same frequency as ePWM interrupts, but ADC interrupt is better, because you'll have your ADC results ready in there. Also consider to change ADC interrupt to EOC5 instead of EOC0, because when you enter ADC interrupt from EOC5, other ADC channels may be not converted at that time. Although it depends on your code, of course...