Advanced Embedded
Systems
ADC (analog-to-digital converter)
and
Sensor Interfacing
Lecture 0901
The AVR Microcontroller and Embedded Systems using Assembly and C
by
M. A. Mazidi, S. Naimi and S. Naimi
1
Parallel versus Serial ADC
Parallel ADC requires multiple data pins to provide output
while Serial ADC provides same output value with fewer
pins.
Parallel ADC are fast while Serial ADC takes more time to
provide converted data.
2
Analog Input Channels
Many data acquisition applications need more than one ADC
ADC chips provide 2, 4, 5, or even 16 channels on a single
chip using multiplexing
Allowing us to monitor multiple
Quantities
Due to multiple analog input
channels and a single digital output
create the need for start
conversion and end-of-
conversion signals.
3
ADC in the AVR
In recent years, an increasing number of microcontrollers have had
an on-chip ADC peripheral.
Atmega 32 ADC features
It is a 10-bit ADC
It has 8 Analog Input channels
Converted Data is placed in 2
registers (Total 10 bits)
ADCL (ADC Result Low)
ADCH (ADC Result High)
Vref can be configured in
different ways.
Conversion time is defined by
crystal frequency and ADPS0:2
bits
4
Hardware Considerations in AVR
AVCC pin provides supply for analog circuitry.
AVREF pin is used to supply reference voltage
GND is to ground the analog circuitry
Capacitors between AVREF and GND, and supply voltage and
AVCC make voltage supply stable, increase precision.
5
Software Considerations in AVR
In the AVR microcontroller, four major registers are
associated with the ADC.
ADCH register contains high data after conversion.
ADCL register contains low data after conversion.
ADCSRA (ADC Control and Status Register)
ADCMUX (ADC Multiplexer Selection Register)
6
Registers Required for ADC
System clock
ADPS
Prescaler
ADCSRA
3
clock
5
10
ADC ADCH ADCL
VIN
VREF
7
ADMUX Register
MUX4-MUX0:
Analog Channel and Gain Selection
8
ADMUX Register
ADLAR:
0: right adjust the result
1: left adjust the result
ADLAR = 0
ADCH
Right Justified ADCL
- - - - - - ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0
ADLAR = 1
Left Justified
ADCH ADCL
ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 - - - - - -
9
ADMUX Register
REFS1-REFS0: clock
Vref selection
10
ADC
VIN
VREF
10
ADCSRA (Status Register)
11
ADC Prescaler (ADPS bits)
PreScaler (ADPS) bits let us change
the clock frequency of ADC (Can Set
Conversion Time)
Frequency of ADC should not be more
than 200 KHz for maximum accuracy.
Conversion time is longer in the first
conversion.
An AVR is connected to the 8 MHz crystal
oscillator. Calculate the ADC frequency for
(a) ADPS2:0 = 001 (b) ADPS2:0 = 100
(c) ADPS2:0 = 111
12
Steps in programming ADC
1. Make the pin for the selected ADC channel an input pin.
2. Turn on the ADC module (ADEN in ADCSRA)
3. Select the conversion speed (ADPS2:0 in ADCSRA)
4. Select voltage reference and ADC input channels (ADMUX).
5. Activate the start conversion bit by writing a one to the
ADSC bit of ADCSRA.
6. Wait for the conversion to be completed by polling the
ADIF bit in the ADCSRA register.
7. After the ADIF bit has gone HIGH, read the ADCL and
ADCH registers to get the digital data output.
8. If you want to read the selected channel again, go back to
step 5.
9. If you want to select another Vref source or input channel,
go back to step 4.
13
Write C Program to get data from channel 0 (ADC0) of ADC and
display the result on Port B and Port D. Set Vref =2.56v
#include <avr/io.h>
int main (void)
{
DDRB = 0xFF;//make Port B an output
DDRD = 0xFF; //make Port D an output
DDRA = 0x00; //make Port A an input
ADCSRA= 0x87;//make ADC enable, select ck/128
ADMUX= 0xC0;//2.56V Vref, right-justified
while(1)
{
ADCSRA = ADCSRA | 0x40; ADCSRA
//start = ADCSRA
conversion | =(1<<ADSC);
ADSC 1
while((ADCSRA & 0x10)==0);
while((ADCSRA &
//wait for conversion to finish by ADIF
(1<<ADIF))==0);
ADCSRA = ADCSRA | 0x10;
PORTD = ADCL;//low byte to PORTD
PORTB = ADCH;//high byte to PORTB
}
}
14
Write Assembly code to get data from channel 0 (ADC0) of ADC
and display the result on Port B and Port D. Set Vref =2.56v
LDI R16, 0xFF
OUT DDRB, R16 ;make Port B an output
OUT DDRD, R16 ;make Port D an output
LDI R16, 0x00
OUT DDRA, R16 ;make Port A an input
LDI R16, 0x87
OUT ADCSRA, R16 ;make ADC enable, select ck/128
LDI R16, 0xC0
OUT ADMUX, R16 ;2.56V Vref, right-justified
READ_ADC:
SBI ADCSRA, ADSC IN R16, ADCL
Keep_Monitoring: OUT PORTD, R16
SBIS ADCSRA, ADIF
RJMP Keep_Monitoring IN R16, ADCH
SBI ADCSRA, ADIF OUT PORTB, R16
RJMP READ_ADC
15