Subversion Repositories HomeAutomation

Rev

Rev 853 | 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. #define BV(x) (1<<(x))
  13.  
  14. // Find a suitable prescaler to get between 75KHz and 150kHz ADC clock
  15. #ifndef ADC_PRESCALER
  16.  #if (F_CPU < 300000)
  17.   #define ADC_PRESCALER 1 // F_CPU/2
  18.  #elif (F_CPU < 600000)
  19.   #define ADC_PRESCALER 2 // F_CPU/4
  20.  #elif (F_CPU < 1200000)
  21.   #define ADC_PRESCALER 3 // F_CPU/8
  22.  #elif (F_CPU < 2400000)
  23.   #define ADC_PRESCALER 4 // F_CPU/16
  24.  #elif (F_CPU < 4800000)
  25.   #define ADC_PRESCALER 5 // F_CPU/32
  26.  #elif (F_CPU < 9600000)
  27.   #define ADC_PRESCALER 6 // F_CPU/64
  28.  #else
  29.   #define ADC_PRESCALER 7 // F_CPU/128
  30.  #endif
  31. #endif
  32.  
  33. /*----------------------------------------------
  34.  * Functions
  35.  * --------------------------------------------*/
  36.  
  37.  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.
  38.  
  39. uint8_t ADC_Init(void)
  40. {
  41.     /* Enable AVcc as Voltage Reference */
  42.     ADMUX |= (1<<REFS0);
  43.     ADMUX &= ~(1<<REFS1);
  44.  
  45.     /* Right adjust the result */
  46.     ADMUX &= ~(1<<ADLAR);
  47.  
  48.     /* Wake up ADC and enable it */
  49.     PRR &= ~(1<<PRADC);
  50.     ADCSRA = (1<<ADEN) | ((ADC_PRESCALER&7)<<ADPS0);
  51.  
  52.     /* Make sure that the next ADC_Get will do an empty measurement first by setting the channel to an impossible value */
  53.     currentChannel = 10;
  54.    
  55.     return 0;
  56. }
  57.  
  58. /*
  59.  * Start reading adc value.
  60.  */
  61. uint16_t ADC_Get(uint8_t channel)
  62. {
  63.     uint16_t adcdata;
  64.    
  65.     if (currentChannel != channel) //Did we use this channel the last time?
  66.     {
  67.         /* Set to 0 all mux registers */
  68.         ADMUX &= ~( BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0) );
  69.         /* Select channel, only first 8 channel modes are supported for now */
  70.         ADMUX |= (channel & 0x07);
  71.        
  72.         currentChannel = channel;   //Update the channel for the last measurement to the one we want this time
  73.         ADC_Get(channel);   //And do a dummy-read
  74.     }
  75.  
  76.     /* Start measurement (takes 13 ADC clock cycles) */
  77.     ADCSRA |= (1<<ADSC);
  78.  
  79.     while( ADCSRA & (1<<ADSC) ){ /* Wait for conversion to complete */ }
  80.  
  81.     /* Get the result and return */
  82.     adcdata = ADCW; //>>2;
  83.  
  84.     return adcdata;
  85.    
  86. }
  87.