ADC/DAC/VREF/Comparators
  F350 24-bit ADC

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   F350 24-bit ADC
newish
New Member
posted July 21, 2010 12:48 PM     Click Here to See the Profile for newish     Edit/Delete Message
I am using the F350 24-bit ADC. Maybe I've been looking in the wrong place or may have just missed something in the data sheets...

Can anyone tell me what the maximum differential input voltage I can read in between, say, AIN0+ and AIN0-. I actually need to read in up to +/-1.5 VDC differential voltage but when I run the demo program with the registers set up for differential inputs, the readings are incorrect when I put a 1.5VDC battery between AIN0+ and AIN0-.

If the F350 can read up to +-1.5VDC in differential mode, what are the changes I need to make in the relevant registers.

Thanks

Al

IP: Logged

picperson
Member
posted July 22, 2010 03:29 AM     Click Here to See the Profile for picperson     Edit/Delete Message
Unipole 0 to +Vref
Bipolar -Vref to + Vref.
Using the internal reference Vref = 2.35 to 2.50, 2.45V nominal.

If your using the F350 development kit and using the internal VREF, jumper 12, pins 9 and 10 should have a link fitted to ground the -ve REF pin.

Put a meter across the +ve REF and AGND to see if the 2.45 volts is there. If not, check -Vref is connected to AGND.

What results are you getting in the ADC conversion and ADC0STA registers when you do a single ADC reading.

What do you believe you should be seeing as the results.

Is any calibration cycles included in the code.

Post the code, we can then see what setup you are using.

Then give us some time to see if we can help you out.

If you find what is wrong, please post the reason so others can learn from your experience.

Regards,
Mike.


IP: Logged

al9090
New Member
posted July 22, 2010 10:25 PM     Click Here to See the Profile for al9090   Click Here to Email al9090     Edit/Delete Message
Thanks for the reply Mike...

I've used the external reference and am getting 2.5VDC across VREF+ and AGND in the terminal strip. I've also used the demo program "F35x_ADC0_Buffered.c" that came with the evaluation board. I've then used a bench power supply to connect up to AIN0.0 and AIN0.1. Register ADC0MUX = 0x01 and so I connected the positive bench supply to AIN0.0 and the negative to AIN0.1. The readings I get when I run this program are ok up until around 1.25V and any further increase in the input voltage results in the readings becoming negative and decreasing in value. It as if the some register has over-flowed.

Relevant extracts of the example code are shown below. Essentially, its the initialization of the ADC, full internal calibration, and collection of the data, in this case 128 samples because the demo program calculated the average, standard deviation, etc..Could the problem be in the conversion to uV, "Note2:" below?


void main(void)
{
// Concatenated ADC output value
volatile long ADC_OutputVal=0;
long xdata sample_array[128];

//Full internal calibration
EIE1 &= ~0x08;
ADC0MD |= 0x01;
while (!AD0CALC);
ADC0MD &= ~0x07;

for (i = 0; i < 128; i++)
{
while(!AD0INT);
AD0INT = 0;

//concatenate ADC0 data bytes to
//form the 24-bit value
ADC_OutputVal = (char)ADC0H;
ADC_OutputVal <<= 16;
ADC_OutputVal += (long)ADC0L + ((long)ADC0M << 8);
sample_array[i] = ADC_OutputVal;
}

for (i = 0; i < 128; i++)
{
long Calculated_uV;
ADC_OutputVal = sample_array[i];

// Caculate measured voltage in uV:
// V(in uV) = ADCcode * VREF * 10 / 2^24
// Note1: Multiplying by 10 because
// VREF is in 10^-2 V
// Note2: Shifting by 4 before
// multiplying 10 to prevent
// overflow of unsigned long
// variable (32 bits)

Calculated_uV =
((((((ADC_OutputVal*2*VREF)/16)*10)/1024)*1000)/1024);

// Output result:
printf("ADC Output Code = %6ld [Calculated voltage = %+08ld uV]\n",
ADC_OutputVal, Calculated_uV);
}
}

