xmega128a1 dac use and setup help

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been confused about the dac setup and use..

To the While(1) i will wrote something like
for....{
internal_Vcc = 3.6;
Vdac(i) =(float)daca_write(0)*(internal_Vcc/1.6V)/ 0xFFF;
delay(..);
}
and also adc output like
for.....{
adc_data[j]=(float) adca_read(j)*1000/2048.;
delay(..);
)

But what i will see at the oscilloscope?
and which is my digital source that i will convert?

how i will see the same Volts that i have for source to any channels of the adc?

for example to connect a sinewave source then i will convert it to digital with the adc and then i will convert that digital to analog with the dac and from the dac to have the same waveform.

Avr xmega128a1 has ADCA , ADCB and DACA,DACB for the adc i know that i can use ch0-ch7 for the dac which channels can i use?

thanks

these two initializations is from the codevision wizard.

// Function used to write data to a DACA channel ch
void daca_write(unsigned char ch, unsigned int data)
{
register unsigned char m=ch ? DAC_CH1DRE_bm : DAC_CH0DRE_bm;
// Wait for the channel data register to be ready for new data
while ((DACA.STATUS & m)==0);
// Write new data to the channel data register
if (m==DAC_CH1DRE_bm) DACA.CH1DATA=data;
else DACA.CH0DATA=data;
}


// ADCA channel data read function using polled mode
signed int adca_read(unsigned char channel)
{
ADC_CH_t *pch=&ADCA.CH0+channel;
signed int data;

// Start the AD conversion
pch->CTRL|=ADC_CH_START_bm;
// Wait for the AD conversion to complete
while ((pch->INTFLAGS & ADC_CH_CHIF_bm)==0);
// Clear the interrupt flag
pch->INTFLAGS=ADC_CH_CHIF_bm;
// Read the AD conversion result
((unsigned char *) &data)[0]=pch->RESL;
((unsigned char *) &data)[1]=pch->RESH;
// Compensate the ADC offset
data-=adca_offset;
return data;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your incoming analog signal is continuous and has an infinite number of points while the DAC can produce only as many points as has been sampled from the ADC. If your scope has enough detail, the waveform generated from the DAC will appear as a discrete signal or a bunch of dots.

If you want to truly recreate the continuous signal you will need to implement an 'active' reconstruction filter which is not trivial and almost always involves the use of an Op-Amp.

A couple other things. Avoid if possible using the 'float' typecast in xmega as it has no floating point unit.

The 3.6 maximum voltage rating is just that and it is not designed to be continuously run at that voltage. It is better to use 3.3V.

Hope that helps.
Dan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your answer GordonFreeman.

But i want to have the same analog signal directly as output from the xmega's DAC.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

why i can't post code?
I get a server error..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

server does not like "%" characters.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while (1)
      {
      // Place your code here
      
      for (j=0;j<=3;j++)
            {
            adc_data[j]=(float) adca_read(j)*1000/2048.;////adca differential mode 
            delay_ms(100); // 400ms to scan

		///ADC:
		///+A.4 -A.0
		///+A.5 -A.1
		///+A.6 -A.2
		///+A.7 -A.3
            }


daca_write[2]=(float)adc_data[1]*1000/2048.;//daca ch2

daca_write[3]=(float)adc_data[2]*1000/2048.;//daca ch3

dacd_write(2)=(float)adc_data[3]*1000/2048.;//dacb ch2

dacd_write(3)=(float)adc_data[3]*1000/2048.;//dacb ch3
       
      // print to lcd & uart
        lcd_clear();
        
        for (j=0;j<=3;j++)
        {
        ftoa(adc_data[j],1,str);
        sprintf(temp,"Ch"%"d: "%"s mV",(j+1),str);
        lcd_gotoxy(0,j);
        lcd_puts(temp);
        puts(temp);
        putchar('\r');
        adc_data[j]=0;
        }
      }
     
}

is that code ok??
thanks Jim

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I made some changes to be better and faster the code and now i want to use as input to the ADC only 3 signals. So these 3 signals i want to take them back from the DAC. adca_read is the ADC function in portA, daca_write is DAC function in portA and dacb_write is DAC function in portB.

These 3 signals is from a 3-axis accelerometer.

ADC is in differential mode.

Is it good?

while (1)
      {
      // Place your code here
      
      for (j=0;j<=3;j++)
            {
            adc_data[j]= adca_read(j);////adca differential mode 
            delay_ms(100); // 400ms to scan

		///ADC:
		///+A.4 -A.0
		///+A.5 -A.1
		///+A.6 -A.2
		///+A.7 -A.3
            }



daca_write(4)= adc_data[0];//daca ch3

dacd_write(3)= adc_data[1];//dacb ch2

dacd_write(4)= adc_data[2];//dacb ch3
       
      // print to lcd & uart
        lcd_clear();
        
        for (j=0;j<=2;j++)
        {
        ftoa(adc_data[j]*3.3/1.6.,1,str);
        sprintf(temp,"Ch"%"d: "%"s mV",(j+1),str);
        lcd_gotoxy(0,j);
        lcd_puts(temp);
        puts(temp);
        putchar('\r');
        adc_data[j]=0;
        }
      }
     
}