ADC as you can guess converts analog voltage to digital number, so we could work with it in microcontroller. We can build simple ADC with comparator, it's a device which compares 2 signals (1 of them is some constant reference voltage) gives one otput if 1 signal is bigger and other if smaller.
ADC accuracy depends on it's resolution. e.g. if we have reference voltage = 5 V and our ADC is 10-bit, then on every bit we have 5 / ( 2^10 - 1 ) = 0.00489 or 5 mV, so we can't measure changes less than 5 mV.
To configure ADC we use ADSCRA register
7 ADEN enable ADC
1 ON
0 OFF
6 ADSC runs ADC, if we configure ADC to run only 1 time then we need to write here 1, after ADC ends calculations this bit will be cleared and we have to change it again if we want to run ADC again.
5 ADFR choose ADC working mode
0 – trigger ADSC manually
1 – auto triggering (it runs endlessly, 1 is always written in ADSC)
4 ADIF This bit is set when an ADC conversion completes and the Data Registers are updated.
3 ADIE Interrupts
0 – Disable
1 – Enable
2 1 0 ADPS ADC frequency
CK = MC frequency
000 СК/2
001 СК/2
010 СК/4
011 СК/8
100 СК/16
101 СК/32
110 СК/64
111 СК/128
ADMUX register is responsible for choosing input pin and reference voltage.
7-6 REFS These bits select the voltage reference for the ADC.
00 AREF
01 AVCC with external capacitor at AREF pin
10 Reserved
11 Internal 2.56V Voltage Reference with external capacitor at AREF pin
5 ADLAR determines how ADC conversion result will be written in data register. We have 10-bit ADC, so we need to use 2 8-bit registers.
4-0 MUX The value of these bits selects which combination of analog inputs are connected to the ADC. (ATmega8)
0000 ADC0
0001 ADC1
0010 ADC2
0011 ADC3
0100 ADC4
0101 ADC5
0110 ADC6
0111 ADC7
Working proteus project
#include <avr io.h> #include <avr interrupt.h> //Configure interrupt ISR(ADC_vect) { unsigned int ADCdata, voltage_0, voltage, voltage_2, voltage_3; ADCdata = ADCW; // ADCW keeps our ADC result value (16 bit) voltage_0 = ADCdata * 48875 / 10000; // 5 вольт / 1023 = 4.8875 voltage = voltage_0 % 10000 / 1000; voltage_2 = voltage_0 % 1000 / 100; voltage_3 = voltage_0 % 100 / 10; PORTC = voltage; PORTD = voltage_2; PORTB = voltage_3; ADCSRA = ADCSRA | 0x40;// Start Conversion 0b01000000 } int main (void) { DDRB = 0xFF; DDRD = 0xFF; DDRC = 0xFF; ADMUX = 0x00; // PA0 ADCSRA = 0b11001110; PORTB = 0x00; PORTD = 0x00; PORTC = 0x00; sei(); while(1); }Circuit:
Applying voltage on PA0. After that convert it in to digital value and display information on displays, Port B == ones, Port C == tenths, Port D == hundreths. So we have 2.35 V.
We get information about voltage from ADCW (it automaticly reads 2 bytes from ADC registers). I configured ADC to take reference voltage from AVCC, when we have 5 V on pin, ADCW value will be 2^10-1 = 1023.
Now we use formule:
Volts = ADCW * reference voltage / resolution
In our case:
5 / 1023 = 0.0048876
1 bit == 0.0048876 V
It's better to use integrers then fractions.
0.0048876 = 48876 / 10000000
I need mV to be integrer, that's why i will 5 multiply by 1000.
5000 / 1023 = 4.8875 = 48875 / 10000
Now 1 bit == 4 mV. (int's are not rounded)
In the end we have:
Now 1 bit == 4 mV. (int's are not rounded)
In the end we have:
ADCdata = ADCW
voltage_0 = ADCW * 48875 / 10000
So in our variable we have a four-digit number which represents mV. e.g. 3524 == 3.524 V.
Now we just need to get every part seperatly.
So in our variable we have a four-digit number which represents mV. e.g. 3524 == 3.524 V.
Now we just need to get every part seperatly.
voltage_0 is our four-digit number.
We take from that remainder when divided by 10000, we would get 3524, after that divide it by 1000, now we get 3.
voltage == 3.
write that in corresponding port and repeat the process with tenths and hundredths
We take from that remainder when divided by 10000, we would get 3524, after that divide it by 1000, now we get 3.
voltage == 3.
write that in corresponding port and repeat the process with tenths and hundredths
Information:
samou4ka.net
avrlab.com
chipenable.ru
radioparty.ru
my-avr.at.ua
myrobot.ru
avr-tutorials.com
Book: "Шпак Ю.А. - Программирование на языке C для AVR и PIC"
No comments :
Post a Comment