source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/arduino/avr/cores/arduino/wiring_analog.c @ 4837

Last change on this file since 4837 was 4837, checked in by daduve, 2 years ago

Adding new version

File size: 7.7 KB
Line 
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
25#include "wiring_private.h"
26#include "pins_arduino.h"
27
28uint8_t analog_reference = DEFAULT;
29
30void analogReference(uint8_t mode)
31{
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;
36}
37
38int analogRead(uint8_t pin)
39{
40        uint8_t low, high;
41
42#if defined(analogPinToChannel)
43#if defined(__AVR_ATmega32U4__)
44        if (pin >= 18) pin -= 18; // allow for channel or pin numbers
45#endif
46        pin = analogPinToChannel(pin);
47#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
48        if (pin >= 54) pin -= 54; // allow for channel or pin numbers
49#elif defined(__AVR_ATmega32U4__)
50        if (pin >= 18) pin -= 18; // allow for channel or pin numbers
51#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
52        if (pin >= 24) pin -= 24; // allow for channel or pin numbers
53#else
54        if (pin >= 14) pin -= 14; // allow for channel or pin numbers
55#endif
56
57#if 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);
61#endif
62 
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).
66#if defined(ADMUX)
67#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
68        ADMUX = (analog_reference << 4) | (pin & 0x07);
69#else
70        ADMUX = (analog_reference << 6) | (pin & 0x07);
71#endif
72#endif
73
74        // without a delay, we seem to read from the wrong channel
75        //delay(1);
76
77#if defined(ADCSRA) && defined(ADCL)
78        // start the conversion
79        sbi(ADCSRA, ADSC);
80
81        // ADSC is cleared when the conversion finishes
82        while (bit_is_set(ADCSRA, ADSC));
83
84        // we have to read ADCL first; doing so locks both ADCL
85        // and ADCH until ADCH is read.  reading ADCL second would
86        // cause the results of each conversion to be discarded,
87        // as ADCL and ADCH would be locked when it completed.
88        low  = ADCL;
89        high = ADCH;
90#else
91        // we dont have an ADC, return 0
92        low  = 0;
93        high = 0;
94#endif
95
96        // combine the two bytes
97        return (high << 8) | low;
98}
99
100// Right now, PWM output only works on the pins with
101// hardware support.  These are defined in the appropriate
102// pins_*.c file.  For the rest of the pins, we default
103// to digital output.
104void analogWrite(uint8_t pin, int val)
105{
106        // We need to make sure the PWM output is enabled for those pins
107        // that support it, as we turn it off when digitally reading or
108        // writing with them.  Also, make sure the pin is in output mode
109        // for consistenty with Wiring, which doesn't require a pinMode
110        // call for the analog output pins.
111        pinMode(pin, OUTPUT);
112        if (val == 0)
113        {
114                digitalWrite(pin, LOW);
115        }
116        else if (val == 255)
117        {
118                digitalWrite(pin, HIGH);
119        }
120        else
121        {
122                switch(digitalPinToTimer(pin))
123                {
124                        // XXX fix needed for atmega8
125                        #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
126                        case TIMER0A:
127                                // connect pwm to pin on timer 0
128                                sbi(TCCR0, COM00);
129                                OCR0 = val; // set pwm duty
130                                break;
131                        #endif
132
133                        #if defined(TCCR0A) && defined(COM0A1)
134                        case TIMER0A:
135                                // connect pwm to pin on timer 0, channel A
136                                sbi(TCCR0A, COM0A1);
137                                OCR0A = val; // set pwm duty
138                                break;
139                        #endif
140
141                        #if defined(TCCR0A) && defined(COM0B1)
142                        case TIMER0B:
143                                // connect pwm to pin on timer 0, channel B
144                                sbi(TCCR0A, COM0B1);
145                                OCR0B = val; // set pwm duty
146                                break;
147                        #endif
148
149                        #if defined(TCCR1A) && defined(COM1A1)
150                        case TIMER1A:
151                                // connect pwm to pin on timer 1, channel A
152                                sbi(TCCR1A, COM1A1);
153                                OCR1A = val; // set pwm duty
154                                break;
155                        #endif
156
157                        #if defined(TCCR1A) && defined(COM1B1)
158                        case TIMER1B:
159                                // connect pwm to pin on timer 1, channel B
160                                sbi(TCCR1A, COM1B1);
161                                OCR1B = val; // set pwm duty
162                                break;
163                        #endif
164
165                        #if defined(TCCR1A) && defined(COM1C1)
166                        case TIMER1C:
167                                // connect pwm to pin on timer 1, channel B
168                                sbi(TCCR1A, COM1C1);
169                                OCR1C = val; // set pwm duty
170                                break;
171                        #endif
172
173                        #if defined(TCCR2) && defined(COM21)
174                        case TIMER2:
175                                // connect pwm to pin on timer 2
176                                sbi(TCCR2, COM21);
177                                OCR2 = val; // set pwm duty
178                                break;
179                        #endif
180
181                        #if defined(TCCR2A) && defined(COM2A1)
182                        case TIMER2A:
183                                // connect pwm to pin on timer 2, channel A
184                                sbi(TCCR2A, COM2A1);
185                                OCR2A = val; // set pwm duty
186                                break;
187                        #endif
188
189                        #if defined(TCCR2A) && defined(COM2B1)
190                        case TIMER2B:
191                                // connect pwm to pin on timer 2, channel B
192                                sbi(TCCR2A, COM2B1);
193                                OCR2B = val; // set pwm duty
194                                break;
195                        #endif
196
197                        #if defined(TCCR3A) && defined(COM3A1)
198                        case TIMER3A:
199                                // connect pwm to pin on timer 3, channel A
200                                sbi(TCCR3A, COM3A1);
201                                OCR3A = val; // set pwm duty
202                                break;
203                        #endif
204
205                        #if defined(TCCR3A) && defined(COM3B1)
206                        case TIMER3B:
207                                // connect pwm to pin on timer 3, channel B
208                                sbi(TCCR3A, COM3B1);
209                                OCR3B = val; // set pwm duty
210                                break;
211                        #endif
212
213                        #if defined(TCCR3A) && defined(COM3C1)
214                        case TIMER3C:
215                                // connect pwm to pin on timer 3, channel C
216                                sbi(TCCR3A, COM3C1);
217                                OCR3C = val; // set pwm duty
218                                break;
219                        #endif
220
221                        #if defined(TCCR4A)
222                        case TIMER4A:
223                                //connect pwm to pin on timer 4, channel A
224                                sbi(TCCR4A, COM4A1);
225                                #if defined(COM4A0)             // only used on 32U4
226                                cbi(TCCR4A, COM4A0);
227                                #endif
228                                OCR4A = val;    // set pwm duty
229                                break;
230                        #endif
231                       
232                        #if defined(TCCR4A) && defined(COM4B1)
233                        case TIMER4B:
234                                // connect pwm to pin on timer 4, channel B
235                                sbi(TCCR4A, COM4B1);
236                                OCR4B = val; // set pwm duty
237                                break;
238                        #endif
239
240                        #if defined(TCCR4A) && defined(COM4C1)
241                        case TIMER4C:
242                                // connect pwm to pin on timer 4, channel C
243                                sbi(TCCR4A, COM4C1);
244                                OCR4C = val; // set pwm duty
245                                break;
246                        #endif
247                               
248                        #if defined(TCCR4C) && defined(COM4D1)
249                        case TIMER4D:                           
250                                // connect pwm to pin on timer 4, channel D
251                                sbi(TCCR4C, COM4D1);
252                                #if defined(COM4D0)             // only used on 32U4
253                                cbi(TCCR4C, COM4D0);
254                                #endif
255                                OCR4D = val;    // set pwm duty
256                                break;
257                        #endif
258
259                                                       
260                        #if defined(TCCR5A) && defined(COM5A1)
261                        case TIMER5A:
262                                // connect pwm to pin on timer 5, channel A
263                                sbi(TCCR5A, COM5A1);
264                                OCR5A = val; // set pwm duty
265                                break;
266                        #endif
267
268                        #if defined(TCCR5A) && defined(COM5B1)
269                        case TIMER5B:
270                                // connect pwm to pin on timer 5, channel B
271                                sbi(TCCR5A, COM5B1);
272                                OCR5B = val; // set pwm duty
273                                break;
274                        #endif
275
276                        #if defined(TCCR5A) && defined(COM5C1)
277                        case TIMER5C:
278                                // connect pwm to pin on timer 5, channel C
279                                sbi(TCCR5A, COM5C1);
280                                OCR5C = val; // set pwm duty
281                                break;
282                        #endif
283
284                        case NOT_ON_TIMER:
285                        default:
286                                if (val < 128) {
287                                        digitalWrite(pin, LOW);
288                                } else {
289                                        digitalWrite(pin, HIGH);
290                                }
291                }
292        }
293}
294
Note: See TracBrowser for help on using the repository browser.