School of Electrical, Computer and Telecommunications Engineering
University of Wollongong
Australia
ECTE333 – Tutorial 5
Analogue to Digital Converter
2
Lam Phung ECTE333 Tutorial 5
ECTE333’s schedule
Lecture (2h) Tutorial (1h) Lab (2h)
L1:Introduction to AVR Microcontrollers
L2: C Programming, Digital IO Tutorial 1 Lab 1
L3: Serial Communication
Tutorial 2 Lab 2
L4: Interrupts, Timers
Tutorial 3 Lab 3
L5: Pulse Width Modulators
Tutorial 4 Lab 4
L6: Analogue-to-Digital Converters
Tutorial 5 Lab 5
L7: Microcontroller Applications
Lab 6
3
Lam Phung ECTE333 Tutorial 5
Tutorial 5’s overview
1. ADC in ATmega16: Quiz
2. ADC ─ Polling-driven processing with multiple inputs
3. ADC ─ Interrupt-driven processing
4. ADC ─ Auto-trigger for regular sampling
5. A-to-D conversion formula
4
Lam Phung ECTE333 Tutorial 5
Tutorial 5’s overview
Exam Appendix: Page 5
5
Lam Phung ECTE333 Tutorial 5
Tutorial 5’s overview
Exam Appendix: Page 5
6
Lam Phung ECTE333 Tutorial 5
Tutorial 5’s overview
Exam Appendix: Page 6
ADC Input Source
7
Lam Phung ECTE333 Tutorial 5
Q1 ─ ADC in ATmega16: Quiz
a) How many analogue input channels does the ATmega16 have?
8 channels: ADC7, ADC6, …, ADC0.
b) On what IO pin can we find ADC channel 0?
Port A pin 0.
c) What is the step size of the ADC for reference voltage of 5V?
In ATmega16, 𝒏 = 10 bits.
For Vref = 5V, step size = 4.88mV.
𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 =
𝑽𝒓𝒆𝒇
𝟐𝒏
8
Lam Phung ECTE333 Tutorial 5
Q1 ─ ADC in ATmega16: Quiz
d) What is the error range of the ADC for Vref of 5V?
e) Using an ADC prescaler of 16 and an internal CPU clock of 1MHz, how long
does each ADC operation take?
Each ADC operation takes 13 ADC clock cycles.
For ADC prescaler of 16 and CPU clock of 1MHz, one ADC clock cycle is 16μs.
Hence, each ADC operation takes 16×13 = 208μs.
For ATmega16, error range = 2 × step size.
For Vref = 5V, step size = 4.88mV, error range = 9.76mV.
9
Lam Phung ECTE333 Tutorial 5
Q1 ─ ADC in ATmega16: Quiz
f) How to enable the ADC unit?
Set flag ADEN to 1 (register ADCSRA).
g) How to force the ADC unit to start a conversion operation?
Set flag ADSC to 1 (register ADCSRA).
h) How do we know that an ADC operation has been completed?
When flag ADSC becomes 0 (after starting an ADC operation).
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSRA register
10
Lam Phung ECTE333 Tutorial 5
Q1 ─ ADC in ATmega16: Quiz
i) How can we store the entire 10-bit digital output in a C integer variable?
d9 d8 d7 d6 d5 d4 d3 d2
ADCH
When bit ADLAR = 1 (Left Aligned)
d1 d0 # # # # # #
ADCL
𝒅 = 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎
= 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐 × 𝟒 + 𝒅𝟏𝒅𝟎
Math
unsigned int d, high, low;
low = (unsigned int) ADCL; // {d1,d0, 0, 0, 0 , 0, 0, 0}
high = (unsigned int) ADCH; // {d9,d8,d7,d6,d5,d4,d3,d2}
d = (high << 2) + ((low & 0b11000000) >> 6);
𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐 × 𝟒 𝒅𝟏𝒅𝟎
C code
11
Lam Phung ECTE333 Tutorial 5
Q1 ─ ADC in ATmega16: Quiz
i) How to store the entire 10-bit digital output in a C integer variable?
# # # # # # d9 d8
ADCH
When bit ADLAR = 0 (Right Aligned)
d7 d6 d5 d4 d3 d2 d1 d0
ADCL
𝒅 = 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎
= 𝒅𝟗𝒅𝟖 × 𝟐𝟓𝟔 + 𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎
Math
unsigned int d, high, low;
low = (unsigned int) ADCL; // {d7,d6,d5,d4,d3,d2,d1,d0}
high = (unsigned int) ADCH; // {0, 0, 0,0, 0, 0,d9,d8}
d = ((high & 0b00000011) << 8) + low;
𝒅𝟗𝒅𝟖 × 𝟐𝟓𝟔 𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎
C code
d = ADCW;
Short-cut (only for right aligned)
#define ADCW _SFR_IO16(0x04)
12
Lam Phung ECTE333 Tutorial 5
Q2/Q3/Q4 ─ Three Approaches for ADC
Approach Start ADC Read results Example
1. Polling-driven
Manually
(set ADSC flag = 1)
Manually
(wait until ADSC = 0)
Q2
2. Interrupt-driven
Manually
(set ADSC flag = 1)
Automatically
(on ADC interrupt)
Q3
3. Auto-trigger
Automatically
(predefined events)
Automatically
(on ADC interrupt)
Q4
13
Lam Phung ECTE333 Tutorial 5
Q2 ─ ADC polling-driven processing
Write C program to digitise joystick x, y signals and turn on LED if the joystick
is too far from the neutral position.
Connect the x signal to pin ADC1.
Connect the y signal to pin ADC2.
Connect supply voltages to the joystick.
Start conversion on channel ADC1. Read digital output d1.
Start conversion on channel ADC2. Read digital output d2.
Turn on LED if: (𝒅𝟏 − 𝟓𝟎𝟎)𝟐+(𝒅𝟐 − 𝟓𝟎𝟎)𝟐≥ 𝟓𝟎
14
Lam Phung ECTE333 Tutorial 5
Q2 ─ ADC polling-driven processing
#include<avr/io.h>
int main (void){
uint32_t low, high, d1, d2;
DDRB = 0xFF; // port B for output
// Configure the ADC module of the ATmega16
ADCSRA = 0b10000111; // ADEN = 1: enable ADC, ADSC = 0: don't start conversion yet
// ADATE = 0: disable auto trigger, ADIE = 0: disable ADC interrupt
// ASPS2:0 = 001: prescaler = 2
while(1){
// Digitise signal joystick x
ADMUX = 0b01000001; // REFS1:0 = 01 -> AVCC as reference, ADLAR = 0 -> Right adjust
// MUX4:0 = 00001 -> ADC1 as input
ADCSRA |= (1 << ADSC); // Start conversion by setting flag ADSC
while (ADCSRA & (1 << ADSC)){;} // Wait until conversion is completed
// Read digital output d1
low = (uint32_t) ADCL; high = (uint32_t) ADCH & 0b00000011;
d1 = (high << 8) + low;
// Digitise signal joystick y
ADMUX = 0b01000010; // MUX4:0 = 00010 -> ADC2 as input
ADCSRA |= (1 << ADSC); // Start conversion by setting flag ADSC
while (ADCSRA & (1 << ADSC)){;} // Wait until conversion is completed
// Read digital output d2
low = (uint32_t) ADCL; high = (uint32_t) ADCH & 0b00000011;
d2 = (high << 8) + low;
if ((d1 -500)*(d1 -500) + (d2 - 500)*(d2 -500) >= 2500)
PORTB &= 0b11111110; // Turn ON LED (Note LED is active low: ON = 0, OFF = 1)
else
PORTB |= 0b00000001;
}
return 0;
}
ADEN
1
ADSC
0
ADATE
0
ADIF
0
ADIE
0
ADPS2
0
ADPS1
0
ADPS0
1
ADCSRA
REFS1
0
REFS0
1
ADLAR
0
MUX4
0
MUX3
0
MUX2
0
MUX1
0
MUX0
0/1
ADMUX
15
Lam Phung ECTE333 Tutorial 5
Q3 ─ ADC interrupt-driven processing
Write a C interrupt-driven program for ADC. The program should repeatedly use
the ADC interrupt to display the low 8 bits of the 10-bit output on PORTB.
Step 1: Configure the ADC
 What is the ADC source? ADC0
 What reference voltage to use? AVCC = 5V
 Align left or right? Right (low 8-bit in ADCL)
 Enable or disable ADC auto-trigger? Disable
 Enable or disable ADC interrupt? Enable
 What is the prescaler? 2 (fastest conversion)
