Features :
- 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).
- 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.
- The ADC can be used in free running mode(which means it will keep on converting continuously) or single conversion mode.
- An interrupt may be generated once a conversion is complete, so that the MCU need not keep on checking for completion of conversion.
- There is a ADC Noise Cancelling mode, which allows the user to switch off the other digital circuitry which might affect the conversion.
- 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.
- 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
}
}