Revision 324
Commented analog.c and analog.h.
Brian forgot to update bom.c and rangefinder.c to use analog_get8 and
analog8 respecitively when he swapped the function names in analog.c.
This has been fixed. Code not tested or compiled but should be ok.
branches/analog/trunk/code/projects/libdragonfly/analog.c | ||
---|---|---|
28 | 28 |
* @brief Analog input and output |
29 | 29 |
* |
30 | 30 |
* Contains functions for manipulating the ADC on the Dragonfly board. |
31 |
* It operates by running throug all available analog ports (set by AN_MAX, |
|
32 |
* see analog.h for details on that constant). It performs a conversion for |
|
33 |
* each port and stores the 8bit and 10bit value. It then increments the |
|
34 |
* port that it is looking at and then procedes to do another read. |
|
35 |
* |
|
36 |
* analog8 and analog10 are changed to use the lookup table. To use the |
|
37 |
* historic functions, use analog_get8 and analog_get10. If you do use those, |
|
38 |
* it is advised to turn off the loop by calling analog_stop_loop and restarting |
|
39 |
* the loop when done with analog_start_loop. This is especially important if you |
|
40 |
* are planning on doing a series of analog_getX reads. |
|
41 |
* |
|
42 |
* This function pretty intensive on the interrupts as it will be called quite |
|
43 |
* often. Plan ahead for this. |
|
31 | 44 |
* |
32 |
* @author Colony Project, CMU Robotics Club |
|
33 |
* code mostly taken from fwr analog file (author: Tom Lauwers)
|
|
45 |
* @author Colony Project, CMU Robotics Club, Kevin Woo
|
|
46 |
* Originally based on fwr code by Tom Lauwers
|
|
34 | 47 |
**/ |
35 | 48 |
|
36 | 49 |
#include <util/delay.h> |
... | ... | |
62 | 75 |
* Initializes the ADC. |
63 | 76 |
* Call analog_init before reading from the analog ports. |
64 | 77 |
* |
65 |
* @see analog8, analog10 |
|
78 |
* @see analog8, analog10, analog_get8, analog_get10, analog_start_loop |
|
79 |
* analog_stop_loop |
|
66 | 80 |
**/ |
67 | 81 |
void analog_init(int start_conversion) |
68 | 82 |
{ |
69 |
for (int i = 0; i < 11; i++) { |
|
83 |
//Initialize the array to 0 |
|
84 |
for (int i = 0; i < (AN_MAX + 1); i++) { |
|
70 | 85 |
an_val[i].adc10 = 0; |
71 | 86 |
an_val[i].adc8 = 0; |
72 | 87 |
} |
73 | 88 |
|
74 |
//cli(); |
|
75 | 89 |
// ADMUX register |
90 |
// The following bits are set |
|
76 | 91 |
// Bit 7,6 - Set voltage reference to AVcc (0b01) |
77 | 92 |
// Bit 5 - ADLAR set to simplify moving from register |
78 | 93 |
// Bit 4 - X |
... | ... | |
83 | 98 |
|
84 | 99 |
|
85 | 100 |
// ADC Status Register A |
101 |
// The following bits are set |
|
86 | 102 |
// Bit 7 - ADEN is set (enables analog) |
87 |
// Bit 6 - Start conversion bit is set (must be done once for free-running mode) |
|
88 |
// Bit 5 - Enable Auto Trigger (for free running mode) NOT DOING THIS RIGHT NOW |
|
89 |
// Bit 4 - ADC interrupt flag, 0 |
|
90 | 103 |
// Bit 3 - Enable ADC Interrupt (required to run free-running mode) |
91 | 104 |
// Bits 2-0 - Set to create a clock divisor of 128, to make ADC clock = 8,000,000/64 = 125kHz |
92 | 105 |
ADCSRA = 0; |
... | ... | |
99 | 112 |
set_adc_mux(0x00); |
100 | 113 |
adc_current_port = AN1; |
101 | 114 |
|
102 |
//Start the conversion if requested |
|
115 |
// Start the conversion if requested
|
|
103 | 116 |
if (start_conversion) |
104 | 117 |
analog_start_loop(); |
105 | 118 |
else |
106 | 119 |
analog_stop_loop(); |
107 |
//sei(); |
|
108 | 120 |
|
109 | 121 |
} |
110 | 122 |
|
123 |
/** |
|
124 |
* Reads an analog value from the look-up table. Values are not |
|
125 |
* good unless the analog loop is running. |
|
126 |
* |
|
127 |
* @param which is the analog port you wish to read. |
|
128 |
* |
|
129 |
* @return returns an 8 bit value which represents the analog value |
|
130 |
* |
|
131 |
* @see analog8, analog_start_loop, analog_stop_loop, analog_init |
|
132 |
**/ |
|
111 | 133 |
unsigned int analog_get8(int which) { |
112 | 134 |
if (which == BOM_PORT) { |
113 | 135 |
return 0; |
... | ... | |
116 | 138 |
} |
117 | 139 |
} |
118 | 140 |
|
141 |
/** |
|
142 |
* Reads an analog value from the look-up table. Values are not |
|
143 |
* good unless the analog loop is running. |
|
144 |
* |
|
145 |
* @param which is the analog port you wish to read. |
|
146 |
* |
|
147 |
* @return returns an 10 bit value which represents the analog value |
|
148 |
* |
|
149 |
* @see analog8, analog_start_loop, analog_stop_loop, analog_init |
|
150 |
**/ |
|
119 | 151 |
unsigned int analog_get10(int which) { |
120 | 152 |
if (which == BOM_PORT) { |
121 | 153 |
return 0; |
... | ... | |
124 | 156 |
} |
125 | 157 |
} |
126 | 158 |
|
159 |
/** |
|
160 |
* Starts the analog loop to put values into the lookup table. Need |
|
161 |
* to have the loop running before analog_get8 and analog_get10 are |
|
162 |
* valid. |
|
163 |
* |
|
164 |
* @see analog_stop_loop, analog_init, analog_get8, analog_get10 |
|
165 |
**/ |
|
127 | 166 |
void analog_start_loop(void) { |
128 | 167 |
//Start the conversion |
129 | 168 |
ADCSRA |= _BV(ADSC); |
130 | 169 |
adc_loop_running = 0x1; |
131 | 170 |
} |
132 | 171 |
|
133 |
//will stop after current conversion finishes |
|
172 |
/** |
|
173 |
* Starts the analog loop to put values into the lookup table. You |
|
174 |
* should disable to loop to use analog8 and analog10 reliably. |
|
175 |
* |
|
176 |
* @see analog_stop_loop, analog_init, analog8, analog10 |
|
177 |
**/ |
|
134 | 178 |
void analog_stop_loop(void) { |
135 | 179 |
//Stop the conversion |
136 | 180 |
adc_loop_running = 0x0; |
... | ... | |
140 | 184 |
* analog_init must be called before using this function. |
141 | 185 |
* |
142 | 186 |
* @param which the analog port to read from. One of |
143 |
* the constants AN0 - AN7.
|
|
187 |
* the constants AN0 - AN15.
|
|
144 | 188 |
* |
145 | 189 |
* @return the eight bit input to the specified port |
146 | 190 |
* |
... | ... | |
173 | 217 |
* |
174 | 218 |
* |
175 | 219 |
* @param which the analog port to read from. Typically |
176 |
* a constant, one of AN0 - AN7.
|
|
220 |
* a constant, one of AN0 - AN15.
|
|
177 | 221 |
* |
178 | 222 |
* @return the ten bit number input to the specified port |
179 | 223 |
* |
... | ... | |
218 | 262 |
**/ |
219 | 263 |
int wheel(void) |
220 | 264 |
{ |
221 |
return analog_get8(WHEEL_PORT);
|
|
265 |
return analog8(WHEEL_PORT); |
|
222 | 266 |
} |
223 | 267 |
|
224 | 268 |
|
... | ... | |
248 | 292 |
ISR(ADC_vect) { |
249 | 293 |
static volatile int adc_prev_loop_running = 0; |
250 | 294 |
|
295 |
// Need these local variables to read ADCH and ADCL in the correct order |
|
251 | 296 |
int adc_h = 0; |
252 | 297 |
int adc_l = 0; |
253 | 298 |
|
254 |
//usb_putc('p'); |
|
255 |
//usb_putc('r'); |
|
256 |
//usb_puti(adc_loop_running); |
|
257 |
//usb_puts("\n\r"); |
|
258 |
|
|
259 | 299 |
//Store the value only if this read isn't for the BOM |
260 | 300 |
if (ADMUX != BOM_PORT) { |
301 |
// Read ADCL before ADCH otherwise the registers change in the middle |
|
261 | 302 |
adc_l = ADCL; |
262 | 303 |
adc_h = ADCH; |
263 | 304 |
|
264 | 305 |
an_val[adc_current_port - 1].adc10 = (adc_h << 2) | (adc_l >> 6); |
265 | 306 |
an_val[adc_current_port - 1].adc8 = adc_h; |
266 |
//usb_puti(an_val[adc_current_port - 1].adc10); |
|
267 |
//usb_puts("\n\r"); |
|
268 |
//usb_puti(an_val[adc_current_port - 1].adc8); |
|
269 |
//usb_puti(ADCH); |
|
270 |
//usb_puts("\n\r"); |
|
307 |
|
|
271 | 308 |
} |
272 | 309 |
|
273 | 310 |
//Save the result only if we just turned off the loop |
... | ... | |
302 | 339 |
return; |
303 | 340 |
|
304 | 341 |
ADCSRA |= _BV(ADSC); |
305 |
|
|
306 |
//if (ADCSRA & _BV(ADSC)) |
|
307 |
// usb_putc('s'); |
|
308 |
|
|
309 | 342 |
return; |
310 | 343 |
} |
311 | 344 |
|
branches/analog/trunk/code/projects/libdragonfly/analog.h | ||
---|---|---|
29 | 29 |
* @brief Contains functions and definitions for using the ADC |
30 | 30 |
* |
31 | 31 |
* Contains definitions and function prototypes for using the |
32 |
* ADC to detect analog signals on pins AN0 - AN7. |
|
33 |
* AN6 and AN7 are used for the wheel and battery. |
|
34 |
|
|
35 |
* The pins labeled E6 and E7 are external interrupt pins and are not related |
|
36 |
* to analog. |
|
37 |
|
|
32 |
* ADC to detect analog signals on pins AN0 - AN15. |
|
33 |
* See analog.c for implementation details. |
|
34 |
* |
|
38 | 35 |
* @author Colony Project, CMU Robotics Club, based on firefly |
39 | 36 |
* code by Tom Lauwers |
40 |
*/ |
|
37 |
**/
|
|
41 | 38 |
|
42 | 39 |
#ifndef _ANALOG_H |
43 | 40 |
#define _ANALOG_H |
... | ... | |
91 | 88 |
/** @brief Analog port for the battery voltage detector **/ |
92 | 89 |
#define BATT_PORT AN11 |
93 | 90 |
|
91 |
/** @brief Used in analog_init to start the analog loop from the get-go **/ |
|
94 | 92 |
#define ADC_START 1 |
93 |
/** @brief Used in analog_init to not start the analog loop from the get-go **/ |
|
95 | 94 |
#define ADC_STOP 0 |
96 |
|
|
95 |
/** @brief Maximum number of analog ports to check. This number is equivalent to |
|
96 |
* AN1 -> AN11 as AN0 and AN7 are skipped. **/ |
|
97 |
#define ANMAX 11 |
|
98 |
/** @brief For use with ADMUX register. Means that We will use AVCC (REFS0) and |
|
99 |
* enable ADLAR. **/ |
|
97 | 100 |
#define ADMUX_OPT 0x60 |
98 | 101 |
|
99 | 102 |
|
... | ... | |
104 | 107 |
void analog_start_loop(void); |
105 | 108 |
/** @brief Stops the analog loop. Doesn't do anything if the loop is already stopped. **/ |
106 | 109 |
void analog_stop_loop(void); |
107 |
/** @brief Read an 8-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
110 |
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog8. **/
|
|
108 | 111 |
unsigned int analog8(int which); |
109 |
/** @brief Read a 10-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
112 |
/** @brief Returns an 10-bit analog value from the look up table. Use this instead of analog10. **/
|
|
110 | 113 |
unsigned int analog10(int which); |
111 | 114 |
/** @brief Read the position of the wheel. **/ |
112 | 115 |
int wheel(void); |
113 |
/** @brief Returns an 8-bit analog value from the look up table. Use this instead of analog8. **/
|
|
116 |
/** @brief Read an 8-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
114 | 117 |
unsigned int analog_get8(int which); |
115 |
/** @brief Returns an 10-bit analog value from the look up table. Use this instead of analog10. **/
|
|
118 |
/** @brief Read a 10-bit number from an analog port. Loop must be stopped for this to work. **/
|
|
116 | 119 |
unsigned int analog_get10(int which); |
117 | 120 |
|
118 | 121 |
|
branches/analog/trunk/code/projects/libdragonfly/bom.c | ||
---|---|---|
141 | 141 |
else |
142 | 142 |
output_low(MONK0); |
143 | 143 |
|
144 |
a = analog8(MONKI); |
|
144 |
a = analog_get8(MONKI);
|
|
145 | 145 |
|
146 | 146 |
if (a < h) |
147 | 147 |
{ |
branches/analog/trunk/code/projects/libdragonfly/rangefinder.c | ||
---|---|---|
134 | 134 |
**/ |
135 | 135 |
int range_read_distance (int range_id) |
136 | 136 |
{ |
137 |
return linearize_distance(analog_get8(range_id));
|
|
137 |
return linearize_distance(analog8(range_id)); |
|
138 | 138 |
} |
139 | 139 |
|
140 | 140 |
/** @} **/ //end defgroup |
Also available in: Unified diff