You are on page 1of 12

## Analog to Digital Conversion

in AVR microcontrollers

## Analog to Digital Conversion in

AVR microcontroller
In this tutorial, we will study the working of the Analog to Digital Conversion
in AVR microcontroller.

1.1

## For reactive embedded system, digital microcontroller system has to interact

with the external environment such as temperature, humidity, speed and
many more. For sensing the external environment, we use sensors which gives
output in the form of analog voltages. So for bridging the gap between analog
voltages and its digital equivalent, AVR microcontroller has an internal 10bit ADC. After getting digital equivalent of the analog value (from a sensor),
we can use them in the code.
Sensors and signal conditioning are vast topics which will not be discussed
in this chapter. But we will focus on operation of ADC present in AVR based
microcontroller and study how to operate the ADC.

1.2

## ADC is an independent block present in AVR microcontroller. It consists

of sub blocks as shown in Figure 1.1. In the heart of ADC is the DAC,
comparator and conversion logic which works on Successive Approximation
algorithm. The DAC gives the analog voltage depending on the digital input
value. The comparator gives high or low, if the input from one of the ADC
channels is higher or lower than the output of DAC. Then conversion logic
with successive approximation method determines next voltage level to be
compared.
This reference voltage determines the range and resolution of the ADC. This
1

## Figure 1.1: ADC block diagram

www.tbt.e-yantra.org

## 1.3. REGISTERS FOR CONFIGURING ADC

leads to restriction in range of input voltage level.
As AVR has a single 10 bit ADC, so it can convert single analog channel
at a time. But to convert multiple signal sources AVR microcontroller has
multiplexer switching circuit which switches different analog signal channel
at a time.
ADC also needs clock signal for its operation but it cant run at the full
speed of the CPU. According to data sheet, ADC can sample at Up to 76.9
103 Samples/Sec (Up to 15 103 Samples/sec at Maximum Resolution). So
clock to the ADC is prescaled (clock frequency is decreased). This prescalar
value (ie division factor for clock frequency) has to be selected considering
the speed of ADCs conversion process.
As ADC is a peripheral device, it needs start command called trigger
to start the conversion process. AVR ADC can be triggered in two ways.
One is through software triggering from code called Single Conversion mode.
Another one is the auto triggering mode where the source of trigger can
be Timers, Interrupts and ADC itself. In auto triggering mode, if ADC is
self-triggered then it is said to be in free running mode.

1.3

For using ADC certain registers must be configured for initialization. These
registers are used for selecting clock source, selecting channel and starting

1.3.1

ADMUX register together with MUX5 bit in ADCSRB is used for selecting
structure and description of register is given below:

REFSO, REFS1 - these bits are used for selecting the reference voltage
for ADC. Table below shows various options.

www.tbt.e-yantra.org

## 1.3. REGISTERS FOR CONFIGURING ADC

REFS0 REFS1
Voltage reference selection
0
0
AREF, Reference voltage connected to AREF pin
0
1
AVCC
1
0
Reserved
1
1
Internal 2.56 V

## In firebird V,5 Volt is connected to AREF pin.

register, otherwise it is right adjusted.
MUX4:0 , these bits together with MUX5 bit in ADCSRB register helps
to select the one of the 16 channels.

1.3.2

ADCSRA register is used for selecting the clock frequency of ADC. It also
conversion process. The other function of register is described below:

ADSC Set to one for starting the A/D conversion.
ADATE If set to one, we can select trigger source for ADC
ADIF This flag is set, when one cycle of A/D conversion ends. Hence, it is
important to check the status of this bit to know the status of the
current A/D conversion.
ADPS2:0 These bits are used for selecting the clock frequency for ADC

www.tbt.e-yantra.org

0
0
0
0
0
1
0
1
1
0
1
0
1
1
1
1

0
1
0
1
0
1
0
1

Division factor
2
2
4
8
16
32
64
128

## We can select a prescalar value of 64 (ADC clock frequency = controller

clock frequency/64 230 kHz) or 128 (ADC clock frequency 115 kHz).

1.3.3

ADCSRB register contains bits for selection of trigger source and the
MUX5 bit.

