4 AVR ADCs

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

Atmega16 ADC

AVR Lecture 4
Analog to Digital Converter
Some major characteristics of ADCs
◼ Resolution
❑ The ADC has n-bit resolution, where n can be
8,10,12,16 or even 24 bits
❑ Higher resolution ADCs have smaller step size,
where step size is the smallest change that can be
discerned by an ADC

2 / 74
Analog to Digital Converter
◼ Reference Voltage - Vref
❑ Vref is an input voltage used for reference voltage.
❑ The Reference voltage, along with the resolution of
the ADC defines the step size.
❑ For an n-bit ADC step size is given by
𝑉𝑟𝑒𝑓
Step size =
2𝑛
❑ For example if analog input voltage varies from 0 to
4 volts, Vref is connected to 4 volts
❑ If it is an 8 bit ADC than
step size = 4/256 = 15.62mV

3 / 74
Analog to Digital Converter
◼ Digital data output
❑ The digital output can be calculated as
𝑉𝑖𝑛
Dout =
𝑠𝑡𝑒𝑝 𝑠𝑖𝑧𝑒
𝑉𝑖𝑛
Dout = x2𝑛
𝑉𝑟𝑒𝑓
n= resolution of ADC (8,10,12,16,24 etc)
Dout= Digital Output in Decimal

4 / 74
Successive Approximation ADC
◼ If Vref =2.56 volt and 8-bit successive approximation
ADC is used, what will be the ADC output (Digital) if
input is 1 volt.

◼ Step size = 2.56/256 = 10mV


◼ D out = (1/step size) = 1V/10mV= 100
◼ D out 01100100

10 / 74
ATmega16 ADCs
◼ The ATmega16 features a 10-bit successive approximation
ADC(Successive Approximation ADC)
◼ The ADC converts an analog input voltage to a 10-bit
digital value through successive approximation
◼ The ADC is connected to an 8-channel Analog Multiplexer
which allows 8 single-ended voltage inputs constructed
from the pins of Port A
◼ The analog input channel are selected by writing to the
MUX bits in ADMUX
◼ The ADC contains a Sample and Hold circuit which
ensures that the input voltage to the ADC is held at a
constant level during conversion

13 / 74
Atmega16 ADC General Steps
◼ Starting/Powering up the ADC (Enabling)
◼ Selecting the triggering source
◼ Selecting the Input channel
◼ Selecting the ADC conversion speed i.e. ADC clock
◼ Selecting the reference voltage
◼ Enabling the interrupts if needed
◼ Reading the ADC conversion data

15 / 74
ATmega16 ADCs Operation
◼ The ADC is enabled by setting the ADC Enable bit,
ADEN in ADCSRA Voltage reference and input channel
selections will not go into effect until ADEN is set.
ADC Control and Status Register A – ADCSRA

◼ Bit 7 – ADEN: ADC Enable


Writing this bit to one enables the ADC. By writing it to
zero, the ADC is turned off. Turning the ADC off while a
conversion is in progress, will terminate this conversion.

16 / 74
Manual Triggering
◼A single conversion is started by writing a logical
one to the ADC Start Conversion bit, ADSC
ADC Control and Status Register A – ADCSRA

◼ Bit 6 – ADSC: ADC Start Conversion


❑ This bit stays high as long as the conversion is in progress
and will be cleared when the conversion is completed
❑ ADSC can also be used to determine if a conversion is in
progress. The ADSC bit will be read as one during a
conversion, independently of how the conversion was started

18 / 74
Auto Triggering Sources
◼ A conversion can be triggered automatically by
various sources
◼ Auto Triggering is enabled by setting the ADC Auto
Trigger Enable bit, ADATE in ADCSRA
ADC Control and Status Register A – ADCSRA

◼ Bit 5 – ADATE: ADC Auto Trigger Enable


❑ When this bit is written to one, Auto Triggering of the ADC
is enabled. The ADC will start a conversion on a positive
edge of the selected trigger signal. This bit is written zero
for manual conversion
19 / 74
Setting the Trigger Source
Special FunctionIO Register – SFIOR

◼ Bit 7:5 – ADTS2:0: ADC Auto Trigger Source


