Dependencies:   mbed

Revision:
0:7c70badd2847
Child:
1:ecca38babc13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Feb 16 23:20:42 2011 +0000
@@ -0,0 +1,161 @@
+/*  Bob Anderson   (bob.anderson.ok@gmail.com)
+
+This program...
+
+   1) Uses AnalogIn but speeds it up by setting
+      the ADC clock to 12MHz (13MHz is max from spec sheet)
+      
+   2) Produces a histogram of deviations around a center
+      value that is determined at the beginning of a run
+      by a "vote" taken from three successive readings.
+      
+   3) Introduces a "glitch" suppression method that appears
+      to be effective.
+      
+With a 100nf capacitor from the analog pin to ground and
+a reasonably low impedance source ( < 5K ) and glitch suppression
+enabled, the LPC1768/9 onboard analog to digital converter subsystem
+becomes quite useable.  Without the capacitor and glitch suppression,
+it is not a reliable ADC --- it is glitch prone, even with the
+cleanest of inputs.  This program will help you determine for
+yourself whether that statement is true.  Play with it.
+
+*/
+
+#include "mbed.h"
+#include "Serial.h"
+#include "AnalogIn.h"
+
+Serial pc( USBTX, USBRX );
+
+AnalogIn ain( p20 );
+
+#define NUM_SAMPLES 1000000
+#define HGRAM_MAX_INDEX 60
+int histoGram[ HGRAM_MAX_INDEX + 1 ];
+
+int glitchCount = 0;
+bool glitchSuppressionWanted = false;
+
+void setADCclockToMaxConversionRate(void);
+int glitchSuppressedAnalogIn( void );
+
+int max( int a, int b ) {
+    if ( a > b ) return a;
+    return b;
+}
+
+int min( int a, int b ) {
+    if ( a < b ) return a;
+    return b;
+}
+
+// middle( a, b, c ) returns true if a is between b and c
+bool middle( int a, int b, int c ) {
+    return (a <= max(b,c)) && (a >= min(b,c));
+}
+
+int main() {
+
+    int referenceValue;
+    int delta;
+    int newValue;
+    
+    // Speedup the AnalogIn conversion rate by readjusting
+    // the ADC clock to 12 MHz (assuming SystemCoreClock = 96MHz)
+    setADCclockToMaxConversionRate();
+    
+    while(1) {
+    
+        printf( "\nPress the s key to start stats gathering\n" );
+        printf( "Press the g key to toggle glitch suppression...\n" );
+        bool waitingForKeyInput = true;
+        
+        while ( waitingForKeyInput ){
+            switch (pc.getc()) {
+              case 'g':
+              case 'G': 
+                glitchSuppressionWanted = ! glitchSuppressionWanted;
+                if ( glitchSuppressionWanted )
+                  printf( "...glitch suppression on...\n" );
+                else
+                  printf( "...glitch suppression off...\n" );
+                break;
+              case 's':
+              case 'S': waitingForKeyInput = false;
+            }
+        }
+        
+        // Establish center point for histogram by taking three readings
+        // and selecting the one in the middle as the reference value around
+        // which deviations will be calculated.
+        int value1 = ain.read_u16() >> 4;
+        int value2 = ain.read_u16() >> 4;
+        int value3 = ain.read_u16() >> 4;
+   
+        if ( middle(value1,value2,value3) ) 
+            referenceValue = value1;
+        else if ( middle(value2,value1,value3) )
+            referenceValue = value2;
+        else
+            referenceValue = value3;
+    
+        printf( "\nreferenceValue: %d   value1: %d   value2: %d   value3: %d\n",
+            referenceValue, value1, value2, value3 );
+        printf( "\n...now gathering...\n\n" );
+             
+        // Clear the histogram array.
+        for ( int k = 0; k <= HGRAM_MAX_INDEX; k++ ) histoGram[k] = 0;
+        
+        glitchCount = 0;
+             
+        for ( int i = 0; i < NUM_SAMPLES; i++ ) {
+            newValue = glitchSuppressedAnalogIn();
+            delta = newValue - referenceValue + (HGRAM_MAX_INDEX / 2);
+            if ( delta < 0 ) histoGram[0]++;
+            else if ( delta > HGRAM_MAX_INDEX ) histoGram[HGRAM_MAX_INDEX]++;
+            else histoGram[delta]++;
+        }
+        
+        // Output histoGram
+        for ( int j = 0; j <= HGRAM_MAX_INDEX; j++ ) {
+            printf( "%4d %8d\n", j, histoGram[j] );
+        }
+        
+        printf( "glitchCount: %d\n", glitchCount );
+    }
+}
+
+void setADCclockToMaxConversionRate(void) {
+    // Set pclk = cclk / 4  (pclk = 96Mhz/4 = 24Mhz)
+    LPC_SC->PCLKSEL0 &= ~(0x3 << 24); // Clear bits 25:24   
+        
+    // software-controlled ADC settings
+    LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected
+              | (1 << 8 )    // CLKDIV: ADCCLK = PCLK / (CLKDIV + 1) (12MHz)
+              | (0 << 16)    // BURST: 0 = software control 
+              | (0 << 17)    // CLKS: not applicable 
+              | (1 << 21)    // PDN: 1 = operational
+              | (0 << 24)    // START: 0 = no start
+              | (0 << 27);   // EDGE: not applicable}
+    return;
+}
+
+int glitchSuppressedAnalogIn( void ) {
+    int v1,v2,delta;
+    
+    v1 = ain.read_u16() >> 4;
+    if ( ! glitchSuppressionWanted ) return v1;
+    
+    // While this has the possiblity of never returning,
+    // the probability of that is vanishingly small.  We assume
+    // that we will eventually find two successive readings that are
+    // within the tolerance band --- i.e., no glitch
+    while(1){
+        v2 = ain.read_u16() >> 4;
+        delta = v1 - v2;
+        if ( (delta > -10) && (delta < 10)) return (v1+v2)/2;
+        v1 = v2;
+        glitchCount++;
+    }
+}
\ No newline at end of file