2 wiring_analog.c - analog input and output
3 Part of Arduino - http://www.arduino.cc/
5 Copyright (c) 2005-2006 David A. Mellis
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.
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.
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
22 Modified 28 September 2010 by Mark Sproul
24 $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
27 #include "wiring_private.h"
28 #include "pins_arduino.h"
30 uint8_t analog_reference = DEFAULT;
32 void analogReference(uint8_t mode)
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;
40 int analogRead(uint8_t pin)
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 #elif defined(__AVR_ATmega1284__)
49 if (pin >= 24) pin -= 24; // allow for channel or pin numbers
51 if (pin >= 14) pin -= 14; // allow for channel or pin numbers
54 #if defined(__AVR_ATmega32U4__)
55 pin = analogPinToChannel(pin);
56 ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
57 #elif defined(ADCSRB) && defined(MUX5)
58 // the MUX5 bit of ADCSRB selects whether we're reading from channels
59 // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
60 ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
63 // set the analog reference (high two bits of ADMUX) and select the
64 // channel (low 4 bits). this also sets ADLAR (left-adjust result)
65 // to 0 (the default).
67 ADMUX = (analog_reference << 6) | (pin & 0x07);
70 // without a delay, we seem to read from the wrong channel
73 #if defined(ADCSRA) && defined(ADCL)
74 // start the conversion
77 // ADSC is cleared when the conversion finishes
78 while (bit_is_set(ADCSRA, ADSC));
80 // we have to read ADCL first; doing so locks both ADCL
81 // and ADCH until ADCH is read. reading ADCL second would
82 // cause the results of each conversion to be discarded,
83 // as ADCL and ADCH would be locked when it completed.
87 // we dont have an ADC, return 0
92 // combine the two bytes
93 return (high << 8) | low;
96 // Right now, PWM output only works on the pins with
97 // hardware support. These are defined in the appropriate
98 // pins_*.c file. For the rest of the pins, we default
100 void analogWrite(uint8_t pin, int val)
102 // We need to make sure the PWM output is enabled for those pins
103 // that support it, as we turn it off when digitally reading or
104 // writing with them. Also, make sure the pin is in output mode
105 // for consistenty with Wiring, which doesn't require a pinMode
106 // call for the analog output pins.
107 pinMode(pin, OUTPUT);
110 digitalWrite(pin, LOW);
114 digitalWrite(pin, HIGH);
118 switch(digitalPinToTimer(pin))
120 // XXX fix needed for atmega8
121 #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
123 // connect pwm to pin on timer 0
125 OCR0 = val; // set pwm duty
129 #if defined(TCCR0A) && defined(COM0A1)
131 // connect pwm to pin on timer 0, channel A
133 OCR0A = val; // set pwm duty
137 #if defined(TCCR0A) && defined(COM0B1)
139 // connect pwm to pin on timer 0, channel B
141 OCR0B = val; // set pwm duty
145 #if defined(TCCR1A) && defined(COM1A1)
147 // connect pwm to pin on timer 1, channel A
149 OCR1A = val; // set pwm duty
153 #if defined(TCCR1A) && defined(COM1B1)
155 // connect pwm to pin on timer 1, channel B
157 OCR1B = val; // set pwm duty
161 #if defined(TCCR2) && defined(COM21)
163 // connect pwm to pin on timer 2
165 OCR2 = val; // set pwm duty
169 #if defined(TCCR2A) && defined(COM2A1)
171 // connect pwm to pin on timer 2, channel A
173 OCR2A = val; // set pwm duty
177 #if defined(TCCR2A) && defined(COM2B1)
179 // connect pwm to pin on timer 2, channel B
181 OCR2B = val; // set pwm duty
185 #if defined(TCCR3A) && defined(COM3A1)
187 // connect pwm to pin on timer 3, channel A
189 OCR3A = val; // set pwm duty
193 #if defined(TCCR3A) && defined(COM3B1)
195 // connect pwm to pin on timer 3, channel B
197 OCR3B = val; // set pwm duty
201 #if defined(TCCR3A) && defined(COM3C1)
203 // connect pwm to pin on timer 3, channel C
205 OCR3C = val; // set pwm duty
211 //connect pwm to pin on timer 4, channel A
213 #if defined(COM4A0) // only used on 32U4
216 OCR4A = val; // set pwm duty
220 #if defined(TCCR4A) && defined(COM4B1)
222 // connect pwm to pin on timer 4, channel B
224 OCR4B = val; // set pwm duty
228 #if defined(TCCR4A) && defined(COM4C1)
230 // connect pwm to pin on timer 4, channel C
232 OCR4C = val; // set pwm duty
236 #if defined(TCCR4C) && defined(COM4D1)
238 // connect pwm to pin on timer 4, channel D
240 #if defined(COM4D0) // only used on 32U4
243 OCR4D = val; // set pwm duty
248 #if defined(TCCR5A) && defined(COM5A1)
250 // connect pwm to pin on timer 5, channel A
252 OCR5A = val; // set pwm duty
256 #if defined(TCCR5A) && defined(COM5B1)
258 // connect pwm to pin on timer 5, channel B
260 OCR5B = val; // set pwm duty
264 #if defined(TCCR5A) && defined(COM5C1)
266 // connect pwm to pin on timer 5, channel C
268 OCR5C = val; // set pwm duty
275 digitalWrite(pin, LOW);
277 digitalWrite(pin, HIGH);