void ADC0_Init (void)
{
unsigned ADC0_decimation;

REF0CN &= ~0x01;
ADC0CN = 0x10;
ADC0CF = 0x04;

// Generate MDCLK for modulator.
// Ideally MDCLK = 2.4576
ADC0CLK = (SYSCLK/MDCLK)-1;

// program decimation rate for desired OWR
ADC0_decimation = (unsigned long) SYSCLK/ (unsigned long) OWR /
(unsigned long) (ADC0CLK+1)/(unsigned long)128;

ADC0_decimation--;
ADC0DEC = ADC0_decimation;
ADC0BUF = 0x00;
// Select Mux inputs
ADC0MUX = 0x01;
ADC0MD = 0x80;
}

IP: Logged

al9090
New Member
posted July 22, 2010 10:32 PM     Click Here to See the Profile for al9090   Click Here to Email al9090     Edit/Delete Message
Thanks for the reply Mike...

I've used the external reference and am getting 2.5VDC across VREF+ and AGND in the terminal strip. I've also used the demo program "F35x_ADC0_Buffered.c" that came with the evaluation board. I've then used a bench power supply to connect up to AIN0.0 and AIN0.1. Register ADC0MUX = 0x01 and so I connected the positive bench supply to AIN0.0 and the negative to AIN0.1. The readings I get when I run this program are ok up until around 1.25V and any further increase in the input voltage results in the readings becoming negative and decreasing in value. It as if the some register has over-flowed.

Relevant extracts of the example code are shown below. Essentially, its the initialization of the ADC, full internal calibration, and collection of the data, in this case 128 samples because the demo program calculated the average, standard deviation, etc..Could the problem be in the conversion to uV, "Note2:" below?


void main(void)
{
// Concatenated ADC output value
volatile long ADC_OutputVal=0;
long xdata sample_array[128];

//Full internal calibration
EIE1 &= ~0x08;
ADC0MD |= 0x01;
while (!AD0CALC);
ADC0MD &= ~0x07;

for (i = 0; i < 128; i++)
{
while(!AD0INT);
AD0INT = 0;

//concatenate ADC0 data bytes to
//form the 24-bit value
ADC_OutputVal = (char)ADC0H;
ADC_OutputVal <<= 16;
ADC_OutputVal += (long)ADC0L + ((long)ADC0M << 8);
sample_array[i] = ADC_OutputVal;
}

for (i = 0; i < 128; i++)
{
long Calculated_uV;
ADC_OutputVal = sample_array[i];

// Caculate measured voltage in uV:
// V(in uV) = ADCcode * VREF * 10 / 2^24
// Note1: Multiplying by 10 because
// VREF is in 10^-2 V
// Note2: Shifting by 4 before
// multiplying 10 to prevent
// overflow of unsigned long
// variable (32 bits)

Calculated_uV =
((((((ADC_OutputVal*2*VREF)/16)*10)/1024)*1000)/1024);

// Output result:
printf("ADC Output Code = %6ld [Calculated voltage = %+08ld uV]\n",
ADC_OutputVal, Calculated_uV);
}
}

void ADC0_Init (void)
{
unsigned ADC0_decimation;

REF0CN &= ~0x01;
ADC0CN = 0x10;
ADC0CF = 0x04;

// Generate MDCLK for modulator.
// Ideally MDCLK = 2.4576
ADC0CLK = (SYSCLK/MDCLK)-1;

// program decimation rate for desired OWR
ADC0_decimation = (unsigned long) SYSCLK/ (unsigned long) OWR /
(unsigned long) (ADC0CLK+1)/(unsigned long)128;

ADC0_decimation--;
ADC0DEC = ADC0_decimation;
ADC0BUF = 0x00;
// Select Mux inputs
ADC0MUX = 0x01;
ADC0MD = 0x80;
}

IP: Logged

vanmierlo
Member
posted July 23, 2010 05:26 AM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
Calculated_uV = ((((((ADC_OutputVal*2*VREF)/16)*10)/1024)*1000)/1024);

When ADC_OutputVal >= 0x00800000 the multiplication with 2*VREF overflows(assuming VREF=250).

Furthermore by assigning ADC_OutputVal with (ADC0H<<16) | (ADC0M<<8) | ADC0L you loose the sign. I advise to assign it with (ADC0H<<24) | (ADC0M<<16) | (ADC0L<<8) and divide by 256 afterwards.

IP: Logged

newish
New Member
posted July 25, 2010 01:23 AM     Click Here to See the Profile for newish     Edit/Delete Message
much appreciated for the solution...

Al

IP: Logged

All times are CT (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | MCU User Forum

Have you seen our MCU Knowledge Base?


Ultimate Bulletin Board 5.47b