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

Last change on this file since 46 was 46, checked in by jrpelegrina, 4 years ago

First release to Xenial

File size: 7.5 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        ADMUX = (analog_reference << 6) | (pin & 0x07);
68#endif
69
70        // without a delay, we seem to read from the wrong channel
71        //delay(1);
72
73#if defined(ADCSRA) && defined(ADCL)
74        // start the conversion
75        sbi(ADCSRA, ADSC);
76
77        // ADSC is cleared when the conversion finishes
78        while (bit_is_set(ADCSRA, ADSC));
79
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.
84        low  = ADCL;
85        high = ADCH;
86#else
87        // we dont have an ADC, return 0
88        low  = 0;
89        high = 0;
90#endif
91
92        // combine the two bytes
93        return (high << 8) | low;
94}
95
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
99// to digital output.
100void analogWrite(uint8_t pin, int val)
101{
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);
108        if (val == 0)
109        {
110                digitalWrite(pin, LOW);
111        }
112        else if (val == 255)
113        {
114                digitalWrite(pin, HIGH);
115        }
116        else
117        {
118                switch(digitalPinToTimer(pin))
119                {
120                        // XXX fix needed for atmega8
121                        #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
122                        case TIMER0A:
123                                // connect pwm to pin on timer 0
124                                sbi(TCCR0, COM00);
125                                OCR0 = val; // set pwm duty
126                                break;
127                        #endif
128
129                        #if defined(TCCR0A) && defined(COM0A1)
130                        case TIMER0A:
131                                // connect pwm to pin on timer 0, channel A
132                                sbi(TCCR0A, COM0A1);
133                                OCR0A = val; // set pwm duty
134                                break;
135                        #endif
136
137                        #if defined(TCCR0A) && defined(COM0B1)
138                        case TIMER0B:
139                                // connect pwm to pin on timer 0, channel B
140                                sbi(TCCR0A, COM0B1);
141                                OCR0B = val; // set pwm duty
142                                break;
143                        #endif
144
145                        #if defined(TCCR1A) && defined(COM1A1)
146                        case TIMER1A:
147                                // connect pwm to pin on timer 1, channel A
148                                sbi(TCCR1A, COM1A1);
149                                OCR1A = val; // set pwm duty
150                                break;
151                        #endif
152
153                        #if defined(TCCR1A) && defined(COM1B1)
154                        case TIMER1B:
155                                // connect pwm to pin on timer 1, channel B
156                                sbi(TCCR1A, COM1B1);
157                                OCR1B = val; // set pwm duty
158                                break;
159                        #endif
160
161                        #if defined(TCCR1A) && defined(COM1C1)
162                        case TIMER1C:
163                                // connect pwm to pin on timer 1, channel B
164                                sbi(TCCR1A, COM1C1);
165                                OCR1C = val; // set pwm duty
166                                break;
167                        #endif
168
169                        #if defined(TCCR2) && defined(COM21)
170                        case TIMER2:
171                                // connect pwm to pin on timer 2
172                                sbi(TCCR2, COM21);
173                                OCR2 = val; // set pwm duty
174                                break;
175                        #endif
176
177                        #if defined(TCCR2A) && defined(COM2A1)
178                        case TIMER2A:
179                                // connect pwm to pin on timer 2, channel A
180                                sbi(TCCR2A, COM2A1);
181                                OCR2A = val; // set pwm duty
182                                break;
183                        #endif
184
185                        #if defined(TCCR2A) && defined(COM2B1)
186                        case TIMER2B:
187                                // connect pwm to pin on timer 2, channel B
188                                sbi(TCCR2A, COM2B1);
189                                OCR2B = val; // set pwm duty
190                                break;
191                        #endif
192
193                        #if defined(TCCR3A) && defined(COM3A1)
194                        case TIMER3A:
195                                // connect pwm to pin on timer 3, channel A
196                                sbi(TCCR3A, COM3A1);
197                                OCR3A = val; // set pwm duty
198                                break;
199                        #endif
200
201                        #if defined(TCCR3A) && defined(COM3B1)
202                        case TIMER3B:
203                                // connect pwm to pin on timer 3, channel B
204                                sbi(TCCR3A, COM3B1);
205                                OCR3B = val; // set pwm duty
206                                break;
207                        #endif
208
209                        #if defined(TCCR3A) && defined(COM3C1)
210                        case TIMER3C:
211                                // connect pwm to pin on timer 3, channel C
212                                sbi(TCCR3A, COM3C1);
213                                OCR3C = val; // set pwm duty
214                                break;
215                        #endif
216
217                        #if defined(TCCR4A)
218                        case TIMER4A:
219                                //connect pwm to pin on timer 4, channel A
220                                sbi(TCCR4A, COM4A1);
221                                #if defined(COM4A0)             // only used on 32U4
222                                cbi(TCCR4A, COM4A0);
223                                #endif
224                                OCR4A = val;    // set pwm duty
225                                break;
226                        #endif
227                       
228                        #if defined(TCCR4A) && defined(COM4B1)
229                        case TIMER4B:
230                                // connect pwm to pin on timer 4, channel B
231                                sbi(TCCR4A, COM4B1);
232                                OCR4B = val; // set pwm duty
233                                break;
234                        #endif
235
236                        #if defined(TCCR4A) && defined(COM4C1)
237                        case TIMER4C:
238                                // connect pwm to pin on timer 4, channel C
239                                sbi(TCCR4A, COM4C1);
240                                OCR4C = val; // set pwm duty
241                                break;
242                        #endif
243                               
244                        #if defined(TCCR4C) && defined(COM4D1)
245                        case TIMER4D:                           
246                                // connect pwm to pin on timer 4, channel D
247                                sbi(TCCR4C, COM4D1);
248                                #if defined(COM4D0)             // only used on 32U4
249                                cbi(TCCR4C, COM4D0);
250                                #endif
251                                OCR4D = val;    // set pwm duty
252                                break;
253                        #endif
254
255                                                       
256                        #if defined(TCCR5A) && defined(COM5A1)
257                        case TIMER5A:
258                                // connect pwm to pin on timer 5, channel A
259                                sbi(TCCR5A, COM5A1);
260                                OCR5A = val; // set pwm duty
261                                break;
262                        #endif
263
264                        #if defined(TCCR5A) && defined(COM5B1)
265                        case TIMER5B:
266                                // connect pwm to pin on timer 5, channel B
267                                sbi(TCCR5A, COM5B1);
268                                OCR5B = val; // set pwm duty
269                                break;
270                        #endif
271
272                        #if defined(TCCR5A) && defined(COM5C1)
273                        case TIMER5C:
274                                // connect pwm to pin on timer 5, channel C
275                                sbi(TCCR5A, COM5C1);
276                                OCR5C = val; // set pwm duty
277                                break;
278                        #endif
279
280                        case NOT_ON_TIMER:
281                        default:
282                                if (val < 128) {
283                                        digitalWrite(pin, LOW);
284                                } else {
285                                        digitalWrite(pin, HIGH);
286                                }
287                }
288        }
289}
290
Note: See TracBrowser for help on using the repository browser.