(ADTS2, ADTS1, ADTS0)
❑ If ADATE in ADCSRA is written to one, the value of these
bits selects which source will trigger an ADC conversion
❑ If ADATE is cleared, the ADTS2:0 settings will have no
effect
❑ A conversion will be triggered by the rising edge of the
selected interrupt flag

20 / 74
Setting the Trigger Source
◼ Triggering Sources

21 / 74
Setting the Trigger Source
◼ The trigger source is selected by setting the ADC
Trigger Select bits, ADTS in SFIOR
◼ The ADC will start a conversion on a positive edge
of the selected trigger signal.
◼ If another positive edge occurs on the trigger signal
during conversion, the edge will be ignored

22 / 74
ADC Free Running Mode
◼ In Free Running mode, the ADC constantly samples
and updates the ADC Data Register
◼ The first conversion must be started by writing a
logical one to the ADSC bit in ADCSRA

23 / 74
Prescaling and Conversion
◼ The ADC module contains a pre-scaler, which
generates an acceptable ADC clock frequency
◼ The pre-scaling is set by the ADPS bits in ADCSRA

ADC Control and Status Register A – ADCSRA


ADC Pre Scaler (ADPSx)

24 / 74
Prescaling and Conversion
◼ Bits 2:0 – ADPS2:0: ADC Pre-scaler Select Bits
❑ These bits determine the division factor between the XTAL
frequency and the input clock to the ADC

25 / 74
Prescaling and Conversion
◼ The successive approximation circuitry requires an
input clock frequency between 50 kHz and 200 kHz
to get maximum resolution

26 / 74
ADC Conversion Result
◼ The ADC generates a 10-bit result which is presented in
the ADC Data Registers ADCH and ADCL

30 / 74
ADC Conversion Result
◼ The ADC has 10 BIT resolution, therefore its result
is saved in TWO registers, ADCH and ADCL.
◼ ADCL must be read first, then ADCH. When ADCL
is read ADC’s access to data registers is blocked.
This ensures that the Data obtained belongs to the
same conversion
◼ Once ADCL is read, and if the ADC completes a
conversion before ADCH is read, the registers are
not updated, hence the data from that conversion is
lost.
◼ When ADCH is read, ADC access to the ADCH and
ADCL Registers is re-enabled

31 / 74
ADC Conversion Result
◼ The ADC generates a 10-bit result which is presented in
the ADC Data Registers ADCH and ADCL
◼ By default, the result is presented right adjusted

32 / 74
ADC Conversion Result
◼ The ADC Data Register – ADCL and ADCH

33 / 74
ADC Conversion Result
◼ The ADC generates a 10-bit result which is presented in
the ADC Data Registers ADCH and ADCL
◼ By default, the result is presented right adjusted

◼ It can optionally be presented left adjusted by setting the


ADLAR bit in ADMUX
ADC Multiplexer Selection Register – ADMUX

34 / 74
ADC Conversion Result
ADC 8-bit output data
◼ If the result is left adjusted and no more
than 8-bit precision is required, it is
sufficient to read ADCH

36 / 74
ADC Voltage Reference
◼ADC reference voltage is selected by the bits in
ADMUX register
ADC Multiplexer Selection Register – ADMUX

◼ Bit 7:6 – REFS1:0: Reference Selection Bits


❑ These bits select the voltage reference for the ADC
❑ If these bits are changed during a conversion, the change
will not go in effect until this conversion is complete

37 / 74
Summary of Pin Description

External interrupt2 ADC Inputs

PortA
PortB
PWM Channel
timer0
Pins Used for
Programming
Ref voltage for ADC
5V Ground
Voltage Supply for ADC

External Crystal
PortC

External interrupt0
PortD

External interrupt1

PWM channels
timer1 PWM Channel timer2

38 / 74
ADC Voltage Reference
◼ AVCC is the supply voltage pin for A/D convertor. It should
be externally connected to VCC, even if the ADC is not used
◼ AREF is the ref voltage pin for ADC

39 / 74
ADC Voltage Reference
◼ Voltage Reference Selections for ADC
REFS1 REFS0 Voltage Reference Selection
0 0 AVREF
0 1 AVCC
1 0 Reserved
1 1 Internal 2.56 V