Step 2: Start an ADC operation.
Step 3: In ISR, read and display ADC result.
16
Lam Phung ECTE333 Tutorial 5
Q3 ─ ADC interrupt-driven processing
#include<avr/io.h>
#include<avr/interrupt.h>
volatile unsigned char result;
ISR(ADC_vect){
result = ADCL; // Read the low 8 bits, and store in variable ‘result’
}
int main (void){
DDRB = 0xFF; // set port B for output
// Configure the ADC module of the ATmega16
ADMUX = 0b01000000; // REFS1:0 = 01 -> AVCC as reference,
// ADLAR = 0 -> Right adjust
// MUX4:0 = 00000 -> ADC0 as input
ADCSRA = 0b10001001; // ADEN = 1: enable ADC,
// ADSC = 0: don't start conversion yet
// ADATE = 0: disable auto trigger,
// ADIE = 1: enable ADC interrupt
// ASPS2:0 = 001: prescaler = 2
sei(); // enable interrupt system globally
while(1){ // main loop
ADCSRA = ADCSRA | 0b01000000; // start a conversion
PORTB = ~result; // display on port B (LED ON = 0, OFF = 1)
}
return 0;
}
ADEN
1
ADSC
0
ADATE
0
ADIF
0
ADIE
1
ADPS2
0
ADPS1
0
ADPS0
1
ADCSRA
REFS1
0
REFS0
1
ADLAR
0
MUX4
0
MUX3
0
MUX2
0
MUX1
0
MUX0
0
ADMUX
17
Lam Phung ECTE333 Tutorial 5
ADTS2 ADTS1 ADTS0 Trigger Source
0 0 0 Free Running mode
0 0 1 Analog Comparator
0 1 0 External Interrupt Request
0 1 1 Timer/Counter0 Compare Match
1 0 0 Timer/Counter0 Overflow
1 0 1 Timer/Counter1 Compare Match B
1 1 0 Timer/Counter1 Overflow
1 1 1 Timer/Counter1 Capture Event
Q4 ─ ADC auto-trigger for regular sampling
Develop an approach that uses the ADC auto-trigger mode to start a conversion
every one second. The top 8 bits of result are to be displayed on PORTB.
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSRA register
ADC Auto Trigger Enable: 1 to enable auto-triggering of ADC
ADTS2 ADTS1 ADTS0 - ACME PUD PSR2 PSR10
Table 6.4:
ADC Auto Trigger Source
ADC Auto
Trigger Source
bits
SFIOR register
18
Lam Phung ECTE333 Tutorial 5
Q4 ─ ADC Auto-trigger for regular sampling
Connect analogue input to an ADC pin, e.g. ADC1.
Configure the ADC unit:
 ADC1 as input
 AVCC as reference voltage,
 ADC prescaler of 2,
 left-adjust output,
 enable auto-trigger on Timer 1 Compare Match B,
 enable ADC interrupt.
