lpcware

LPC1768 ADC errors

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by 2394y80 on Tue Nov 19 11:51:43 MST 2013
I have a board using a LPC1768 which interfaces directly to another board.  I have a problem where the AD values start to show errors when the sister board is powered up.  I have isolated the power supply, but it appears that there still is some noise coming down the data lines with affect the ADC output.  I have tried different chokes on the Vdda/Vssa/Vrefp/Vrefn pins without any effect.

The actual ADC routine runs as an interrupt which scans 7 of the AD pins in a loop, but the ADC error rate is the same outside an interrupt, so I have test code as below. Note that I am using the Keil RTX RTOS and Pclk is 100 MHz, and I I have tied the AD pin to a voltage source so that I can detect and quantify how many reads are inaccurate.
LPC_ADC->ADCR = 0; // Power AD down
LPC_SC->PCONP |= (1 << 12); // Enable power to AD block
LPC_SC->PCLKSEL0 &= ~(1<<24); // clock 25 MHz
LPC_SC->PCLKSEL0 &= ~(1<<25);
LPC_ADC->ADCR = 7 << 8; // conversion clock = 100 Mhz / 8 [7+1] = 12.5 MHz
LPC_ADC->ADCR |= (1<<21); // PDN = set AD operational
LPC_ADC->ADCR |= (1<<0); // SEL = select AD0.0 to start

int Good = 1;
int Bad = 0;
while(1)
{
LPC_ADC->ADCR |= (1<<24); // START = start conversion now
while (!(LPC_ADC->ADGDR & ( 1UL << 31)))
;  /* Wait for Conversion end       */
int value = (LPC_ADC->ADDR0 >> 4) & 0xFFF;
if((value < 0x580) || (value > 0x5FF))
Bad++;
else
Good++;
double pct = (double)Bad * 100 / (double)Good;
Debug("AN0 = %X good %5d bad %5d %.02f%%", value, Good , Bad, pct);
os_dly_wait(25);
}

The output of the test code is like this:
AN0 = 5D6 good     2 bad     0 0.00%
AN0 = 5D8 good     3 bad     0 0.00%
AN0 = 5D3 good     4 bad     0 0.00%
AN0 = 5D8 good     5 bad     0 0.00%
AN0 = 5D8 good     6 bad     0 0.00%
AN0 = 5D6 good     7 bad     0 0.00%
AN0 = 3FF good     7 bad     1 14.29%
AN0 = 5D7 good     8 bad     1 12.50%
AN0 = 5D5 good     9 bad     1 11.11%
AN0 = 5D8 good    10 bad     1 10.00%
AN0 = 5D7 good    11 bad     1 9.09%
AN0 = 5D9 good    12 bad     1 8.33%
AN0 = 5D7 good    13 bad     1 7.69%
AN0 = 5D5 good    14 bad     1 7.14%
AN0 = 5D7 good    15 bad     1 6.67%
AN0 = 5D8 good    16 bad     1 6.25%
AN0 = 5D6 good    17 bad     1 5.88%
AN0 = 5D6 good    18 bad     1 5.56%
AN0 = 5D9 good    19 bad     1 5.26%
AN0 = 5D7 good    20 bad     1 5.00%
AN0 = 5D7 good    21 bad     1 4.76%
AN0 = 5D8 good    22 bad     1 4.55%
AN0 = 5D6 good    23 bad     1 4.35%
AN0 = FFF good    23 bad     2 8.70%
AN0 = 5D5 good    24 bad     2 8.33%

Over time the error rate is about 2.8%.  Most of the erroneous values are 0xFFF, 0xDFF or similar, so I believe that the ADC is being glitched from noise.  A slow conversion clock gives more errors - about 4% - so I believe that the slower clock gives the ADC core more chance of glitching.  Setting the pin to pull up or pull down makes no difference.

I don't believe the problem is with the software setup / pin configuration since if I start the debugger and manually set up the ADC registers and then keep firing the START bit I get about the same error rate.

The next step would be to re-design the board to give more isolation, but that is going to take some time, and from what I see may not help much.  Any ideas? 

Outcomes