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.

adc - dac conversion delay

Hi, I want to ask a tough question about adc-dac conversion.

I read an analog signal with f28377d board and then put the same signal on dac output. I observe both input analog signal and dac output signal. These signals are identical so dac and adc works well.

Howevever, when the frequency is lower than 500Hz threre is a delay between input signal and output signal. (about 250ms)

 Why is that? I mean if I see the delay on high frequencies that could be logical but high frequencies are very well. The problem is low frequencies.

The code is below:

////adc_dac.h////

#ifndef ADC_DAC_H_

#define ADC_DAC_H_

//definitions for selecting ADC resolution

#define RESOLUTION_12BIT 0 //12-bit resolution

#define RESOLUTION_16BIT 1 //16-bit resolution (not supported for all variants)

//definitions for selecting ADC signal mode

#define SIGNAL_SINGLE 0 //single-ended channel conversions (12-bit mode only)

#define SIGNAL_DIFFERENTIAL 1 //differential pair channel conversions

#define TWO_PI 6.283185307179586476925286766559

 

void ConfigureADC(void);

void ConfigureDAC(void);

void SetupADCSoftware(void);

void ConfigureADC(void)

{

EALLOW;

AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4

AdcaRegs.ADCCTL2.bit.RESOLUTION = RESOLUTION_12BIT;

AdcaRegs.ADCCTL2.bit.SIGNALMODE = SIGNAL_SINGLE;

AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;

AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4

AdcbRegs.ADCCTL2.bit.RESOLUTION = RESOLUTION_12BIT;

AdcbRegs.ADCCTL2.bit.SIGNALMODE = SIGNAL_SINGLE;

AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;

AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;

//DELAY_US(100);

EDIS;

}

void ConfigureDAC(void)

{

EALLOW;

DacaRegs.DACCTL.bit.DACREFSEL=1; ////A09

DacaRegs.DACCTL.bit.MODE=0;

DacaRegs.DACCTL.bit.LOADMODE=0;

DacaRegs.DACOUTEN.bit.DACOUTEN=1;

DacbRegs.DACCTL.bit.DACREFSEL=1; ////A11

DacbRegs.DACCTL.bit.MODE=0;

DacbRegs.DACCTL.bit.LOADMODE=0;

DacbRegs.DACOUTEN.bit.DACOUTEN=1;

DaccRegs.DACCTL.bit.DACREFSEL=1; ////A14

DaccRegs.DACCTL.bit.MODE=0;

DaccRegs.DACCTL.bit.LOADMODE=0;

DaccRegs.DACOUTEN.bit.DACOUTEN=1;

//DELAY_US(100);

EDIS;

}

void SetupADCSoftware(void)

{

Uint16 acqps;

if(RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){

acqps = 14; //75ns

}

else { //resolution is 16-bit

acqps = 63; //320ns

}

    EALLOW;

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2;  //SOC0 will convert pin ANA15

    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles

    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 3;  //SOC1 will convert pin ANA17

    AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1; //end of SOC1 will set INT1 flag

    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared

    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2;  //SOC0 will convert pin ANA18

    AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles

    AdcbRegs.ADCSOC1CTL.bit.CHSEL = 3;  //SOC1 will convert pin ANA20

    AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps + 1 SYSCLK cycles

    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 1; //end of SOC1 will set INT1 flag

    AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag

    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared

}

 

#endif /* ADC_DAC_H_ */

//////And the main/////

void main()

{

ConfigureADC();

ConfigureDAC();

SetupADCSoftware();

 

do {

while(AdcaRegs.ADCINTFLG.bit.ADCINT1 == 0);

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;

AdcaResult0 = AdcaResultRegs.ADCRESULT0;

DacaRegs.DACVALS.bit.DACVALS=AdcaResult0;

} while(1);

}

Thank you for all your attention. Have a nice  day.

  • Hi Fatih,

    What are you using to trigger the ADC?  Somewhere you should have some lines of code that look like:

    AdcxRegs.ADCSOCyCTL.bit.TRIGSEL = ?

    Presumably you are using an ePWM module or CPU timer to trigger the ADC SOCs? If so, how is this timer module configured?

    The ADC conversion time is roughly 1/3.5MHz and the DAC value should be loaded a few SYSCLK cycles after this based on your code (it will take some additional time for the DAC to slew and settle).  The time of this full process should be on the order of a few micro seconds, so a delay of many ms is not expected.

  • I am using AdcxRegs.ADCSOCyCTL.bit.TRIGSEL register on its default value (0).

    But I solved the problem it was a silly thing. I was observing the signals on oscilloscope AC mode. The reason of the delay was this. I observed the signals with DC coupling now it is ok.

     As a last thing I have a little confusion. The TRIGSEL register defines the adc trigger but why do we need it? I mean why I want to change the tirger of the adc the system clock is pretty well for the conversion why do I need a PWM signal to trigger it ?

    Thank you for your reply and attention have a nice day.

  • Hi Fatih,

    Glad you were able to solve the issue.

    Using the other triggers are useful when you want precise timing of the ADC samples.  For example, if you wanted to sample a signal at exactly 10KHz, you could setup the ePWM for this frequency and then setup that ADC SOC to also generate an interrupt.  The system would then automatically enter the ISR each time the ADC sample is complete for processing.  For devices with a DMA, samples can be automatically aggregated without CPU intervention until they are needed.

    If the ePWM module is used to control something, maybe a motor or a power supply, then ADC samples can be precisely placed somewhere in the control loop period (perhaps where switching noise is lowest, or a measured value is at its theoretical peak).