Author Topic: possible to set ADC reference voltage on individual AVR pins?  (Read 3978 times)

0 Members and 1 Guest are viewing this topic.

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,659
  • Helpful? 169
    • Society of Robots
possible to set ADC reference voltage on individual AVR pins?
« on: December 09, 2008, 11:40:22 AM »
I was browsing through the AVRlib code (adc.c and adc.h) and noticed I can set the ADC reference voltage to 2.56V. This would be incredibly useful for gyros and other low voltage output sensors!

However the code appears to only allow for configuring the entire port and not individual pins. I can't seem to figure it out. Below is the involved code . . . but not sure if a mask change would do it or not. Also, since the Axon has two ADC ports, how would I go about configuring just one of those ports? AVRlib was only written for one port in mind . . .

Code: [Select]
a2dSetReference(ADC_REFERENCE_AVCC); // configure ADC reference voltage
Code: [Select]
#define ADC_REFERENCE_AVCC 0x01 ///< 0x01 -> AVCC pin, internal VREF turned off
#define ADC_REFERENCE_256V 0x03 ///< 0x03 -> Internal 2.56V VREF
// default value
#define ADC_REFERENCE ADC_REFERENCE_AVCC
// do not change the mask value
#define ADC_REFERENCE_MASK 0xC0

// bit mask for A2D channel multiplexer
#define ADC_MUX_MASK 0x1F//0x1F//<-old version
Code: [Select]
// configure A2D converter voltage reference
void a2dSetReference(unsigned char ref)
{
outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6)));
}

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,430
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
Re: possible to set ADC reference voltage on individual AVR pins?
« Reply #1 on: December 09, 2008, 01:11:46 PM »
I believe the answers you are looking for lie within this page:

http://extremeelectronics.co.in/avr-tutorials/using-the-analog-to-digital-converter/


instead of this:

ch=ch&0b00000111;
ADMUX|=ch;

You could do this:
PORT_ON(ADMUX, MYPINNUM);   // Select ADC Channel


so it would go something like this (i think):


ADMUX= (1<<REFS1) | (1<<REFS0);    //   Internal 2.56 Voltage Reference
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Prescalar div factor (not sure if this is needed more than once)
PORT_ON(ADMUX, MYPINNUM);   // Select ADC Channel
ADCSRA|=(1<<ADSC); // Start single conversion
while(!(ADCSRA & (1<<ADIF)));  // wait for conversion to complete
ADCSRA|=(1<<ADIF); //clear ADIF
return(ADC); // return your ADC value
ADMUX = (0<<REFS1) | (0<<REFS0);  // Select AREF as voltage reference, vcc as reference would be (0<<REFS1) | (1<<REFS0)
//now take readings as normal







« Last Edit: December 09, 2008, 01:52:03 PM by pomprocker »

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,659
  • Helpful? 169
    • Society of Robots
Re: possible to set ADC reference voltage on individual AVR pins?
« Reply #2 on: December 10, 2008, 03:00:17 AM »
That didn't help (or I'm being noobish and didn't understand it properly) . . . so I'll reword my question ;D

Is it possible to configure different pins with different reference voltages simultaneously?

For example, PF0 at 2.56V, PF1 at VCC, and PF2 at VREF?

The only solution I can think of is this:
Code: [Select]
a2dSetReference(ADC_REFERENCE_AVCC); // configure ADC reference voltage
a2dConvert8bit(0);
a2dSetReference(ADC_REFERENCE_256V); // configure ADC reference voltage
a2dConvert8bit(1);
a2dSetReference(ADC_REFERENCE_AREF); // configure ADC reference voltage
a2dConvert8bit(2);

I am concerned a sensor might output 5V to an ADC pin configured for 2.56V . . . would that damage the ADC?

Offline mbateman

  • Full Member
  • ***
  • Posts: 82
  • Helpful? 0
Re: possible to set ADC reference voltage on individual AVR pins?
« Reply #3 on: December 10, 2008, 10:13:22 AM »
I spent some time with the datasheet, and it looks like there can only be one reference voltage at a time for all ADC pins.

As long as you don't go too far over Vcc, you will not damage the circuit. You will just get the max reading.

Quote
The reference voltage for the ADC (VREF) indicates the conversion range for the ADC. Single
ended channels that exceed VREF will result in codes close to 0x3FF. VREF can be selected as
either AVCC, internal 1.1V reference, internal 2.56V reference or external AREF pin.

You can switch the reference voltage before reading each pin, but there is a delay before the new reading is valid. Read section 26.5 on the atMega640 datasheet for more details.

Quote
Special care should be taken when changing differential channels. Once a differential channel
has been selected, the stage may take as much as 125 μs to stabilize to the new value. Thus
conversions should not be started within the first 125 μs after selecting a new differential channel.
Alternatively, conversion results obtained within this period should be discarded.
The same settling time should be observed for the first differential conversion after changing
ADC reference (by changing the REFS1:0 bits in ADMUX).

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,430
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
Re: possible to set ADC reference voltage on individual AVR pins?
« Reply #4 on: December 10, 2008, 11:17:21 AM »
Yeah the code above was putting the adc in single conversion mode.

That means one at a time, and before doing one you have to make sure you set the reference voltage to what you want.

Oh yeah I was also reading somewhere that putting in like a 10ms delay after changing the adc helped out.
« Last Edit: December 10, 2008, 11:18:53 AM by pomprocker »

 


Get Your Ad Here