You are on page 1of 12

Task Based Training (TBT-2016)

Bridging the gap:

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

What is ADC?

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

Major Blocks of ADC

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.
ADC has multiplexer which helps to select reference voltage for ADC.
This reference voltage determines the range and resolution of the ADC. This
1

1.2. MAJOR BLOCKS OF ADC

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

Registers for configuring ADC

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

1.3.1

ADMUX-ADC Multiplexer Selection Register

ADMUX register together with MUX5 bit in ADCSRB is used for selecting
the analog input channel and selecting the reference voltage. The detailed
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.


ADLAR , if set, left adjusts the ADC conversion result in the ADC data
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-ADC Control and Status Register A

ADCSRA register is used for selecting the clock frequency of ADC. It also
contains ADEN for enabling the ADC and ADSC for starting the
conversion process. The other function of register is described below:

ADEN If set to one, enables ADC


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

1.4. MINIMUM CONFIGURATION OF ADC


ADPS2 ADPS1
0
0
0
0
0
1
0
1
1
0
1
0
1
1
1
1

ADPS0
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-ADC Control and Status Register B

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
ADATE is set in ADCSRA

1.4

Minimum configuration of ADC

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


ADC peripheral block.
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


Choosing left adjusted or right adjusted mode according to the
application requirement.
Since the ADC has a 10 bit resolution, it has two 8 bit registers (ADCH
and ADCL) to store the result.

Left adjusted or Right adjusted


ADLAR bit in ADMUX register is used for setting the left or right
adjusted mode of ADC.
If ADLAR=0, ADC is in right adjusted mode. So result after
conversion is found in ADCL and ADCH register as shown below:

If ADLAR=1, ADC is in left adjusted mode. So result after conversion is found in ADCL and ADCH register as shown below:

Selecting ADLAR=1, will store the most significant values of the conversion
result in ADCH. Hence, only the ADCH register can be read for the 8 bit
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

Initialization of ADC

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.5. FIRST STEP TO REAL WORLD

1
2
3
4

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

//set PORTF direction as input


//set PORTK direction as input

For initializing the ADC, first enable the ADC by setting the ADEN
bit in ADCSRA.
Then we have to select the frequency of clock source for ADC and
reference voltage of ADC. For getting the accurate reading from the
ADC, clock frequency to ADC block must be between 50 kHz to 200
kHz. Hence, we select a prescalar of 128 (i.e. ADPS2:ADPS0=1).
Finally, select the external 5V connected to AREF pin as the reference
voltage by setting REFS1=0 and REFS1=0 in the ADMUX register.
So for initialization, values of ADMUX = 0x00 and ADCSRA =
0b10000111 = 0x87.
Initial value of ADCSRB is set to 0.

Figure 1.2: ADCSRA Register

1
2
3
4

//Function to Initialize ADC


void adc_init()
{
ADMUX = 0x00; //Vref=5V,selecting external voltage connected
to AREF pin
ADCSRA = 0x87; //ADEN=1 & ADPS2:0 = 1 1 1

ADCSRB = 0x00; // initial value

7
8

}
Listing 1.1: ADC initialization

www.tbt.e-yantra.org

1.5. FIRST STEP TO REAL WORLD

1.5.2

Reading the ADC value

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
result. Therefore set ADLAR=1 in ADMUX register.

Figure 1.3: ADMUX Register


1

ADMUX |= 0x21.

MUX5 bit must be set in the ADCSRB register to select ADC


channel no.9.

Figure 1.4: ADCSRB Register

ADCSRB |= 0x08.

Trigger the ADC by setting the start conversion bit (ADSC) in


ADCSRA Register..
1

ADCSRA| = 0x40.

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


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

1.5. FIRST STEP TO REAL WORLD

Figure 1.5: ADCSRA Register

while((ADCSRA&0x10)==0);
complete

//Wait for ADC conversion to

Once the conversion completes, finally read the ADC conversion


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

adc_value = ADCH;
ADCSRA = ADCSRA|0x10;

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
unsigned char ADC_Conversion(unsigned char Ch)
{
unsigned char adc_value;
if (Ch>7)
{
ADCSRB = 0x08;
//Set MUX5 bit to 1
}
Ch = Ch & 0x07;
ADMUX |= Ch;
ADCSRA = ADCSRA | 0x40; //Set start conversion bit
while((ADCSRA&0x10)==0);//Wait for ADC conversion to complete
adc_value=ADCH;
// Read conversion result from ADCH
Register
ADCSRA = ADCSRA|0x10; //clear ADIF (ADC Interrupt Flag)
// by writing 1 to it
ADCSRB = 0x00;
return adc_value;
}
Listing 1.2: ADC read channel
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.

Figure 1.6: ADC channel number,sensors connected, MUX5:0 values

1.6

Hints for Experiment 1

The ADC conversion code snippet above described a single function to


read ADC values from all the 16 ADC channels. However in experiment 1
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
have many similarities with the previous ADC read channel function.

www.tbt.e-yantra.org

10

1.6. HINTS FOR EXPERIMENT 1

1
2
3

unsigned char ADC_Conversion_sharp_sensor()


{
//Set MUX5 bit in the ADCSRB register.

//Set the ADLAR bit in ADMUX register and put appropriate


value for MUX 4:0

6
7

// Start the ADC conversion process by setting ADSC bit in the


ADCSRA register.

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


use the while construct used in the previous ADC read
channel code snippet.

10

//Once the conversion completes, read the digital value into


a variable.

11

12

//Clear the ADIF bit by setting it to logic 1.

13
14

//Clear the MUX5 bit in ADCSRB register.

15
16

//return read digital value.

17
18
19

}
Listing 1.3: ADC read channel
The ADC channel Read function for white line sensors will be the same as
code described in listing 1.2 except the if condition included to check if
the channel number is greater than 7. (Since the channel number of all the
three white line sensors is less than 7).
This concludes the tutorial. All the best!

www.tbt.e-yantra.org

11

You might also like