ADMUX = 0b01110001;
ADCSRA = 0b10101001;
SFIOR = 0b10100000;
Configure Timer 1 to trigger Compare Match B every 1s:
 internal clock of 1MHz.
 timer prescaler of 256.
 Fast PWM mode 1111:
TOP = OCR1A, Compare Match on OCR1B.
 Disable timer interrupt
 Disable changing output compare pins
TCCR1A = 0b00000011;
TCCR1B = 0b00011100;
OCR1A = 3096;
OCR1B = 3096;
(See Lecture 5/Tutorial 4)
19
Lam Phung ECTE333 Tutorial 5
Q4 ─ ADC Auto-trigger for regular sampling
#include<avr/io.h>
#include<avr/interrupt.h>
volatile unsigned char result;
ISR(ADC_vect){
result = ADCH; // take top 8-bits of output
}
int main (void){
DDRB = 0xFF; // set port B for output
// Configure ADC
ADMUX = 0b01100001; // channel ADC1, Vref = 5V, left adjust
ADCSRA = 0b10101001; // ADEN = 1: enable ADC,
// ADSC = 0: don't start conversion yet
// ADATE = 1: enable auto trigger
// ADIE = 1: enable ADC interrupt
// ASPS2:0 = 001: ADC prescaler = 2
SFIOR = 0b10100000; // ADC auto-trigger on Compare Match Channel B
// Configure Timer 1
TCCR1A = 0b00000011; // Timer mode bits WGM11-10= 11
TCCR1B = 0b00011100; // Timer mode bits WGM13-12= 11
// Timer prescaler bits = 100 (x256)
OCR1A = 3906; // Top limit 3906 x 256us = 1 second
OCR1B = 3906; // When to trigger compare match B
TIMSK = 0; // Disable all timer interrupts
sei();
while(1){
PORTB = ~result; // display ADC output
}
return 0;
}
ADEN
1
ADSC
0
ADATE
1
ADIF
0
ADIE
1
ADPS2
0
ADPS1
0
ADPS0
1
ADCSRA
REFS1
0
REFS0
1
ADLAR
1
MUX4
0
MUX3
0
MUX2
0
MUX1
0
MUX0
1
ADMUX
20
Lam Phung ECTE333 Tutorial 5
Q5 ─ A-to-D Conversion Formula
a) What is resolution or step size of the ADC?
∆𝑽 = ∆𝑻 × 𝒈𝒂𝒊𝒏
= 𝟎. 𝟎𝟏 𝒐𝑪 × 𝟎. 𝟏
𝑽
𝒐𝑪
= 𝟎. 𝟎𝟎𝟏𝑽
𝑻
Temperature
Transducer 𝑽 ADC 𝒅 =
𝑽 − 𝑽𝒎𝒊𝒏
𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆
𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏
- Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC
- Temperature transducer gain: gain = 0.1V/oC
- Temperature change to detect: ∆𝑻 = 0.01oC
21
Lam Phung ECTE333 Tutorial 5
Q5 ─ A-to-D Conversion Formula
𝑻
Temperature
Transducer 𝑽 ADC 𝒅 =
𝑽 − 𝑽𝒎𝒊𝒏
𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆
𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏
- Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC
- Temperature transducer gain: gain = 0.1V/oC
- Temperature change to detect: ∆𝑻 = 0.01oC
b) What is the number of bits required for the ADC?
 We assume that 𝑽𝒎𝒊𝒏 = 𝟎 when 𝑻𝒎𝒊𝒏 = −𝟓𝟎𝒐𝑪.
 We have:
