blackbox/driver/adc.c

changeset 0
9b7de464f0ea
child 7
f4e250d5402b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/blackbox/driver/adc.c	Mon Nov 14 20:31:32 2011 +0100
@@ -0,0 +1,79 @@
+#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