United International University: EEE 424: Microprocessor and Interfacing Laboratory Experiment#5

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

United International University

EEE 424: Microprocessor and Interfacing Laboratory


Experiment#5
Working with Analogue to Digital Converter (ADC)

1. Objective
The objective of this experiment is to familiarize the students with the use of Analogue to Digital
converter (ADC) of ATmega32.

2. The Analogue to Digital Converter (ADC)


Temperature, pressure, humidity, velocity are a few examples of physical quantities we deal with every
day. A physical quantity is converted into electrical (voltage or current) signals by the devices which are
called transducer Transducers are also referred to as sensors. Most of the sensors produce an output
that is voltage (or current) Therefore, we need an Analogue-to-Digital (ADC) converter to translate
analogue signals to digital numbers so that microcontroller can read and process them.

3. Block Diagram of ADC


The ADC of ATmega is a 10-bit ADC. A voltage of Vref is required to be selected. It determines the step
size (minimum value) of the analogue data of conversion. The analogue voltage has to be made input to
the microcontroller and there are 8-pins (PA0-PA7) for inputting the analogue voltages to be converted.
After selecting Vref and analogue channel, a start of conversion signal starts the conversion process.
When the conversion is finished a flag is raised by the microcontroller. In polling method program has to
monitor that flag and in interrupt method the microcontroller itself monitors the flag and calls the
corresponding ISR.
Vref

Vin D0
Digital
Start Output
Conversion D10

GND
4. Registers to be used for ADC
a) ADC Data Register
The converted data is stored in a register called ADCW which is a 16-bit register, its lower byte and
higher bites can be accessed from 8-bit registers ADCL and ADCH respectively. The 10-bit digital data is
stored in 16-bit ADCW register and the data can be stored either in right or in left adjusted form.
ADCW
ADCH ADCL

b) ADC control and Status Register


It is called ADCSRA register. The format of the register is as follows:
ADCSRA
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0

ADEN – ADC enable bit (ADC will not all work if this bit not made high)
ADSC – ADC start conversion bit (by making this bit high the conversion process is started)
ADATE – ADC auto trigger enable bit (is made high if the ADC to be triggered automatically)
ADIF – ADC interrupt flag (as explained in the earlier section)
ADIE – ADC interrupt enable bit (if somebody wants to use ISR of ADC, this bit is to be high)
ADPS2:ADPS0 – Combination of this three bits decide the pre-scaling of clock for the ADC
000 – fosc
001 – fosc/2
010 – fosc/4
011 – fosc/8
100 – fosc/16
101 – fosc/32
110 – fosc/64
111 – fosc/128

c) ADC Multiplexer Register


It is called ADMUX register. The format of the register is as follows:

ADMUX
REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0

REFS1:0 – Selection of Voltage Reference. 00-AREF, 01-AVCC, 10-NOT USED, 11-internal 2.56V
ADLAR – right or left adjusted data in ADCW register, 0- right and 1- left adjustment
MUX4:0 – Combination of these 5 bits makes the selection of input channel (single ended) or channels
(for differential input)
The combinations for the channel selection are given below:

When ADLAR = 0

When ADLAR = 1
For single ended input:

MUX4:0 ADC Channel


00000 ADC0
00001 ADC1
00010 ADC2
00011 ADC3
00100 ADC4
00101 ADC5
00110 ADC6
00111 ADC7

For differential input:

MUX4:0 Dif(+) Diff(-) Gain


01001 ADC1 ADC0 10X
01011 ADC1 ADC0 200X
01101 ADC3 ADC2 10X
01111 ADC3 ADC2 200X
10000 ADC0 ADC1 1X
10010 ADC2 ADC1 1X
10011 ADC3 ADC1 1X
10100 ADC4 ADC1 1X
10101 ADC5 ADC1 1X
10110 ADC6 ADC1 1X
10111 ADC7 ADC1 1X
11000 ADC0 ADC2 1X
11001 ADC1 ADC2 1X
11011 ADC3 ADC2 1X
11100 ADC4 ADC2 1X
11101 ADC5 ADC2 1X
Note that some of the differential inputs have a gain of 10 and some have a gain 200 and others have 1.

1. Steps of programming
Step #1: Make the pin for the selected ADC channel as Input pin
Step #2: Enable the ADC
Step #3: Select the conversion speed
Step #4: Select voltage reference and ADC input channels
Step #5: Set the Start Conversion bit, ADSC
Step #6: Wait for some time and continuously monitor the ADIF bit.
Step #7: After ADIF bit is found to be high; ADCL and ADCH bytes are read
Step #8: If want to read the selected channel again go to step 5
6. An Experiment with the ADC
A variable voltage source will be connected to one of the channel of ADC. It is channel ADC0 (1st
channel). The analogue voltage will be converted into digital form by the ADC. The voltage read and
after converting into decimal will be displayed on LCD. Reference voltage will be connected to AVCC. The
prescaler is chosen as 128. So, for 16 MHz crystal, ADC frequency will be 16 MHz/128 = 125 kHz

7. The Proteus Design


The design in Proteus for the experiment is shown in the next page:

8. The code
The CodeVision code for the experiment is as follows:
#include <mega32.h>
#include <delay.h>
#include <stdlib.h>
#include <alcd.h>
interrupt [ADC_INT] void adc_isr(void)
{
float adc_data;
char disp[16];
// Read the AD conversion result
adc_data=ADCW/204.8;
ftoa(adc_data,2,disp);
lcd_gotoxy(0,0);
lcd_puts(disp);
}
void main(void)
{
ADMUX=0b01000000;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) |
(1<<ADPS0);
lcd_init(16);
#asm("sei")
while (1)
{
delay_us(10);
ADCSRA |= (1<<ADSC);
delay_ms(1000);
}
}
Note that Step size – Vref/210. In this experiment, Vref=AVCC so, step size = 5/1024=1/204.8

9. Temperature Sensor
The temperature sensors produce analogue voltage corresponding to temperature. We shall do an
experiment with a commonly used sensor called LM35. The features are as follows:

 Temperature Sensor IC => LM35


 Resolution of the sensor => 0.01 V per 10 C
 For 1500C => 1.5V
 Therefore let us set AREF at 1.5 V
 So the resolution of the ADC will be 1.5/1024=1.465 mV
 So the REFS1:0 bits should be set at 00.
 for Vref=AREF, REFS1:0=00
 for Vref=AVCC, REFS1:0=01
 for Vref=internal 2.56V, REFS1:0=11
10. The Design file with a temperature sensor

11. The code for the reading analogue voltage from a temperature sensor
#include <mega32.h>
#include <delay.h>
#include <stdlib.h>
#include <alcd.h>
interrupt [ADC_INT] void adc_isr(void)
{
float adc_data;
char disp[16];
// Read the AD conversion result
adc_data=ADCW*1.5/10.24;
ftoa(adc_data,2,disp);
lcd_gotoxy(0,0);
lcd_puts(disp);
}
void main(void)
{
ADMUX=0b00000000;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) |
(1<<ADPS0);
lcd_init(16);
#asm("sei")
while (1)
{
delay_us(10);
ADCSRA |= (1<<ADSC);
delay_ms(1000);
}
}

Note: There are two changes in the code


1. The Vref is AREF not AVCC. So REFS1:0=00 which is reflected in two MSB bits of ADCSRA register.
2. The conversion statement. AREF is set ar 1.5V. So, step size = 1.5/1025 and the conversion from
voltage to temperature in centigrade is 100. So the multiplying factor is 100*1.5/1024 =
1.5/10.24.
=========

You might also like