𝑽𝒎𝒂𝒙 − 𝑽𝒎𝒊𝒏 = 𝑻𝒎𝒂𝒙– 𝑻𝒎𝒊𝒏 × 𝒈𝒂𝒊𝒏
= {𝟏𝟓𝟎 – (– 𝟓𝟎)} × 𝟎. 𝟏 = 𝟐𝟎𝑽
 Hence, the number of bits is
𝒏 = 𝒍𝒐𝒈𝟐
𝑽𝒎𝒂𝒙 − 𝑽𝒎𝒊𝒏
𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆
+ 𝟏 = 𝟏𝟒. 𝟐𝟗 → 𝒏 = 𝟏𝟓
22
Lam Phung ECTE333 Tutorial 5
Q5 ─ A-to-D Conversion Formula
𝑻
Temperature
Transducer 𝑽 ADC 𝒅 =
𝑽 − 𝑽𝒎𝒊𝒏
𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆
𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏
- Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC
- Temperature transducer gain: gain = 0.1V/oC
- Temperature change to detect: ∆𝑻 = 0.01oC
c) What is full scale voltage?
d) What is the reference voltage of the converter?
𝑽𝑭𝑺𝑪 = 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 × 𝟐𝒏
− 𝟏 = 𝟑𝟐. 𝟕𝟔𝟕 𝑽
𝑽𝒓𝒆𝒇 = 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 × 𝟐𝒏
= 𝟑𝟐. 𝟕𝟔𝟖 𝑽
23
Lam Phung ECTE333 Tutorial 5
Q5 ─ A-to-D Conversion Formula
𝑻
Temperature
Transducer 𝑽 ADC 𝒅 =
𝑽 − 𝑽𝒎𝒊𝒏
𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆
𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏
- Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC
- Temperature transducer gain: gain = 0.1V/oC
- Temperature change to detect: ∆𝑻 = 0.01oC
e) What is the actual input temperature when the digital output 𝒅 = 𝟐𝟎?
 Input voltage of the ADC: 𝑽𝒊𝒏 = 𝑽𝒎𝒊𝒏 + 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 × 𝒅 = 𝟎 + 𝟎. 𝟎𝟎𝟏 × 𝟐𝟎 = 𝟎. 𝟎𝟐 V
 The actual range: 𝑽𝒊𝒏 = 𝟎. 𝟎𝟐 ± 𝟎. 𝟎𝟎𝟎𝟓 V
 Note that: 𝑽𝒊𝒏 = 𝑻𝒊𝒏 − 𝑻𝒎𝒊𝒏 × 𝒈𝒂𝒊𝒏 = 𝑻𝒊𝒏 + 𝟓𝟎 × 𝟎. 𝟏
→ 𝑻𝒊𝒏=
𝑽𝒊𝒏
𝟎.𝟏
− 𝟓𝟎
 Therefore, the range of input temperature 𝑻𝒊𝒏: [-49.805oC, -49.795oC].
24
Lam Phung ECTE333 Tutorial 5
Extra practice for Lecture/Lab/Tutorial 5
Write and test a C program that uses the auto-trigger mode of the ADC unit in
ATmega16 to start a conversion operation every 500 millisecond.
The analogue input is to be connected to pin A.0.
The top-8 bits of conversion result are to be displayed on PORTB.
25
Lam Phung ECTE333 Tutorial 5
Extra practice for Lecture/Lab/Tutorial 5
Solve Problem Q4 using ADC Auto Trigger and Timer 1 Overflow.