MUX5 this bit together with ADMUX4:0 is used to select required ADC
channel
ADTS2:0 These bits are used for selecting the trigger source when

1.4

## For basic operation of the ADC we have to initialize following blocks in

Setting the prescalar for suitable clock source to ADC.
Selecting the required reference voltage.
Selecting the channel to sample
Selection of the trigger source for starting the conversion process.
www.tbt.e-yantra.org

## 1.5. FIRST STEP TO REAL WORLD

application requirement.
Since the ADC has a 10 bit resolution, it has two 8 bit registers (ADCH
and ADCL) to store the result.

ADLAR bit in ADMUX register is used for setting the left or right

Selecting ADLAR=1, will store the most significant values of the conversion
version of the conversion result (ADC Data).

1.5

## First step to real world

In this section, we will learn about various settings of the ADC for getting s
sensor value and if this value is less than a certain limit sound the buzzer.
In this example, we will be running ADC in single conversion mode (i.e.
making the ADSC bit to logic 1 whenever we wish to start conversion).
We will be reading the analog value from ADC channel number 9 in this
example.

1.5.1

All the 8 pins of PORTF and PORTK act as ADC input channels.
Hence, set the direction of all the pins of both these ports as inputs
and Initialize the corresponding port pin values as 0.
www.tbt.e-yantra.org

1
2
3
4

DDRF = 0x00;
PORTF = 0x00;
DDRK = 0x00;
PORTK = 0x00;

## //set PORTF direction as input

//set PORTK direction as input

Then we have to select the frequency of clock source for ADC and
ADC, clock frequency to ADC block must be between 50 kHz to 200
Finally, select the external 5V connected to AREF pin as the reference
voltage by setting REFS1=0 and REFS1=0 in the ADMUX register.
0b10000111 = 0x87.
Initial value of ADCSRB is set to 0.

1
2
3
4

{
ADMUX = 0x00; //Vref=5V,selecting external voltage connected
to AREF pin

## ADCSRB = 0x00; // initial value

7
8

}

www.tbt.e-yantra.org

## 1.5. FIRST STEP TO REAL WORLD

1.5.2

Now for reading the ADC value from a sensor we do the following steps:
Select the channel of microcontroller where sensor is connected by
setting MUX5:0 values. For selecting ADC channel no.9,
MUX5:0=100001. In the ADMUX register, only MUX 4:0 bits are
present, hence MUX 4:0=00001.
We will use only the most significant 8 bits of the ADC conversion

1

channel no.9.

1

## Then poll the ADIF flag,for completion of conversion. (ADIF flag is

set to 1 when the conversion completes).
www.tbt.e-yantra.org

complete

## //Wait for ADC conversion to

result from ADCH register in a variable and clear the ADIF flag by
writing 1 to it.
1
2

Finally listing 1.3 contains the example function for reading a ADC channel.
1

2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18

## //This Function accepts the Channel Number and returns the

corresponding Analog Value
{
if (Ch>7)
{
//Set MUX5 bit to 1
}
Ch = Ch & 0x07;
Register
// by writing 1 to it
}
www.tbt.e-yantra.org

## 1.6. HINTS FOR EXPERIMENT 1

You may find below the list containing the ADC channel numbers and the
sensors to which they connected on your Default Firebird V robotic kit.

1.6

## The ADC conversion code snippet above described a single function to

you are expected to write two different functions one for reading white line
sensors and one for the front sharp sensor. We will discuss the basic outline
of these two functions to assist you in writing them. You must have noticed
from Figure 1.6 that the front sharp IR sensor is connected to ADC channel
no. 11 and the MUX5 bit is set to 1 for selecting this channel. So, we
will have to set MUX5 bit in ADCSRB register. The code structure will

www.tbt.e-yantra.org

10

## 1.6. HINTS FOR EXPERIMENT 1

1
2
3

{
//Set MUX5 bit in the ADCSRB register.

value for MUX 4:0

6
7

## //Continuously check ADIF bit until it becomes 0. You can

channel code snippet.

10

a variable.

11

12

13
14

15
16

17
18
19

}