Rev Author Line No. Line
1145 kaklik 1 /*! \file a2d.c \brief Analog-to-Digital converter function library. */
2 //*****************************************************************************
3 //
4 // File Name : 'a2d.c'
5 // Title : Analog-to-digital converter functions
6 // Author : Pascal Stang - Copyright (C) 2002
7 // Created : 2002-04-08
8 // Revised : 2002-09-30
9 // Version : 1.1
10 // Target MCU : Atmel AVR series
11 // Editor Tabs : 4
12 //
13 // This code is distributed under the GNU Public License
14 // which can be found at http://www.gnu.org/licenses/gpl.txt
15 //
16 //*****************************************************************************
17  
18 #include <avr/io.h>
19 #include <avr/interrupt.h>
20  
21 #include "global.h"
22 #include "a2d.h"
23  
24 // global variables
25  
26 //! Software flag used to indicate when
27 /// the a2d conversion is complete.
28 volatile unsigned char a2dCompleteFlag;
29  
30 // functions
31  
32 // initialize a2d converter
33 void a2dInit(void)
34 {
35 sbi(ADCSR, ADEN); // enable ADC (turn on ADC power)
36 cbi(ADCSR, ADFR); // default to single sample convert mode
37 a2dSetPrescaler(ADC_PRESCALE); // set default prescaler
38 a2dSetReference(ADC_REFERENCE); // set default reference
39 cbi(ADMUX, ADLAR); // set to right-adjusted result
40  
41 sbi(ADCSR, ADIE); // enable ADC interrupts
42  
43 a2dCompleteFlag = FALSE; // clear conversion complete flag
44 sei(); // turn on interrupts (if not already on)
45 }
46  
47 // turn off a2d converter
48 void a2dOff(void)
49 {
50 cbi(ADCSR, ADIE); // disable ADC interrupts
51 cbi(ADCSR, ADEN); // disable ADC (turn off ADC power)
52 }
53  
54 // configure A2D converter clock division (prescaling)
55 void a2dSetPrescaler(unsigned char prescale)
56 {
57 outb(ADCSR, ((inb(ADCSR) & ~ADC_PRESCALE_MASK) | prescale));
58 }
59  
60 // configure A2D converter voltage reference
61 void a2dSetReference(unsigned char ref)
62 {
63 outb(ADMUX, ((inb(ADMUX) & ~ADC_REFERENCE_MASK) | (ref<<6)));
64 }
65  
66 // sets the a2d input channel
67 void a2dSetChannel(unsigned char ch)
68 {
69 outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
70 }
71  
72 // start a conversion on the current a2d input channel
73 void a2dStartConvert(void)
74 {
75 sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag
76 sbi(ADCSR, ADSC); // start conversion
77 }
78  
79 // return TRUE if conversion is complete
80 u08 a2dIsComplete(void)
81 {
82 return bit_is_set(ADCSR, ADSC);
83 }
84  
85 // Perform a 10-bit conversion
86 // starts conversion, waits until conversion is done, and returns result
87 unsigned short a2dConvert10bit(unsigned char ch)
88 {
89 a2dCompleteFlag = FALSE; // clear conversion complete flag
90 outb(ADMUX, (inb(ADMUX) & ~ADC_MUX_MASK) | (ch & ADC_MUX_MASK)); // set channel
91 sbi(ADCSR, ADIF); // clear hardware "conversion complete" flag
92 sbi(ADCSR, ADSC); // start conversion
93 //while(!a2dCompleteFlag); // wait until conversion complete
94 //while( bit_is_clear(ADCSR, ADIF) ); // wait until conversion complete
95 while( bit_is_set(ADCSR, ADSC) ); // wait until conversion complete
96  
97 // CAUTION: MUST READ ADCL BEFORE ADCH!!!
98 return (inb(ADCL) | (inb(ADCH)<<8)); // read ADC (full 10 bits);
99 }
100  
101 // Perform a 8-bit conversion.
102 // starts conversion, waits until conversion is done, and returns result
103 unsigned char a2dConvert8bit(unsigned char ch)
104 {
105 // do 10-bit conversion and return highest 8 bits
106 return a2dConvert10bit(ch)>>2; // return ADC MSB byte
107 }
108  
109 //! Interrupt handler for ADC complete interrupt.
110 SIGNAL(SIG_ADC)
111 {
112 // set the a2d conversion flag to indicate "complete"
113 a2dCompleteFlag = TRUE;
114 }
115