AVR: How to take Analog input in AVR.

Filed in AVR , Articles , MCU 1 comments


Article by: Kumail Ahmed


In the last article we learned how to take digital inputs in AVR. This time we will learn how to take analog input. As you all know, natural environment is all analog. From temperature to seismic waves and from wind to fire every value is continuous in nature. But the problem is that all electronics is turning into digital, a non-continuous domain. So to acquire data from the environment we use an ADC (Analog to Digital Convertor).
For our example we will use a potentiometer. A pot produces different voltage value as it is turned. Connect the circuit as below:

ADC Schematic - Click to enlarge

ADC Schematic - Click to enlarge

This is the most basic circuit. For better voltage regulation you can add a capacitor and inductor at AVCC pin (See datasheet). Although for this purpose, you don’t need this. The POT is connected to ADC0.

ATMEGA8 has 6 ADCs. They have a 10 bit resolution. This means that the highest value in decimal is 1024. Now the code:

#include<avr\io.h>
#include<util\delay.h>
int main()
{

DDRD=0xff;                    //make portD all output
ADMUX=(1<<REFS0)|(1<<ADLAR); //Make AVcc the reference, make the

//bit value left aligned and select

//ADC0 channel.

ADCSRA=(1<<ADEN)|(1<<ADFR)|(1<<ADPS2); //Enable Analog convertor,

//set prescaler to 16

//and free running mode

while(1)

{

ADCSRA|=(1<<ADSC); //start conversion

PORTD=ADCH;       //Write ADC value to PORTD

_delay_us(5);    //optional

}

return 1;

}

As you can see, ADC requires three registers, ADMUX, ADCSRA and ADC(H or L). Internally, ADC channels are multiplexed. So to select a specific channel we have to write to the ADMUX register. Secondly, we also have to select the reference source, in this case it is AVcc pin. Lastly, ADLAR is made high to shift the 8 MSBs into ADCH. Because PORTB has a 8-bit space therefore we truncate the 2 LSBs.

Next comes ADCSRA. Through this we set the status register of the ADC.  We select the free running mode and select the conversion frequency to Fosc/16. ADC can be either interrupt driven or free running. As we are polling the data therefore, we selected the later. To understand Prescaler, you should know something about sampling rates.  This example is a tutorial so sampling rate is not an issue but when working with real environment (i.e. LM35 or LM36) sampling is an issue.  If the input frequency to the ADC is say 100KHz, our sampling frequency should be >(2*100Khz).  This is called the Nyquist’s frequency. This is the minimum limit. Selecting a frequency lower then this will cause aliasing. In our case we kept this to be 16 (see datasheet for prescaler detail). Therefore the sampling is (10MHz/16).

Lastly, to start the conversion we make ADSC high in the ADCSRA register. Notice the ‘|’(pipe) operator in this line. For more information read the previous post.

During conversion, the microcontroller simply hangs like a UNIAC or any other uni-tasking system. This is the biggest drawback of Polling. But never mind if the data is not time critical. After conversion, data is stored in the ADC register which of 10-bits. Although we could simply write:

PORTD=ADC;

But it is more logical and to the point if we write ADCH instead of ADC.  Making ADLAR high has made the data left-aligned. The figure below describes this:

Register Table - Click to enlarge

Register Table - Click to enlarge

Just to make sure we are getting the correct data we may write it to PORTD. Connect some LEDs on the port if you are doing practically (no need in protues!).

The last issue is how to interpret the data? Use the following equation for 10-bits.

ADC Value = (Vin /Vref) x 1024

In our case Vreference is 5V. For example if Vin=4V then ADC value would be 819(decimal) which is equal to 11 0011 0011 in binary. As mentioned before, 2 LSBs are truncated and the result is 1100 1100 or 204(decimal),0xCC(Hex). Respective LEDs would turn-on at PORTD.

Hope this would be helpful.

ATMEGA8 datasheet- www.atmel.com/dyn/resources/prod_documents/doc2486.pdf

View the datasheet for an in-depth discussion on ADMUX, ADCSRA and ADC register. Some techniques are also given for acquiring data with greater accuracy.

Posted by hamzaazeem   @   26 September 2009 1 comments
Tags : , , ,

Share This Post

RSS Digg Twitter StumbleUpon Delicious Technorati

1 Comments

blog comments powered by Disqus
Previous Post
«
Next Post
»
EXULT designed by ZENVERSE  |  In conjunction with Reseller Hosting from the #1 Web Hosting Provider - HostNexus.