ECTE333-Tutorial-05-Solutionfsdfsfsfa.pdf

  • 1.
    School of Electrical,Computer and Telecommunications Engineering University of Wollongong Australia ECTE333 – Tutorial 5 Analogue to Digital Converter
  • 2.
    2 Lam Phung ECTE333Tutorial 5 ECTE333’s schedule Lecture (2h) Tutorial (1h) Lab (2h) L1:Introduction to AVR Microcontrollers L2: C Programming, Digital IO Tutorial 1 Lab 1 L3: Serial Communication Tutorial 2 Lab 2 L4: Interrupts, Timers Tutorial 3 Lab 3 L5: Pulse Width Modulators Tutorial 4 Lab 4 L6: Analogue-to-Digital Converters Tutorial 5 Lab 5 L7: Microcontroller Applications Lab 6
  • 3.
    3 Lam Phung ECTE333Tutorial 5 Tutorial 5’s overview 1. ADC in ATmega16: Quiz 2. ADC ─ Polling-driven processing with multiple inputs 3. ADC ─ Interrupt-driven processing 4. ADC ─ Auto-trigger for regular sampling 5. A-to-D conversion formula
  • 4.
    4 Lam Phung ECTE333Tutorial 5 Tutorial 5’s overview Exam Appendix: Page 5
  • 5.
    5 Lam Phung ECTE333Tutorial 5 Tutorial 5’s overview Exam Appendix: Page 5
  • 6.
    6 Lam Phung ECTE333Tutorial 5 Tutorial 5’s overview Exam Appendix: Page 6 ADC Input Source
  • 7.
    7 Lam Phung ECTE333Tutorial 5 Q1 ─ ADC in ATmega16: Quiz a) How many analogue input channels does the ATmega16 have? 8 channels: ADC7, ADC6, …, ADC0. b) On what IO pin can we find ADC channel 0? Port A pin 0. c) What is the step size of the ADC for reference voltage of 5V? In ATmega16, 𝒏 = 10 bits. For Vref = 5V, step size = 4.88mV. 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 = 𝑽𝒓𝒆𝒇 𝟐𝒏
  • 8.
    8 Lam Phung ECTE333Tutorial 5 Q1 ─ ADC in ATmega16: Quiz d) What is the error range of the ADC for Vref of 5V? e) Using an ADC prescaler of 16 and an internal CPU clock of 1MHz, how long does each ADC operation take? Each ADC operation takes 13 ADC clock cycles. For ADC prescaler of 16 and CPU clock of 1MHz, one ADC clock cycle is 16μs. Hence, each ADC operation takes 16×13 = 208μs. For ATmega16, error range = 2 × step size. For Vref = 5V, step size = 4.88mV, error range = 9.76mV.
  • 9.
    9 Lam Phung ECTE333Tutorial 5 Q1 ─ ADC in ATmega16: Quiz f) How to enable the ADC unit? Set flag ADEN to 1 (register ADCSRA). g) How to force the ADC unit to start a conversion operation? Set flag ADSC to 1 (register ADCSRA). h) How do we know that an ADC operation has been completed? When flag ADSC becomes 0 (after starting an ADC operation). ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSRA register
  • 10.
    10 Lam Phung ECTE333Tutorial 5 Q1 ─ ADC in ATmega16: Quiz i) How can we store the entire 10-bit digital output in a C integer variable? d9 d8 d7 d6 d5 d4 d3 d2 ADCH When bit ADLAR = 1 (Left Aligned) d1 d0 # # # # # # ADCL 𝒅 = 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎 = 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐 × 𝟒 + 𝒅𝟏𝒅𝟎 Math unsigned int d, high, low; low = (unsigned int) ADCL; // {d1,d0, 0, 0, 0 , 0, 0, 0} high = (unsigned int) ADCH; // {d9,d8,d7,d6,d5,d4,d3,d2} d = (high << 2) + ((low & 0b11000000) >> 6); 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐 × 𝟒 𝒅𝟏𝒅𝟎 C code
  • 11.
    11 Lam Phung ECTE333Tutorial 5 Q1 ─ ADC in ATmega16: Quiz i) How to store the entire 10-bit digital output in a C integer variable? # # # # # # d9 d8 ADCH When bit ADLAR = 0 (Right Aligned) d7 d6 d5 d4 d3 d2 d1 d0 ADCL 𝒅 = 𝒅𝟗𝒅𝟖𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎 = 𝒅𝟗𝒅𝟖 × 𝟐𝟓𝟔 + 𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎 Math unsigned int d, high, low; low = (unsigned int) ADCL; // {d7,d6,d5,d4,d3,d2,d1,d0} high = (unsigned int) ADCH; // {0, 0, 0,0, 0, 0,d9,d8} d = ((high & 0b00000011) << 8) + low; 𝒅𝟗𝒅𝟖 × 𝟐𝟓𝟔 𝒅𝟕𝒅𝟔𝒅𝟓𝒅𝟒𝒅𝟑𝒅𝟐𝒅𝟏𝒅𝟎 C code d = ADCW; Short-cut (only for right aligned) #define ADCW _SFR_IO16(0x04)
  • 12.
    12 Lam Phung ECTE333Tutorial 5 Q2/Q3/Q4 ─ Three Approaches for ADC Approach Start ADC Read results Example 1. Polling-driven Manually (set ADSC flag = 1) Manually (wait until ADSC = 0) Q2 2. Interrupt-driven Manually (set ADSC flag = 1) Automatically (on ADC interrupt) Q3 3. Auto-trigger Automatically (predefined events) Automatically (on ADC interrupt) Q4
  • 13.
    13 Lam Phung ECTE333Tutorial 5 Q2 ─ ADC polling-driven processing Write C program to digitise joystick x, y signals and turn on LED if the joystick is too far from the neutral position. Connect the x signal to pin ADC1. Connect the y signal to pin ADC2. Connect supply voltages to the joystick. Start conversion on channel ADC1. Read digital output d1. Start conversion on channel ADC2. Read digital output d2. Turn on LED if: (𝒅𝟏 − 𝟓𝟎𝟎)𝟐+(𝒅𝟐 − 𝟓𝟎𝟎)𝟐≥ 𝟓𝟎
  • 14.
    14 Lam Phung ECTE333Tutorial 5 Q2 ─ ADC polling-driven processing #include<avr/io.h> int main (void){ uint32_t low, high, d1, d2; DDRB = 0xFF; // port B for output // Configure the ADC module of the ATmega16 ADCSRA = 0b10000111; // ADEN = 1: enable ADC, ADSC = 0: don't start conversion yet // ADATE = 0: disable auto trigger, ADIE = 0: disable ADC interrupt // ASPS2:0 = 001: prescaler = 2 while(1){ // Digitise signal joystick x ADMUX = 0b01000001; // REFS1:0 = 01 -> AVCC as reference, ADLAR = 0 -> Right adjust // MUX4:0 = 00001 -> ADC1 as input ADCSRA |= (1 << ADSC); // Start conversion by setting flag ADSC while (ADCSRA & (1 << ADSC)){;} // Wait until conversion is completed // Read digital output d1 low = (uint32_t) ADCL; high = (uint32_t) ADCH & 0b00000011; d1 = (high << 8) + low; // Digitise signal joystick y ADMUX = 0b01000010; // MUX4:0 = 00010 -> ADC2 as input ADCSRA |= (1 << ADSC); // Start conversion by setting flag ADSC while (ADCSRA & (1 << ADSC)){;} // Wait until conversion is completed // Read digital output d2 low = (uint32_t) ADCL; high = (uint32_t) ADCH & 0b00000011; d2 = (high << 8) + low; if ((d1 -500)*(d1 -500) + (d2 - 500)*(d2 -500) >= 2500) PORTB &= 0b11111110; // Turn ON LED (Note LED is active low: ON = 0, OFF = 1) else PORTB |= 0b00000001; } return 0; } ADEN 1 ADSC 0 ADATE 0 ADIF 0 ADIE 0 ADPS2 0 ADPS1 0 ADPS0 1 ADCSRA REFS1 0 REFS0 1 ADLAR 0 MUX4 0 MUX3 0 MUX2 0 MUX1 0 MUX0 0/1 ADMUX
  • 15.
    15 Lam Phung ECTE333Tutorial 5 Q3 ─ ADC interrupt-driven processing Write a C interrupt-driven program for ADC. The program should repeatedly use the ADC interrupt to display the low 8 bits of the 10-bit output on PORTB. Step 1: Configure the ADC  What is the ADC source? ADC0  What reference voltage to use? AVCC = 5V  Align left or right? Right (low 8-bit in ADCL)  Enable or disable ADC auto-trigger? Disable  Enable or disable ADC interrupt? Enable  What is the prescaler? 2 (fastest conversion) Step 2: Start an ADC operation. Step 3: In ISR, read and display ADC result.
  • 16.
    16 Lam Phung ECTE333Tutorial 5 Q3 ─ ADC interrupt-driven processing #include<avr/io.h> #include<avr/interrupt.h> volatile unsigned char result; ISR(ADC_vect){ result = ADCL; // Read the low 8 bits, and store in variable ‘result’ } int main (void){ DDRB = 0xFF; // set port B for output // Configure the ADC module of the ATmega16 ADMUX = 0b01000000; // REFS1:0 = 01 -> AVCC as reference, // ADLAR = 0 -> Right adjust // MUX4:0 = 00000 -> ADC0 as input ADCSRA = 0b10001001; // ADEN = 1: enable ADC, // ADSC = 0: don't start conversion yet // ADATE = 0: disable auto trigger, // ADIE = 1: enable ADC interrupt // ASPS2:0 = 001: prescaler = 2 sei(); // enable interrupt system globally while(1){ // main loop ADCSRA = ADCSRA | 0b01000000; // start a conversion PORTB = ~result; // display on port B (LED ON = 0, OFF = 1) } return 0; } ADEN 1 ADSC 0 ADATE 0 ADIF 0 ADIE 1 ADPS2 0 ADPS1 0 ADPS0 1 ADCSRA REFS1 0 REFS0 1 ADLAR 0 MUX4 0 MUX3 0 MUX2 0 MUX1 0 MUX0 0 ADMUX
  • 17.
    17 Lam Phung ECTE333Tutorial 5 ADTS2 ADTS1 ADTS0 Trigger Source 0 0 0 Free Running mode 0 0 1 Analog Comparator 0 1 0 External Interrupt Request 0 1 1 Timer/Counter0 Compare Match 1 0 0 Timer/Counter0 Overflow 1 0 1 Timer/Counter1 Compare Match B 1 1 0 Timer/Counter1 Overflow 1 1 1 Timer/Counter1 Capture Event Q4 ─ ADC auto-trigger for regular sampling Develop an approach that uses the ADC auto-trigger mode to start a conversion every one second. The top 8 bits of result are to be displayed on PORTB. ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSRA register ADC Auto Trigger Enable: 1 to enable auto-triggering of ADC ADTS2 ADTS1 ADTS0 - ACME PUD PSR2 PSR10 Table 6.4: ADC Auto Trigger Source ADC Auto Trigger Source bits SFIOR register
  • 18.
    18 Lam Phung ECTE333Tutorial 5 Q4 ─ ADC Auto-trigger for regular sampling Connect analogue input to an ADC pin, e.g. ADC1. Configure the ADC unit:  ADC1 as input  AVCC as reference voltage,  ADC prescaler of 2,  left-adjust output,  enable auto-trigger on Timer 1 Compare Match B,  enable ADC interrupt. ADMUX = 0b01110001; ADCSRA = 0b10101001; SFIOR = 0b10100000; Configure Timer 1 to trigger Compare Match B every 1s:  internal clock of 1MHz.  timer prescaler of 256.  Fast PWM mode 1111: TOP = OCR1A, Compare Match on OCR1B.  Disable timer interrupt  Disable changing output compare pins TCCR1A = 0b00000011; TCCR1B = 0b00011100; OCR1A = 3096; OCR1B = 3096; (See Lecture 5/Tutorial 4)
  • 19.
    19 Lam Phung ECTE333Tutorial 5 Q4 ─ ADC Auto-trigger for regular sampling #include<avr/io.h> #include<avr/interrupt.h> volatile unsigned char result; ISR(ADC_vect){ result = ADCH; // take top 8-bits of output } int main (void){ DDRB = 0xFF; // set port B for output // Configure ADC ADMUX = 0b01100001; // channel ADC1, Vref = 5V, left adjust ADCSRA = 0b10101001; // ADEN = 1: enable ADC, // ADSC = 0: don't start conversion yet // ADATE = 1: enable auto trigger // ADIE = 1: enable ADC interrupt // ASPS2:0 = 001: ADC prescaler = 2 SFIOR = 0b10100000; // ADC auto-trigger on Compare Match Channel B // Configure Timer 1 TCCR1A = 0b00000011; // Timer mode bits WGM11-10= 11 TCCR1B = 0b00011100; // Timer mode bits WGM13-12= 11 // Timer prescaler bits = 100 (x256) OCR1A = 3906; // Top limit 3906 x 256us = 1 second OCR1B = 3906; // When to trigger compare match B TIMSK = 0; // Disable all timer interrupts sei(); while(1){ PORTB = ~result; // display ADC output } return 0; } ADEN 1 ADSC 0 ADATE 1 ADIF 0 ADIE 1 ADPS2 0 ADPS1 0 ADPS0 1 ADCSRA REFS1 0 REFS0 1 ADLAR 1 MUX4 0 MUX3 0 MUX2 0 MUX1 0 MUX0 1 ADMUX
  • 20.
    20 Lam Phung ECTE333Tutorial 5 Q5 ─ A-to-D Conversion Formula a) What is resolution or step size of the ADC? ∆𝑽 = ∆𝑻 × 𝒈𝒂𝒊𝒏 = 𝟎. 𝟎𝟏 𝒐𝑪 × 𝟎. 𝟏 𝑽 𝒐𝑪 = 𝟎. 𝟎𝟎𝟏𝑽 𝑻 Temperature Transducer 𝑽 ADC 𝒅 = 𝑽 − 𝑽𝒎𝒊𝒏 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏 - Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC - Temperature transducer gain: gain = 0.1V/oC - Temperature change to detect: ∆𝑻 = 0.01oC
  • 21.
    21 Lam Phung ECTE333Tutorial 5 Q5 ─ A-to-D Conversion Formula 𝑻 Temperature Transducer 𝑽 ADC 𝒅 = 𝑽 − 𝑽𝒎𝒊𝒏 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏 - Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC - Temperature transducer gain: gain = 0.1V/oC - Temperature change to detect: ∆𝑻 = 0.01oC b) What is the number of bits required for the ADC?  We assume that 𝑽𝒎𝒊𝒏 = 𝟎 when 𝑻𝒎𝒊𝒏 = −𝟓𝟎𝒐𝑪.  We have: 𝑽𝒎𝒂𝒙 − 𝑽𝒎𝒊𝒏 = 𝑻𝒎𝒂𝒙– 𝑻𝒎𝒊𝒏 × 𝒈𝒂𝒊𝒏 = {𝟏𝟓𝟎 – (– 𝟓𝟎)} × 𝟎. 𝟏 = 𝟐𝟎𝑽  Hence, the number of bits is 𝒏 = 𝒍𝒐𝒈𝟐 𝑽𝒎𝒂𝒙 − 𝑽𝒎𝒊𝒏 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 + 𝟏 = 𝟏𝟒. 𝟐𝟗 → 𝒏 = 𝟏𝟓
  • 22.
    22 Lam Phung ECTE333Tutorial 5 Q5 ─ A-to-D Conversion Formula 𝑻 Temperature Transducer 𝑽 ADC 𝒅 = 𝑽 − 𝑽𝒎𝒊𝒏 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏 - Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC - Temperature transducer gain: gain = 0.1V/oC - Temperature change to detect: ∆𝑻 = 0.01oC c) What is full scale voltage? d) What is the reference voltage of the converter? 𝑽𝑭𝑺𝑪 = 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 × 𝟐𝒏 − 𝟏 = 𝟑𝟐. 𝟕𝟔𝟕 𝑽 𝑽𝒓𝒆𝒇 = 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 × 𝟐𝒏 = 𝟑𝟐. 𝟕𝟔𝟖 𝑽
  • 23.
    23 Lam Phung ECTE333Tutorial 5 Q5 ─ A-to-D Conversion Formula 𝑻 Temperature Transducer 𝑽 ADC 𝒅 = 𝑽 − 𝑽𝒎𝒊𝒏 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 𝑽 = {𝑻 – 𝑻𝒎𝒊𝒏} × 𝒈𝒂𝒊𝒏 - Temperature measurement range: 𝑻𝒎𝒊𝒏 = -50oC to 𝑻𝒎𝒂𝒙 = 150oC - Temperature transducer gain: gain = 0.1V/oC - Temperature change to detect: ∆𝑻 = 0.01oC e) What is the actual input temperature when the digital output 𝒅 = 𝟐𝟎?  Input voltage of the ADC: 𝑽𝒊𝒏 = 𝑽𝒎𝒊𝒏 + 𝒔𝒕𝒆𝒑 𝒔𝒊𝒛𝒆 × 𝒅 = 𝟎 + 𝟎. 𝟎𝟎𝟏 × 𝟐𝟎 = 𝟎. 𝟎𝟐 V  The actual range: 𝑽𝒊𝒏 = 𝟎. 𝟎𝟐 ± 𝟎. 𝟎𝟎𝟎𝟓 V  Note that: 𝑽𝒊𝒏 = 𝑻𝒊𝒏 − 𝑻𝒎𝒊𝒏 × 𝒈𝒂𝒊𝒏 = 𝑻𝒊𝒏 + 𝟓𝟎 × 𝟎. 𝟏 → 𝑻𝒊𝒏= 𝑽𝒊𝒏 𝟎.𝟏 − 𝟓𝟎  Therefore, the range of input temperature 𝑻𝒊𝒏: [-49.805oC, -49.795oC].
  • 24.
    24 Lam Phung ECTE333Tutorial 5 Extra practice for Lecture/Lab/Tutorial 5 Write and test a C program that uses the auto-trigger mode of the ADC unit in ATmega16 to start a conversion operation every 500 millisecond. The analogue input is to be connected to pin A.0. The top-8 bits of conversion result are to be displayed on PORTB.
  • 25.
    25 Lam Phung ECTE333Tutorial 5 Extra practice for Lecture/Lab/Tutorial 5 Solve Problem Q4 using ADC Auto Trigger and Timer 1 Overflow.