blackbox/driver/adc.c

Thu, 24 Nov 2011 16:04:30 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Thu, 24 Nov 2011 16:04:30 +0100
changeset 17
9e6feafc19e1
parent 7
f4e250d5402b
permissions
-rw-r--r--

added timer0 based car id detection - works only on 50/50 input signal

#include "adc.h"
#include <avr/io.h> 
#include <string.h>
#include <stdint.h>


// Functions to access the internal ADC

// internal ADC reference configuration
static uint8_t adcReference=(1<<REFS0); // = VCC 5V

// get a sample from ADC chip.
// chanell must be in range 0-7.
uint16_t getADC(int channel) {
//    if (channel == 0)
        adcReference = ((1<<REFS1) | (1<<REFS0)); // switch to 2.56V (~2x
        //adcReference = (1<<REFS1); // switch to 1.1v (~4.5x) - not on ATMEGA16
//    else
//        adcReference = (1<<REFS0); // switch to 5v (1x)
    ADMUX = adcReference + channel;
    // start one sample
    ADCSRA |= (1<<ADSC);
    // wait for the result
    loop_until_bit_is_clear(ADCSRA, ADSC);
    return ADC;
}

// initialize the ADC 
void initADC() {
    ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
}

// select reference
// value can be "VCC", "1.1V or "2.56V"
// returns 1 on success
uint8_t setAREF(char* name) {
    if (strcmp(name,"VCC")==0)
        adcReference=(1<<REFS0);
    else if (strcmp(name,"1.1V")==0)
        adcReference=(1<<REFS1);
    else if (strcmp(name,"2.56V")==0)
        adcReference=((1<<REFS1) | (1<<REFS0));
    else if (strcmp(name,"EXT")==0)     
        adcReference=0;                        
    else 
        return 0;
    // Perform one sample to initialize the ADC on the new reference
    ADMUX = adcReference;
    ADCSRA |= (1<<ADSC);
    loop_until_bit_is_clear(ADCSRA, ADSC);
    (ADC);
    return 1;
}

#ifdef EXT_AREF
// get current current voltage
// This assumes that VCC is 5.0 Volt.
float getAREF(void) {
    uint8_t aref=ADMUX & ((1<<REFS1) | (1<<REFS0));
    if (aref == 0)
        return EXT_AREF/1024;        
    else if (aref == (1<<REFS0))
        return 5.00/1024;        
    else if (aref == (1<<REFS1))
        return 1.10/1024;
    else
        return 2.56/1024;
}
#endif


uint16_t getADC_smooth(uint8_t channel, uint8_t samples) {
    uint16_t result = 0;
    unsigned char i;
    for (i=0; i<samples; i++) {
        result += getADC(channel);
    }
    return (result / samples);
};

mercurial