File content as of revision 0:7c70badd2847:
/* 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++;
}
}