40 / 74
ADC Voltage Reference
◼ The reference voltage for the ADC (VREF) indicates
the conversion range for the ADC
◼ VREF can be selected as either
❑ AVCC
❑ Internal 2.56V reference
❑ External AREF pin

41 / 74
Channel Selection
◼ Input channel for ADC conversion is selected
through the MUXn bits in the ADMUX register

INPUT MUX4 MUX3 MUX2 MUX1 MUX0


ADC0 0 0 0 0 0
ADC1 0 0 0 0 1
ADC2 0 0 0 1 0
ADC3 0 0 0 1 1
ADC4 0 0 1 0 0
ADC5 0 0 1 0 1
ADC6 0 0 1 1 0
ADC7 0 0 1 1 1

44 / 74
ADC Interrupt
◼ ADC can generate an interrupt every time a
conversion is completed
◼ ADC interrupt is controlled by following bit

ADC Control and Status Register A – ADCSRA

◼ Bit 3 – ADIE: ADC Interrupt Enable


❑ When this bit is written to one and the I-bit in SREG is set,
the ADC Conversion Complete Interrupt is activated

46 / 74
ADC Interrupt
◼ Bit 4 – ADIF: ADC Interrupt Flag
❑ This bit is set when an ADC conversion completes and the
Data Registers are updated
❑ ADIF is cleared when executing the corresponding interrupt
handling vector
❑ Alternatively, ADIF is cleared by writing a logical one to the
flag

47 / 74
Steps in programming ADC using polling
1. Make pin for the selected ADC channel as input pin
2. Turn on the ADC module of AVR by setting ADEN
bit in ADCSRA register
3. Select the conversion speed by setting values of
bits ADPS2:0 in ADCSRA register
4. Select voltage reference by setting bits REFS0 and
REFS1 in ADMUX register, and select the input
channel by setting bit MUX4:0 in ADMUX
5. Activate the start conversion bit by writing one to
ADSC bit of ADCSRA
6. Wait for the conversion to be completed by polling
ADIF bit in ADCSRA register

50 / 74
Steps in programming ADC using polling
7. After ADIF bit has gone high, Read 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.

51 / 74
Example
◼ Use the ADC with AVCC as the VREF, make use of
single ended conversions to check the value of an
analog voltage connected with ADC0 and display its
digital value on port B. (Use INTERRUPT and manual
conversion)
If we use internal oscillator at 8MHz than set the
prescaler such that the ADC clock has the frequency of
125kHz. [Use Channel Zero]

53 / 74
Solution Code
#include<avr/io.h>
#include<avr/interrupt.h>

unsigned char adc_data=0;


void main()
{
SREG|=0b10000000; //enabling Global Interrupt
ADCSRA= ; //Enabling ADCs and setting Prescalar
SFIOR=;
ADMUX=; //Vref=AVCC, data is left shift, Channel 0 is selected

DDRB=; //configuring port B as output


ADCSRA=; //starting conversion - Manual
}

54 / 74
Solution (Setting Value of ADSCRA)
◼ ADCSRA

❑ We enable the ADC by setting ADEN bit


❑ We enable the ADC interrupt by setting ADIE bit
❑ ADATE bit is left zero because we are not using
any auto triggering source
◼ Hence
ADEN=1 and ADIE =1

55 / 74
Solution (Setting Value of ADSCRA)
◼ Now setting prescalar, 8MHz/125kHz=64

◼ Hence from above table


ADPS2=1, ADPS1=1, ADPS0=0
◼ So the value of ADCSRA is
❑ ADCSRA=0b10001110
56/57
56 / 74
Solution (Setting Value of SFIOR)
◼ Now the Register SFIOR

◼ Since we are not using auto triggering mode


hence
ADTS2=0, ADTS1=0, ADTS0=0;
◼ Hence
SFIOR&=0b00001111

58 / 74
Solution (Setting Value of ADMUX)
◼ Now we select reference voltage by setting bits of
register ADMUX

◼ For VREF=AVCC
REFS1=0, REFS0=1

60 / 74
Solution (Setting Value of ADMUX)
◼ As we are interested in 8-bit result only so we
set ADLAR=1 so that result is left adjusted in
ADCH and ADCL register
ADLAR=1
◼ Mux[0] = 000
◼ Hence
ADMUX|=0b01100000

