Lab2: A/D Converter - University of Colorado Colorado Springs

Download Report

Transcript Lab2: A/D Converter - University of Colorado Colorado Springs

Lab2: A/D Converter
1
Lab2: A/D Converter
• This circuit connects a variable voltage to an A/D
port on the AVR mcu. Your software running on
the AVR mcu will read the digital value and
display the percent and raw value of the voltage,
VA as shown in Table 1.
• The interface consists of some analog circuitry
as well as wiring the analog circuit to the
STK500 and running corresponding software on
the AVR mcu. Each circuit requires a unique Croutine.
2
Atmeg16
We use ATmega16 having the same pin layout
3
Pin 40 = PA0 = ADC0
AD converter Channel 0
Pin 32 = AREF
(= VTG on STK500
board)
Pin 31 = GND = AVR board ground
Use the AVR board ground
4
5
Pin layout is different from Atmeg16
Port A
also
serves
as
AD inputs
Atmega8515 is at SCKT3000D3
6
Lab2: A/D Converter
• Pre-Lab Assignments
• Read the ATmega16/ATmega8515 on-line
data book available in the course website,
pages 202 through 220.
• Read B, C, and O (course text), chapter 2.
• Read the AVR STK500 User Guide, page
3-11 and pages 3-16 through 3-18.
• Answer Pre-Lab Questions
7
Pre_lab questions
1.What is the range of an n-bit A/D converter?
2. Our ATmeg16/ATmega8515 has an 10-bit A/D converter.
What is the resolution if the full-scale input range is 5V?
3. Briefly describe the two operating modes of the ADC in
the ATmeg16/ATmega8515.
4. What are the ADC noise canceling techniques?
5. What two registers are used by the ADC and
what are their purposes?
ADCSRA ADMUX ADCW
8
ADCSRA bit definitions (Textbook: page 143)
Bit
7
6
5
4
3
2
1
0
Bit7: ADC Enable bit
Bit6: ADC start conversion bit
Bit5: ADC free running bit
Bit0-Bit2: ADC prescaler select bit
ADCSRA=0xE9; /*enable ADC, free run, started,
clock prescaler of 64 */
ADCSRA = 11101110
9
There are two operating modes of ADC:
1. In the interrupt-driven, (single-conversion)
mode, only one conversion occurs after setting
the start conversion bit and the bit must be set
again before another conversion.
2. In the free-running mode, successive
conversions are restarted automatically once
the first conversion completes.
10
Lab2 software requirements
• The ADC program can use a 100 ms clock to trigger the
ISR. The ISR set a flag and the actual work of reading
the ADC and running the math can be done in main().
• Every 5 times through the ISR – i.e. every 500 ms – the
ISR blinked an LED. This is done to provide a heartbeat
signal. If the rest of the program is not working but the
LED is blinking, we know that the P is OK and that the
software is not hung. This was very useful in the
troubleshooting phase.
• Demo and produce Table 1
11
Table 1 Voltage and Percentage of Full Scale
Voltage Measured
Value at Point VA
Display Voltage
Digital Value
Percentage of Full
Scale
0.00 V
0.00 V
0x000
0%
0.50 V
0.50 V
0x068
10%
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
4.72 V
4.79 V
0x3D6
95%
12
Table 1. ADC Measurements for Different Potentiometer Settings
Measured
Displayed Voltage
Digital Value
Percent of Full
Voltage (V)
(V)
(Decimal)
Scale (%)
0.000042
0
0
0.25
0.244
50
0.503
0.503
103
0.755
0.757
155
1
1.006
206
1.245
1.256
257
1.495
1.505
308
1.755
1.769
362
2.033
2.052
420
2.231
2.253
461
2.556
2.585
529
2.75
2.781
569
3.013
3.044
623
3.257
3.294
674
3.507
3.548
726
3.756
3.797
777
4.042
4.086
836
4.26
4.305
881
4.535
4.584
938
4.742
4.794
981
4.954
5
1023
0
4
10
15
20
25
30
35
41
45
51
55
60
65
70
75
81
86
91
95
100
13
Lab2 software requirement
 For noise elimination you can make your program to
measure the ADC channel 4 times, then throws out the
highest and the lowest and takes an average of the
remaining 2 data points.
 This makes sure that outlying data points (flyers) do not
affect the final result.
 The main issue is an occasional data point that is
obviously very far out of the normal band. The technique
used for noise elimination can eliminate those data
points. The resulting output was quite stable. Output
data was solidly +/- 1 unit (5 mV) with an occasional
jump to +/- 2 units.
14
main()
Initialize peripherals in Atmeg16 P:
Port B : output, initialized to all 1’s = LED’s off.
Timer 1 : 278 s period, interrupt on, reload for 100 ms period.
ADC: turn ADC on, enable the interrupt and set ADC clock to
115 kHz
Wait until the ADC flag is set by the ISR.
Clear the ADC flag.
Initialize loop variables and select channel 1.
Run ADC measure loop 4 times
………… more work.
15
Timer 1, ISR()
Reload counter for 100 ms.
Increment the 1-5 counter.
If the 1-5 counter overflows, blink the heartbeat LED.
Set the ADC flag. ……..
ADC, ISR()
Set the ADC done flag.
16
#include <mega16.h>
// Standard Input/Output functions
#include <stdio.h>
char adcFlag = 0;
char ledFlag = 0;
char adcDone = 0;
char count = 0;
unsigned char led1 = 0xFF;
unsigned char led2 = 0xFE;
….
17
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer 1 value
TCNT1H=0xFE;
TCNT1L=0x97;
// Place your code here
adcFlag = 1;
// Increment the count
// Every 5 times through (500 ms) blink the LED (heartbeat LED)
…………..
interrupt [ADC_INT] void adc_isr(void)
{
adcDone = 1;
}
void main(void)
// Main Control Loop
while (1){
// When ADC flag is set by interrupt,
// do conversion and show results
// Wait for ISR to set flag
// Wait until conversion is done
while(adcDone == 0){ }
// Get and process data
volts = ADCW;
//printf(" v = %d", volts);
if(volts < loV){ loV = volts; }
if(volts > hiV){ hiV = volts; }
sumV += volts;
Another approach
1. write the read_adc function
2. main calls the read_adc function
20
This is another example of reading ADC output.
while (1)
{
// Place your code here
delay_ms(900);
// delay 900 ms;
ADC_sum=0;
// initialize ADC_sum;
for (i=0;i < 10; i++){ // start to sum 10 ADC samples;
delay_ms(10);
// take ADC sample every 10 ms;
ADC_sum += read_adc(0); // read ADC output from PA0 and add to ADC_sum;
}
ADC_output = ADC_sum/10;
// averaged ADC output;
ADC_percent = ADC_output*25/256;
// calculate percentage of ADC full range for current ADC output;
printf("ADC Output = %4d
ADC Percentage = %3d%%\r", ADC_output,
ADC_percent); // Display ADC output to terminal;
if (ADC_output > 0x0332)
// threshold detection at 4.0V;
PORTB = 0xFE;
//turn on LED0 when ADC output > 4.0V;
else
PORTB = 0xFF;
};
21