User | Revision | Line number | New contents of line |
bobanderson |
0:7c70badd2847
|
1
|
/* Bob Anderson (bob.anderson.ok@gmail.com)
|
bobanderson |
0:7c70badd2847
|
2
|
|
bobanderson |
0:7c70badd2847
|
3
|
This program...
|
bobanderson |
0:7c70badd2847
|
4
|
|
bobanderson |
0:7c70badd2847
|
5
|
1) Uses AnalogIn but speeds it up by setting
|
bobanderson |
0:7c70badd2847
|
6
|
the ADC clock to 12MHz (13MHz is max from spec sheet)
|
bobanderson |
0:7c70badd2847
|
7
|
|
bobanderson |
0:7c70badd2847
|
8
|
2) Produces a histogram of deviations around a center
|
bobanderson |
0:7c70badd2847
|
9
|
value that is determined at the beginning of a run
|
bobanderson |
0:7c70badd2847
|
10
|
by a "vote" taken from three successive readings.
|
bobanderson |
0:7c70badd2847
|
11
|
|
bobanderson |
0:7c70badd2847
|
12
|
3) Introduces a "glitch" suppression method that appears
|
bobanderson |
0:7c70badd2847
|
13
|
to be effective.
|
bobanderson |
0:7c70badd2847
|
14
|
|
bobanderson |
0:7c70badd2847
|
15
|
With a 100nf capacitor from the analog pin to ground and
|
bobanderson |
0:7c70badd2847
|
16
|
a reasonably low impedance source ( < 5K ) and glitch suppression
|
bobanderson |
0:7c70badd2847
|
17
|
enabled, the LPC1768/9 onboard analog to digital converter subsystem
|
bobanderson |
0:7c70badd2847
|
18
|
becomes quite useable. Without the capacitor and glitch suppression,
|
bobanderson |
0:7c70badd2847
|
19
|
it is not a reliable ADC --- it is glitch prone, even with the
|
bobanderson |
0:7c70badd2847
|
20
|
cleanest of inputs. This program will help you determine for
|
bobanderson |
0:7c70badd2847
|
21
|
yourself whether that statement is true. Play with it.
|
bobanderson |
0:7c70badd2847
|
22
|
|
bobanderson |
0:7c70badd2847
|
23
|
*/
|
bobanderson |
0:7c70badd2847
|
24
|
|
bobanderson |
0:7c70badd2847
|
25
|
#include "mbed.h"
|
bobanderson |
0:7c70badd2847
|
26
|
#include "Serial.h"
|
bobanderson |
0:7c70badd2847
|
27
|
#include "AnalogIn.h"
|
bobanderson |
0:7c70badd2847
|
28
|
|
bobanderson |
0:7c70badd2847
|
29
|
Serial pc( USBTX, USBRX );
|
bobanderson |
0:7c70badd2847
|
30
|
|
bobanderson |
0:7c70badd2847
|
31
|
AnalogIn ain( p20 );
|
bobanderson |
0:7c70badd2847
|
32
|
|
bobanderson |
0:7c70badd2847
|
33
|
#define NUM_SAMPLES 1000000
|
bobanderson |
0:7c70badd2847
|
34
|
#define HGRAM_MAX_INDEX 60
|
bobanderson |
0:7c70badd2847
|
35
|
int histoGram[ HGRAM_MAX_INDEX + 1 ];
|
bobanderson |
0:7c70badd2847
|
36
|
|
bobanderson |
0:7c70badd2847
|
37
|
int glitchCount = 0;
|
bobanderson |
0:7c70badd2847
|
38
|
bool glitchSuppressionWanted = false;
|
bobanderson |
0:7c70badd2847
|
39
|
|
bobanderson |
0:7c70badd2847
|
40
|
void setADCclockToMaxConversionRate(void);
|
bobanderson |
0:7c70badd2847
|
41
|
int glitchSuppressedAnalogIn( void );
|
bobanderson |
0:7c70badd2847
|
42
|
|
bobanderson |
0:7c70badd2847
|
43
|
int max( int a, int b ) {
|
bobanderson |
0:7c70badd2847
|
44
|
if ( a > b ) return a;
|
bobanderson |
0:7c70badd2847
|
45
|
return b;
|
bobanderson |
0:7c70badd2847
|
46
|
}
|
bobanderson |
0:7c70badd2847
|
47
|
|
bobanderson |
0:7c70badd2847
|
48
|
int min( int a, int b ) {
|
bobanderson |
0:7c70badd2847
|
49
|
if ( a < b ) return a;
|
bobanderson |
0:7c70badd2847
|
50
|
return b;
|
bobanderson |
0:7c70badd2847
|
51
|
}
|
bobanderson |
0:7c70badd2847
|
52
|
|
bobanderson |
0:7c70badd2847
|
53
|
// middle( a, b, c ) returns true if a is between b and c
|
bobanderson |
0:7c70badd2847
|
54
|
bool middle( int a, int b, int c ) {
|
bobanderson |
0:7c70badd2847
|
55
|
return (a <= max(b,c)) && (a >= min(b,c));
|
bobanderson |
0:7c70badd2847
|
56
|
}
|
bobanderson |
0:7c70badd2847
|
57
|
|
bobanderson |
0:7c70badd2847
|
58
|
int main() {
|
bobanderson |
0:7c70badd2847
|
59
|
|
bobanderson |
0:7c70badd2847
|
60
|
int referenceValue;
|
bobanderson |
0:7c70badd2847
|
61
|
int delta;
|
bobanderson |
0:7c70badd2847
|
62
|
int newValue;
|
bobanderson |
0:7c70badd2847
|
63
|
|
bobanderson |
0:7c70badd2847
|
64
|
// Speedup the AnalogIn conversion rate by readjusting
|
bobanderson |
0:7c70badd2847
|
65
|
// the ADC clock to 12 MHz (assuming SystemCoreClock = 96MHz)
|
bobanderson |
0:7c70badd2847
|
66
|
setADCclockToMaxConversionRate();
|
bobanderson |
0:7c70badd2847
|
67
|
|
bobanderson |
0:7c70badd2847
|
68
|
while(1) {
|
bobanderson |
0:7c70badd2847
|
69
|
|
bobanderson |
0:7c70badd2847
|
70
|
printf( "\nPress the s key to start stats gathering\n" );
|
bobanderson |
0:7c70badd2847
|
71
|
printf( "Press the g key to toggle glitch suppression...\n" );
|
bobanderson |
0:7c70badd2847
|
72
|
bool waitingForKeyInput = true;
|
bobanderson |
0:7c70badd2847
|
73
|
|
bobanderson |
0:7c70badd2847
|
74
|
while ( waitingForKeyInput ){
|
bobanderson |
0:7c70badd2847
|
75
|
switch (pc.getc()) {
|
bobanderson |
0:7c70badd2847
|
76
|
case 'g':
|
bobanderson |
0:7c70badd2847
|
77
|
case 'G':
|
bobanderson |
0:7c70badd2847
|
78
|
glitchSuppressionWanted = ! glitchSuppressionWanted;
|
bobanderson |
0:7c70badd2847
|
79
|
if ( glitchSuppressionWanted )
|
bobanderson |
0:7c70badd2847
|
80
|
printf( "...glitch suppression on...\n" );
|
bobanderson |
0:7c70badd2847
|
81
|
else
|
bobanderson |
0:7c70badd2847
|
82
|
printf( "...glitch suppression off...\n" );
|
bobanderson |
0:7c70badd2847
|
83
|
break;
|
bobanderson |
0:7c70badd2847
|
84
|
case 's':
|
bobanderson |
0:7c70badd2847
|
85
|
case 'S': waitingForKeyInput = false;
|
bobanderson |
0:7c70badd2847
|
86
|
}
|
bobanderson |
0:7c70badd2847
|
87
|
}
|
bobanderson |
0:7c70badd2847
|
88
|
|
bobanderson |
0:7c70badd2847
|
89
|
// Establish center point for histogram by taking three readings
|
bobanderson |
0:7c70badd2847
|
90
|
// and selecting the one in the middle as the reference value around
|
bobanderson |
0:7c70badd2847
|
91
|
// which deviations will be calculated.
|
bobanderson |
0:7c70badd2847
|
92
|
int value1 = ain.read_u16() >> 4;
|
bobanderson |
0:7c70badd2847
|
93
|
int value2 = ain.read_u16() >> 4;
|
bobanderson |
0:7c70badd2847
|
94
|
int value3 = ain.read_u16() >> 4;
|
bobanderson |
0:7c70badd2847
|
95
|
|
bobanderson |
0:7c70badd2847
|
96
|
if ( middle(value1,value2,value3) )
|
bobanderson |
0:7c70badd2847
|
97
|
referenceValue = value1;
|
bobanderson |
0:7c70badd2847
|
98
|
else if ( middle(value2,value1,value3) )
|
bobanderson |
0:7c70badd2847
|
99
|
referenceValue = value2;
|
bobanderson |
0:7c70badd2847
|
100
|
else
|
bobanderson |
0:7c70badd2847
|
101
|
referenceValue = value3;
|
bobanderson |
0:7c70badd2847
|
102
|
|
bobanderson |
0:7c70badd2847
|
103
|
printf( "\nreferenceValue: %d value1: %d value2: %d value3: %d\n",
|
bobanderson |
0:7c70badd2847
|
104
|
referenceValue, value1, value2, value3 );
|
bobanderson |
0:7c70badd2847
|
105
|
printf( "\n...now gathering...\n\n" );
|
bobanderson |
0:7c70badd2847
|
106
|
|
bobanderson |
0:7c70badd2847
|
107
|
// Clear the histogram array.
|
bobanderson |
0:7c70badd2847
|
108
|
for ( int k = 0; k <= HGRAM_MAX_INDEX; k++ ) histoGram[k] = 0;
|
bobanderson |
0:7c70badd2847
|
109
|
|
bobanderson |
0:7c70badd2847
|
110
|
glitchCount = 0;
|
bobanderson |
0:7c70badd2847
|
111
|
|
bobanderson |
0:7c70badd2847
|
112
|
for ( int i = 0; i < NUM_SAMPLES; i++ ) {
|
bobanderson |
0:7c70badd2847
|
113
|
newValue = glitchSuppressedAnalogIn();
|
bobanderson |
0:7c70badd2847
|
114
|
delta = newValue - referenceValue + (HGRAM_MAX_INDEX / 2);
|
bobanderson |
0:7c70badd2847
|
115
|
if ( delta < 0 ) histoGram[0]++;
|
bobanderson |
0:7c70badd2847
|
116
|
else if ( delta > HGRAM_MAX_INDEX ) histoGram[HGRAM_MAX_INDEX]++;
|
bobanderson |
0:7c70badd2847
|
117
|
else histoGram[delta]++;
|
bobanderson |
0:7c70badd2847
|
118
|
}
|
bobanderson |
0:7c70badd2847
|
119
|
|
bobanderson |
0:7c70badd2847
|
120
|
// Output histoGram
|
bobanderson |
0:7c70badd2847
|
121
|
for ( int j = 0; j <= HGRAM_MAX_INDEX; j++ ) {
|
bobanderson |
0:7c70badd2847
|
122
|
printf( "%4d %8d\n", j, histoGram[j] );
|
bobanderson |
0:7c70badd2847
|
123
|
}
|
bobanderson |
0:7c70badd2847
|
124
|
|
bobanderson |
0:7c70badd2847
|
125
|
printf( "glitchCount: %d\n", glitchCount );
|
bobanderson |
0:7c70badd2847
|
126
|
}
|
bobanderson |
0:7c70badd2847
|
127
|
}
|
bobanderson |
0:7c70badd2847
|
128
|
|
bobanderson |
0:7c70badd2847
|
129
|
void setADCclockToMaxConversionRate(void) {
|
bobanderson |
0:7c70badd2847
|
130
|
// Set pclk = cclk / 4 (pclk = 96Mhz/4 = 24Mhz)
|
bobanderson |
0:7c70badd2847
|
131
|
LPC_SC->PCLKSEL0 &= ~(0x3 << 24); // Clear bits 25:24
|
bobanderson |
0:7c70badd2847
|
132
|
|
bobanderson |
0:7c70badd2847
|
133
|
// software-controlled ADC settings
|
bobanderson |
0:7c70badd2847
|
134
|
LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected
|
bobanderson |
0:7c70badd2847
|
135
|
| (1 << 8 ) // CLKDIV: ADCCLK = PCLK / (CLKDIV + 1) (12MHz)
|
bobanderson |
0:7c70badd2847
|
136
|
| (0 << 16) // BURST: 0 = software control
|
bobanderson |
0:7c70badd2847
|
137
|
| (0 << 17) // CLKS: not applicable
|
bobanderson |
0:7c70badd2847
|
138
|
| (1 << 21) // PDN: 1 = operational
|
bobanderson |
0:7c70badd2847
|
139
|
| (0 << 24) // START: 0 = no start
|
bobanderson |
0:7c70badd2847
|
140
|
| (0 << 27); // EDGE: not applicable}
|
bobanderson |
0:7c70badd2847
|
141
|
return;
|
bobanderson |
0:7c70badd2847
|
142
|
}
|
bobanderson |
0:7c70badd2847
|
143
|
|
bobanderson |
0:7c70badd2847
|
144
|
int glitchSuppressedAnalogIn( void ) {
|
bobanderson |
0:7c70badd2847
|
145
|
int v1,v2,delta;
|
bobanderson |
0:7c70badd2847
|
146
|
|
bobanderson |
0:7c70badd2847
|
147
|
v1 = ain.read_u16() >> 4;
|
bobanderson |
0:7c70badd2847
|
148
|
if ( ! glitchSuppressionWanted ) return v1;
|
bobanderson |
0:7c70badd2847
|
149
|
|
bobanderson |
0:7c70badd2847
|
150
|
// While this has the possiblity of never returning,
|
bobanderson |
0:7c70badd2847
|
151
|
// the probability of that is vanishingly small. We assume
|
bobanderson |
0:7c70badd2847
|
152
|
// that we will eventually find two successive readings that are
|
bobanderson |
0:7c70badd2847
|
153
|
// within the tolerance band --- i.e., no glitch
|
bobanderson |
0:7c70badd2847
|
154
|
while(1){
|
bobanderson |
0:7c70badd2847
|
155
|
v2 = ain.read_u16() >> 4;
|
bobanderson |
0:7c70badd2847
|
156
|
delta = v1 - v2;
|
bobanderson |
0:7c70badd2847
|
157
|
if ( (delta > -10) && (delta < 10)) return (v1+v2)/2;
|
bobanderson |
0:7c70badd2847
|
158
|
v1 = v2;
|
bobanderson |
0:7c70badd2847
|
159
|
glitchCount++;
|
bobanderson |
0:7c70badd2847
|
160
|
}
|
bobanderson |
0:7c70badd2847
|
161
|
} |