61 / 74
Solution Code
#include<avr/io.h>
#include<avr/interrupt.h>

unsigned char adc_data=0;


void main()
{
SREG|=0b10000000; //enabling Global Interrupt
ADCSRA=0b10001110; //Enabling ADCs and setting Prescalar
SFIOR&=0b00001111;
ADMUX|=0b01100000; //Vref=AVCC, data is left shift, Channel 0 is selected

DDRB=0xFF; //configuring port B as output


ADCSRA|= 0b01000000; //starting conversion - Manual
while(1)
{
PORTB=adc_data;
}
} // ISR
ISR(ADC_vect)
{
adc_data=ADCH;
ADCSRA|=0b01000000; //starting next conversion
}
62 / 74
Example
Use the ADC with AVCC as the VREF, make use of single
ended conversions to check the value of 3 digital voltages
connected with ADC0, ADC1 and ADC2, and display their
analog values on port B, C and D respectively
If we use internal oscillator at 8MHz than set the pre-scaler
such that the ADC clock has the frequency of 125kHz

63 / 74
Example
◼ Interrupt
◼ Polling

64 / 74
Solution Code (using interrupt)
#include<avr/io.h>
#include<avr/interrupt.h>

unsigned char channel=0;


unsigned char adc_data[3];
void main()
{
SREG|=0b10000000; //enabling Global Interrupt
ADCSRA=0b10001110; //Enabling ADCs and setting Prescalar
SFIOR&=0b00001111;
ADMUX|=0b01100000; //Vref=AVCC and data is left shift

DDRB=0xFF; //configuring port B as output


DDRC=0XFF; //configuring port C as output
DDRD=0XFF; //configuring port D as output
ADCSRA|= 0b01000000; //starting conversion
// while loop and ISR
65 / 74
Solution Code (using interrupt)
while(1)
{
PORTB=adc_data[0];
PORTC=adc_data[1];
PORTD=adc_data[2];
}
}
ISR(ADC_vect)
{
adc_data[channel]=ADCH;
channel++;
if(channel==3)
{ channel=0;
}
ADMUX&=0xE0; //making mux selection bits zero;1110 0000
ADMUX|=channel; //selecting desired channel
ADCSRA|=0x40; //starting adc conversion
}
66 / 74
Using polling (Only) by checking Int Flag ADIF
void main()
{
SREG|=0b10000000; //enabling Global Interrupt
ADCSRA=0b10000110; //Enabling ADCs and setting Prescalar
SFIOR&=0b00001111;
ADMUX|=0b01100000; //Vref=AVCC and data is left shift

DDRB=0xFF; //configuring port B as output


DDRC=0XFF; //configuring port C as output
DDRD=0XFF; //configuring port D as output

while(1)
{ ADC_Calc();
}
}

67 / 74
Using polling (Only) by checking Int Flag ADIF
void ADC_Calc()
{
ADMUX=0x60;//selecting channel 0
ADCSRA|=0x40;// starting conversion
while(!(ADCSRA&0x10)); //waiting for Interrupt flag ADIF to get set
PORTB=ADCH;

ADMUX=0x61;//selecting channel 1
ADCSRA|=0x40;// starting conversion
while(!(ADCSRA&0x10)); //waiting for Interrupt flag to get set
PORTC=ADCH;

ADMUX=0x62;//selecting channel 2
ADCSRA|=0x40;// starting conversion
while(!(ADCSRA&0x10)); //waiting for Interrupt flag to get set
PORTD=ADCH;
}

68 / 74
Using polling (Only) by checking ADSC Flag
void ADC_Calc()
{
ADMUX=0x60;//selecting channel 0
ADCSRA|=0x40;// starting conversion
while((ADCSRA&0x40));//waiting for the start conversion bit ADSC to get clear

PORTB=ADCH;

ADMUX=0x61;//selecting channel 1
ADCSRA|=0x40;// starting conversion
While((ADCSRA&0x40)); //waiting for the start conversion bit to get clear
PORTC=ADCH;

ADMUX=0x62;//selecting channel 2
ADCSRA|=0x40;// starting conversion
while((ADCSRA&0x40)); //waiting for the start conversion bit to get clear
PORTD=ADCH;
}
69 / 74

You might also like