root / arduino-1.0 / hardware / arduino / cores / arduino / wiring_analog.c @ 58d82c77
History | View | Annotate | Download (6.95 KB)
1 |
/*
|
---|---|
2 |
wiring_analog.c - analog input and output
|
3 |
Part of Arduino - http://www.arduino.cc/
|
4 |
|
5 |
Copyright (c) 2005-2006 David A. Mellis
|
6 |
|
7 |
This library is free software; you can redistribute it and/or
|
8 |
modify it under the terms of the GNU Lesser General Public
|
9 |
License as published by the Free Software Foundation; either
|
10 |
version 2.1 of the License, or (at your option) any later version.
|
11 |
|
12 |
This library is distributed in the hope that it will be useful,
|
13 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 |
Lesser General Public License for more details.
|
16 |
|
17 |
You should have received a copy of the GNU Lesser General
|
18 |
Public License along with this library; if not, write to the
|
19 |
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
20 |
Boston, MA 02111-1307 USA
|
21 |
|
22 |
Modified 28 September 2010 by Mark Sproul
|
23 |
|
24 |
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
|
25 |
*/
|
26 |
|
27 |
#include "wiring_private.h" |
28 |
#include "pins_arduino.h" |
29 |
|
30 |
uint8_t analog_reference = DEFAULT; |
31 |
|
32 |
void analogReference(uint8_t mode)
|
33 |
{ |
34 |
// can't actually set the register here because the default setting
|
35 |
// will connect AVCC and the AREF pin, which would cause a short if
|
36 |
// there's something connected to AREF.
|
37 |
analog_reference = mode; |
38 |
} |
39 |
|
40 |
int analogRead(uint8_t pin)
|
41 |
{ |
42 |
uint8_t low, high; |
43 |
|
44 |
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
45 |
if (pin >= 54) pin -= 54; // allow for channel or pin numbers |
46 |
#elif defined(__AVR_ATmega32U4__)
|
47 |
if (pin >= 18) pin -= 18; // allow for channel or pin numbers |
48 |
#else
|
49 |
if (pin >= 14) pin -= 14; // allow for channel or pin numbers |
50 |
#endif
|
51 |
|
52 |
#if defined(__AVR_ATmega32U4__)
|
53 |
pin = analogPinToChannel(pin); |
54 |
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); |
55 |
#elif defined(ADCSRB) && defined(MUX5)
|
56 |
// the MUX5 bit of ADCSRB selects whether we're reading from channels
|
57 |
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
|
58 |
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); |
59 |
#endif
|
60 |
|
61 |
// set the analog reference (high two bits of ADMUX) and select the
|
62 |
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
|
63 |
// to 0 (the default).
|
64 |
#if defined(ADMUX)
|
65 |
ADMUX = (analog_reference << 6) | (pin & 0x07); |
66 |
#endif
|
67 |
|
68 |
// without a delay, we seem to read from the wrong channel
|
69 |
//delay(1);
|
70 |
|
71 |
#if defined(ADCSRA) && defined(ADCL)
|
72 |
// start the conversion
|
73 |
sbi(ADCSRA, ADSC); |
74 |
|
75 |
// ADSC is cleared when the conversion finishes
|
76 |
while (bit_is_set(ADCSRA, ADSC));
|
77 |
|
78 |
// we have to read ADCL first; doing so locks both ADCL
|
79 |
// and ADCH until ADCH is read. reading ADCL second would
|
80 |
// cause the results of each conversion to be discarded,
|
81 |
// as ADCL and ADCH would be locked when it completed.
|
82 |
low = ADCL; |
83 |
high = ADCH; |
84 |
#else
|
85 |
// we dont have an ADC, return 0
|
86 |
low = 0;
|
87 |
high = 0;
|
88 |
#endif
|
89 |
|
90 |
// combine the two bytes
|
91 |
return (high << 8) | low; |
92 |
} |
93 |
|
94 |
// Right now, PWM output only works on the pins with
|
95 |
// hardware support. These are defined in the appropriate
|
96 |
// pins_*.c file. For the rest of the pins, we default
|
97 |
// to digital output.
|
98 |
void analogWrite(uint8_t pin, int val) |
99 |
{ |
100 |
// We need to make sure the PWM output is enabled for those pins
|
101 |
// that support it, as we turn it off when digitally reading or
|
102 |
// writing with them. Also, make sure the pin is in output mode
|
103 |
// for consistenty with Wiring, which doesn't require a pinMode
|
104 |
// call for the analog output pins.
|
105 |
pinMode(pin, OUTPUT); |
106 |
if (val == 0) |
107 |
{ |
108 |
digitalWrite(pin, LOW); |
109 |
} |
110 |
else if (val == 255) |
111 |
{ |
112 |
digitalWrite(pin, HIGH); |
113 |
} |
114 |
else
|
115 |
{ |
116 |
switch(digitalPinToTimer(pin))
|
117 |
{ |
118 |
// XXX fix needed for atmega8
|
119 |
#if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
|
120 |
case TIMER0A:
|
121 |
// connect pwm to pin on timer 0
|
122 |
sbi(TCCR0, COM00); |
123 |
OCR0 = val; // set pwm duty
|
124 |
break;
|
125 |
#endif
|
126 |
|
127 |
#if defined(TCCR0A) && defined(COM0A1)
|
128 |
case TIMER0A:
|
129 |
// connect pwm to pin on timer 0, channel A
|
130 |
sbi(TCCR0A, COM0A1); |
131 |
OCR0A = val; // set pwm duty
|
132 |
break;
|
133 |
#endif
|
134 |
|
135 |
#if defined(TCCR0A) && defined(COM0B1)
|
136 |
case TIMER0B:
|
137 |
// connect pwm to pin on timer 0, channel B
|
138 |
sbi(TCCR0A, COM0B1); |
139 |
OCR0B = val; // set pwm duty
|
140 |
break;
|
141 |
#endif
|
142 |
|
143 |
#if defined(TCCR1A) && defined(COM1A1)
|
144 |
case TIMER1A:
|
145 |
// connect pwm to pin on timer 1, channel A
|
146 |
sbi(TCCR1A, COM1A1); |
147 |
OCR1A = val; // set pwm duty
|
148 |
break;
|
149 |
#endif
|
150 |
|
151 |
#if defined(TCCR1A) && defined(COM1B1)
|
152 |
case TIMER1B:
|
153 |
// connect pwm to pin on timer 1, channel B
|
154 |
sbi(TCCR1A, COM1B1); |
155 |
OCR1B = val; // set pwm duty
|
156 |
break;
|
157 |
#endif
|
158 |
|
159 |
#if defined(TCCR2) && defined(COM21)
|
160 |
case TIMER2:
|
161 |
// connect pwm to pin on timer 2
|
162 |
sbi(TCCR2, COM21); |
163 |
OCR2 = val; // set pwm duty
|
164 |
break;
|
165 |
#endif
|
166 |
|
167 |
#if defined(TCCR2A) && defined(COM2A1)
|
168 |
case TIMER2A:
|
169 |
// connect pwm to pin on timer 2, channel A
|
170 |
sbi(TCCR2A, COM2A1); |
171 |
OCR2A = val; // set pwm duty
|
172 |
break;
|
173 |
#endif
|
174 |
|
175 |
#if defined(TCCR2A) && defined(COM2B1)
|
176 |
case TIMER2B:
|
177 |
// connect pwm to pin on timer 2, channel B
|
178 |
sbi(TCCR2A, COM2B1); |
179 |
OCR2B = val; // set pwm duty
|
180 |
break;
|
181 |
#endif
|
182 |
|
183 |
#if defined(TCCR3A) && defined(COM3A1)
|
184 |
case TIMER3A:
|
185 |
// connect pwm to pin on timer 3, channel A
|
186 |
sbi(TCCR3A, COM3A1); |
187 |
OCR3A = val; // set pwm duty
|
188 |
break;
|
189 |
#endif
|
190 |
|
191 |
#if defined(TCCR3A) && defined(COM3B1)
|
192 |
case TIMER3B:
|
193 |
// connect pwm to pin on timer 3, channel B
|
194 |
sbi(TCCR3A, COM3B1); |
195 |
OCR3B = val; // set pwm duty
|
196 |
break;
|
197 |
#endif
|
198 |
|
199 |
#if defined(TCCR3A) && defined(COM3C1)
|
200 |
case TIMER3C:
|
201 |
// connect pwm to pin on timer 3, channel C
|
202 |
sbi(TCCR3A, COM3C1); |
203 |
OCR3C = val; // set pwm duty
|
204 |
break;
|
205 |
#endif
|
206 |
|
207 |
#if defined(TCCR4A) && defined(COM4A1)
|
208 |
case TIMER4A:
|
209 |
// connect pwm to pin on timer 4, channel A
|
210 |
sbi(TCCR4A, COM4A1); |
211 |
OCR4A = val; // set pwm duty
|
212 |
break;
|
213 |
#endif
|
214 |
|
215 |
#if defined(TCCR4A) && defined(COM4B1)
|
216 |
case TIMER4B:
|
217 |
// connect pwm to pin on timer 4, channel B
|
218 |
sbi(TCCR4A, COM4B1); |
219 |
OCR4B = val; // set pwm duty
|
220 |
break;
|
221 |
#endif
|
222 |
|
223 |
#if defined(TCCR4A) && defined(COM4C1)
|
224 |
case TIMER4C:
|
225 |
// connect pwm to pin on timer 4, channel C
|
226 |
sbi(TCCR4A, COM4C1); |
227 |
OCR4C = val; // set pwm duty
|
228 |
break;
|
229 |
#endif
|
230 |
|
231 |
#if defined(TCCR4A) && defined(COM4D1)
|
232 |
case TIMER4D:
|
233 |
// connect pwm to pin on timer 4, channel D
|
234 |
sbi(TCCR4A, COM4D1); |
235 |
OCR4D = val; // set pwm duty
|
236 |
break;
|
237 |
#endif
|
238 |
|
239 |
#if defined(TCCR5A) && defined(COM5A1)
|
240 |
case TIMER5A:
|
241 |
// connect pwm to pin on timer 5, channel A
|
242 |
sbi(TCCR5A, COM5A1); |
243 |
OCR5A = val; // set pwm duty
|
244 |
break;
|
245 |
#endif
|
246 |
|
247 |
#if defined(TCCR5A) && defined(COM5B1)
|
248 |
case TIMER5B:
|
249 |
// connect pwm to pin on timer 5, channel B
|
250 |
sbi(TCCR5A, COM5B1); |
251 |
OCR5B = val; // set pwm duty
|
252 |
break;
|
253 |
#endif
|
254 |
|
255 |
#if defined(TCCR5A) && defined(COM5C1)
|
256 |
case TIMER5C:
|
257 |
// connect pwm to pin on timer 5, channel C
|
258 |
sbi(TCCR5A, COM5C1); |
259 |
OCR5C = val; // set pwm duty
|
260 |
break;
|
261 |
#endif
|
262 |
|
263 |
case NOT_ON_TIMER:
|
264 |
default:
|
265 |
if (val < 128) { |
266 |
digitalWrite(pin, LOW); |
267 |
} else {
|
268 |
digitalWrite(pin, HIGH); |
269 |
} |
270 |
} |
271 |
} |
272 |
} |