Atmel AVR ADC sample code

Microcontroller Topics
Post Reply
User avatar
Shane
Captain
Captain
Posts: 226
Joined: Sun Jul 19, 2009 9:59 pm
Location: Jönköping, Sweden

Atmel AVR ADC sample code

Post by Shane » Thu Apr 12, 2012 11:53 pm

An ADC, or Analog to Digital Converter, allows one to convert an analog voltage to a digital value that can be used by a microcontroller. There are many sources of analog signals that one might like to measure. There are analog sensors available that measure temperature, light intensity, distance, position, and force, just to name a few.

Features :
  1. The reference (maximum) value can be taken from the AREF pin or an internal reference level of 2.56V is provided which can be accessed by the software. The AVCC may also be used as AREF by simply decoupling it(connecting to ground through a capacitor).
  2. 10-bit is available. This means that you can distinguish between two readings which have a difference of (Reference Value/210) . This means that the max value is broken up into 210-1 = 1023 parts and if you have a reference of say 5V, you can distinguish between readings 4.88mV apart.
  3. The ADC can be used in free running mode(which means it will keep on converting continuously) or single conversion mode.
  4. An interrupt may be generated once a conversion is complete, so that the MCU need not keep on checking for completion of conversion.
  5. There is a ADC Noise Cancelling mode, which allows the user to switch off the other digital circuitry which might affect the conversion.
  6. Since the result is 10 bit, the result is stored in 2 registers : ADCH and ADCL. If the ADLAR bit is not set, the result is right aligned. In that case, the 2 MSBs of the result are the 2 LSBs of the ADCH register and the remaining 8 LSBs of the result are in the ADCL. In this case, it is necessary to read the ADCL first and the ADCH second, only then will the ADC registers be updated with the next result.
  7. Accuracy is best between 50 and 200 Khz clock frequency. Running at 16 Mhz,we select the prescaler as 128, which gives a clock frequency of 8/128, which is 125 Khz.

Code: Select all

#include <avr/io.h>
#include <avr/interrupt.h>

int main (void)
{
   ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz

   ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
   ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading

   // No MUX values needed to be changed to use ADC0
   ADCSRA |= (1 << ADFR);  // Set ADC to Free-Running Mode
   ADCSRA |= (1 << ADEN);  // Enable ADC

   ADCSRA |= (1 << ADIE);  // Enable ADC Interrupt
   sei();   // Enable Global Interrupts

   ADCSRA |= (1 << ADSC);  // Start A2D Conversions

   for(;;)  // Loop Forever
   {
   }
}

ISR(ADC_vect){

   if(ADCH < 128)
   {
      PORTE |= (1 << 2); // Turn on LED1
      PORTG &= ~(1 << 0); // Turn off LED2
   }
   else
   {
      PORTE &= ~(1 << 2); // Turn off LED1
      PORTG |= (1 << 0); // Turn on LED2
   }
} 
Post Reply

Return to “Microcontrollers”