Analog to Digital Conversion in AVR

Error message

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls in menu_set_active_trail() (line 2405 of /home/minmaro3/domains/

Input signals in microcontrollers may be digital or analog. Digital signal may have two values “0” and “1” while analog any value in given interval. while AVR microcontroller may operate with only digital signals, analog signals have to be converted to digital. Mega series of AVR have built in ADC inside chip what makes this task much easier. Lets take Atmega8 as example. If Atmega8 DIP, then it has 6 ADC inputs, if package is TQFP-32 or MLF, then there are two additional ADC inputs. All ADC channels have 10 bit resolution. Bellow you see simplified Atmega8 ADC unit. Input signals come from pins PC0-PC5. Then enters multiplexer and according to ADMUX register signals is sent from one pin to ADC converter.

For normal ADC operation there is reference voltage needed Vref and clock signal Fadc. Fadc is selected from ADCSRA register. Converted signal is stored in register pair ADCH and ADCL, because result is 10 bit length. So each ADC input can be converted one by one. Multiplexer also can additionally pass couple reference levels: 0.23V and 0V(GND). This is handy for calibrating. AREF may be set to AVCC or internal 2.56V. Otherwise it can be set to any value externally by applying voltage to AREF pin. Depending on reference voltage Vref depends measured signal range. If Vref=2.56V, then maximum signal level must not exceed 2.56V and so on. Higher voltages mus be divided with voltage dividers.

ADC conversion is simple. If resolution is set to 10 bit, then there can be 1024 values. At time moment amplitude value is taken ant passed to ADC, where converted value is stored in ADCH and ADCL register pair. At next Fadc clock cycle another value is converted. So you need to take converted value between two conversions otherwise it will be overwritten with new one.

Input value is calculated by formula:


For instance if Vref=4V, and values of registers ADCH=0x02 and ADCL=0x11, then Vin=(2·256+17)·4/1024=2.066V.

ADC may operate at 8 bit resolution, then result is stored in ADCH register. And value can be calculated by formula:


Time between conversion of internal ADC of Atmega8 can be selected between 15 – 260us what means sampling frequency 4 to 66kHz. Of course time between conversion may be longer, but recommended interval should be between 65 to 260us in order to avoid errors.

Despite AVR ADC has resolution of 10 bits, there are system error which is eaqual to ±1.5..2 LSB. Guaranteed values are 8 of 10 bits. So error because of this already is 0.4%. If internal reference voltage 2.56V (where variation may reach between 2.3 and 2.7V) is used and 1.23V(1.15 to 1.4V), then it means and if AVCC error is about 0.5 – 1%, then real precision lowers to 5 – 6 bits(1 -3%). So there are two ways to minimise error:

  • Use multiple readings and averaging;

  • Calibrating with external voltmeter and setting coefficient.

ADC may be programmed to perform one time conversion or continuous conversion. How this is done we will see in next articles.


how to find libraries of winavr like adcare those program and function that you put on site found in library?is there library help like micro e