Subversion Repositories HomeAutomation

Rev

Rev 796 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. /*-----------------------------------------------
  3.  * Includes
  4.  * ---------------------------------------------*/
  5. #include <avr/io.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8.  
  9. #include <config.h>
  10. #include "adc.h"
  11. /*----------------------------------------------
  12.  * Functions
  13.  * --------------------------------------------*/
  14.  
  15.  static uint8_t currentChannel; //Used to keep the channel of the last measurement. This is used to determine if the channel needs to be changed.
  16.  
  17. uint8_t ADC_Init(void)
  18. {
  19.     /* Enable AVcc as Voltage Reference */
  20.     ADMUX |= (1<<REFS0);
  21.     ADMUX &= ~(1<<REFS1);
  22.  
  23.     /* Right adjust the result */
  24.     ADMUX &= ~(1<<ADLAR);
  25.  
  26.     /* Wake up ADC and enable it */
  27.     PRR &= ~(1<<PRADC);
  28.     ADCSRA |= (1<<ADEN);
  29.  
  30.     /* Make sure that the next ADC_Get will do an empty measurement first by setting the channel to an impossible value */
  31.     currentChannel = 10;
  32.    
  33.     return 0;
  34. }
  35.  
  36. /*
  37.  * Start reading adc value.
  38.  */
  39. uint16_t ADC_Get(uint8_t channel)
  40. {
  41.     uint16_t adcdata;
  42.    
  43.     if (currentChannel != channel) //Did we use this channel the last time?
  44.     {
  45.         switch(channel)//If not, let's switch the admux
  46.         {
  47. #if ADCHAN0!=0
  48.         case 0:
  49.             /* Enable ADC0 */
  50.             ADMUX &= ~((1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3));
  51.             break;
  52. #endif
  53. #if ADCHAN1!=0
  54.         case 1:
  55.             /* Enable ADC1 */
  56.             ADMUX |= (1<<MUX0);
  57.             ADMUX &= ~((1<<MUX1)|(1<<MUX2)|(1<<MUX3));
  58.             break;
  59. #endif
  60. #if ADCHAN2!=0
  61.         case 2:
  62.             /* Enable ADC2 */
  63.             ADMUX |= (1<<MUX1);
  64.             ADMUX &= ~((1<<MUX0)|(1<<MUX2)|(1<<MUX3));
  65.             break;
  66. #endif
  67. #if ADCHAN3!=0
  68.         case 3:
  69.             /* Enable ADC3 */
  70.             ADMUX |= (1<<MUX0)|(1<<MUX1);
  71.             ADMUX &= ~((1<<MUX2)|(1<<MUX3));
  72.             break;
  73. #endif
  74. #if ADCHAN4!=0
  75.         case 4:
  76.             /* Enable ADC4 */
  77.             ADMUX |= (1<<MUX2);
  78.             ADMUX &= ~((1<<MUX0)|(1<<MUX1)|(1<<MUX3));
  79.             break;
  80. #endif
  81. #if ADCHAN5!=0
  82.         case 5:
  83.             /* Enable ADC5 */
  84.             ADMUX |= (1<<MUX0)|(1<<MUX2);
  85.             ADMUX &= ~((1<<MUX1)|(1<<MUX3));
  86.             break;
  87. #endif
  88. #if ADCHAN6!=0
  89.         case 6:
  90.             /* Enable ADC6 (only for TQFP&MLF package) */
  91.             ADMUX |= (1<<MUX1)|(1<<MUX2);
  92.             ADMUX &= ~((1<<MUX0)|(1<<MUX3));
  93.             break;
  94. #endif
  95. #if ADCHAN7!=0
  96.         case 7:
  97.             /* Enable ADC7 (only for TQFP&MLF package) */
  98.             ADMUX |= (1<<MUX0)|(1<<MUX1)|(1<<MUX2);
  99.             ADMUX &= ~(1<<MUX3);
  100.             break;
  101. #endif
  102.         default:
  103.             break;
  104.             //Some kind of error message?
  105.         }
  106.        
  107.         currentChannel = channel;   //Update the channel for the last measurement to the one we want this time
  108.         ADC_Get(channel);   //And do a dummy-read
  109.     }
  110.  
  111.     /* Start measurement (takes 13 ADC clock cycles) */
  112.     ADCSRA |= (1<<ADSC);
  113.  
  114.     while( ADCSRA & (1<<ADSC) ){ /* Wait for conversion to complete */ }
  115.  
  116.     /* Get the result and return */
  117.     adcdata = ADCW; //>>2;
  118.  
  119.     return adcdata;
  120.    
  121. }
  122.