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
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
25
#include "wiring_private.h"
26
#include "pins_arduino.h"
28
uint8_t analog_reference = DEFAULT;
30
void analogReference(uint8_t mode)
32
// can't actually set the register here because the default setting
33
// will connect AVCC and the AREF pin, which would cause a short if
34
// there's something connected to AREF.
35
analog_reference = mode;
38
int analogRead(uint8_t pin)
42
// set the analog reference (high two bits of ADMUX) and select the
43
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
44
// to 0 (the default).
45
ADMUX = (analog_reference << 6) | (pin & 0x07);
47
#if defined(__AVR_ATmega1280__)
48
// the MUX5 bit of ADCSRB selects whether we're reading from channels
49
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
50
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
53
// without a delay, we seem to read from the wrong channel
56
// start the conversion
59
// ADSC is cleared when the conversion finishes
60
while (bit_is_set(ADCSRA, ADSC));
62
// we have to read ADCL first; doing so locks both ADCL
63
// and ADCH until ADCH is read. reading ADCL second would
64
// cause the results of each conversion to be discarded,
65
// as ADCL and ADCH would be locked when it completed.
69
// combine the two bytes
70
return (high << 8) | low;
73
// Right now, PWM output only works on the pins with
74
// hardware support. These are defined in the appropriate
75
// pins_*.c file. For the rest of the pins, we default
77
void analogWrite(uint8_t pin, int val)
79
// We need to make sure the PWM output is enabled for those pins
80
// that support it, as we turn it off when digitally reading or
81
// writing with them. Also, make sure the pin is in output mode
82
// for consistenty with Wiring, which doesn't require a pinMode
83
// call for the analog output pins.
86
if (digitalPinToTimer(pin) == TIMER1A) {
87
// connect pwm to pin on timer 1, channel A
91
} else if (digitalPinToTimer(pin) == TIMER1B) {
92
// connect pwm to pin on timer 1, channel B
96
#if defined(__AVR_ATmega8__)
97
} else if (digitalPinToTimer(pin) == TIMER2) {
98
// connect pwm to pin on timer 2, channel B
103
} else if (digitalPinToTimer(pin) == TIMER0A) {
105
digitalWrite(pin, LOW);
107
// connect pwm to pin on timer 0, channel A
112
} else if (digitalPinToTimer(pin) == TIMER0B) {
114
digitalWrite(pin, LOW);
116
// connect pwm to pin on timer 0, channel B
121
} else if (digitalPinToTimer(pin) == TIMER2A) {
122
// connect pwm to pin on timer 2, channel A
126
} else if (digitalPinToTimer(pin) == TIMER2B) {
127
// connect pwm to pin on timer 2, channel B
132
#if defined(__AVR_ATmega1280__)
133
// XXX: need to handle other timers here
134
} else if (digitalPinToTimer(pin) == TIMER3A) {
135
// connect pwm to pin on timer 3, channel A
139
} else if (digitalPinToTimer(pin) == TIMER3B) {
140
// connect pwm to pin on timer 3, channel B
144
} else if (digitalPinToTimer(pin) == TIMER3C) {
145
// connect pwm to pin on timer 3, channel C
149
} else if (digitalPinToTimer(pin) == TIMER4A) {
150
// connect pwm to pin on timer 4, channel A
154
} else if (digitalPinToTimer(pin) == TIMER4B) {
155
// connect pwm to pin on timer 4, channel B
159
} else if (digitalPinToTimer(pin) == TIMER4C) {
160
// connect pwm to pin on timer 4, channel C
164
} else if (digitalPinToTimer(pin) == TIMER5A) {
165
// connect pwm to pin on timer 5, channel A
169
} else if (digitalPinToTimer(pin) == TIMER5B) {
170
// connect pwm to pin on timer 5, channel B
175
} else if (val < 128)
176
digitalWrite(pin, LOW);
178
digitalWrite(pin, HIGH);