wiring_analog.c 7.6 KB

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