Bob Anderson
/
AnalogInAnalyzer
Diff: main.cpp
- 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