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