This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC1768 ADC instability!!!

Hello everyone,
I'm developing software for embedded systems for medical supposes. In my latest project, I need to read the ADC value for 6 channels of LPC1768 ADC unit.
I'm having some problems though. The ADC gives me some random conversions even when I connect the ADC pin to ground.
Here is my code:
#include <LPC17xx.H>
#include "ClockConfig.h"
#include <lpc17xx_pinsel.h>
#include <lpc17xx_adc.h>

void ignore(void);
void ADC_IRQHandler(void);

double percent = 0;
double error = 0;
double count = 0;

int result0 = 0;
int previousResult0 = 0;
int result1 = 0;
int result2 = 0;
int result3 = 0;
int result4 = 0;
int result5 = 0;

int main()
{ SetCoreClock();

PINSEL_SetPinFunc(PINSEL_PORT_0, PINSEL_PIN_23, PINSEL_FUNC_1); PINSEL_SetPinFunc(PINSEL_PORT_0, PINSEL_PIN_24, PINSEL_FUNC_1); PINSEL_SetPinFunc(PINSEL_PORT_0, PINSEL_PIN_25, PINSEL_FUNC_1); PINSEL_SetPinFunc(PINSEL_PORT_0, PINSEL_PIN_26, PINSEL_FUNC_1); PINSEL_SetPinFunc(PINSEL_PORT_1, PINSEL_PIN_30, PINSEL_FUNC_3); PINSEL_SetPinFunc(PINSEL_PORT_1, PINSEL_PIN_31, PINSEL_FUNC_3);

PINSEL_SetResistorMode(PINSEL_PORT_0, PINSEL_PIN_23,PINSEL_PINMODE_TRISTATE); PINSEL_SetResistorMode(PINSEL_PORT_0, PINSEL_PIN_24,PINSEL_PINMODE_TRISTATE); PINSEL_SetResistorMode(PINSEL_PORT_0, PINSEL_PIN_25,PINSEL_PINMODE_TRISTATE); PINSEL_SetResistorMode(PINSEL_PORT_0, PINSEL_PIN_26,PINSEL_PINMODE_TRISTATE); PINSEL_SetResistorMode(PINSEL_PORT_1, PINSEL_PIN_30,PINSEL_PINMODE_TRISTATE); PINSEL_SetResistorMode(PINSEL_PORT_1, PINSEL_PIN_31,PINSEL_PINMODE_TRISTATE);

ADC_Init(LPC_ADC, 5000); ADC_ChannelCmd(LPC_ADC,0,ENABLE); ADC_ChannelCmd(LPC_ADC,1,ENABLE); ADC_ChannelCmd(LPC_ADC,2,ENABLE); ADC_ChannelCmd(LPC_ADC,3,ENABLE); ADC_ChannelCmd(LPC_ADC,4,ENABLE); ADC_ChannelCmd(LPC_ADC,5,ENABLE);

ADC_IntConfig(LPC_ADC, ADC_ADINTEN0, ENABLE); ADC_IntConfig(LPC_ADC, ADC_ADINTEN1, ENABLE); ADC_IntConfig(LPC_ADC, ADC_ADINTEN2, ENABLE); ADC_IntConfig(LPC_ADC, ADC_ADINTEN3, ENABLE); ADC_IntConfig(LPC_ADC, ADC_ADINTEN4, ENABLE); ADC_IntConfig(LPC_ADC, ADC_ADINTEN5, ENABLE);

NVIC_EnableIRQ(ADC_IRQn); ADC_BurstCmd(LPC_ADC, ENABLE);

while (1);
}

void ADC_IRQHandler()
{ if (ADC_ChannelGetStatus(LPC_ADC, ADC_CHANNEL_0, ENABLE)) { count ++; previousResult0 = result0; result0 = ADC_ChannelGetData(LPC_ADC, ADC_CHANNEL_0);

if (result0>0) error++;

percent = error/ count; }

if (ADC_ChannelGetStatus(LPC_ADC, ADC_CHANNEL_1, ENABLE)) result1 = ADC_ChannelGetData(LPC_ADC, ADC_CHANNEL_1);

if (ADC_ChannelGetStatus(LPC_ADC, ADC_CHANNEL_2, ENABLE)) result2 = ADC_ChannelGetData(LPC_ADC, ADC_CHANNEL_2);

if (ADC_ChannelGetStatus(LPC_ADC, ADC_CHANNEL_3, ENABLE)) result3 = ADC_ChannelGetData(LPC_ADC, ADC_CHANNEL_3);

if (ADC_ChannelGetStatus(LPC_ADC, ADC_CHANNEL_4, ENABLE)) result4 = ADC_ChannelGetData(LPC_ADC, ADC_CHANNEL_4);

if (ADC_ChannelGetStatus(LPC_ADC, ADC_CHANNEL_5, ENABLE)) result5 = ADC_ChannelGetData(LPC_ADC, ADC_CHANNEL_5);
}

when I connect P0.23 (AD0.0 to ground, I expect the result to be zero. but ADC gives me values distributed over 0-4095 range.) This is very strange that the ADC reads 3.3 volts even when it is connected to the ground. this happens 0.5% of all conversion. for 99.5% of conversions the result is 0 as one would expect.

Thanks in advance for your help

Parents
  • I'm not sure why you would get values all over the range.

    But you can get non-zero values because ground isn't always zero in all parts of a circuit. So a test != 0 is too strict when you look for errors.

    Another thing - you have an ISR that updates variables. If you want your main loop to make use of these variables then you should use the 'volatile' keyword. You must always use that keyword when there are asynchronous updates to variables, i.e. when multiple threads or ISR+main loop interacts with the same variable.

Reply
  • I'm not sure why you would get values all over the range.

    But you can get non-zero values because ground isn't always zero in all parts of a circuit. So a test != 0 is too strict when you look for errors.

    Another thing - you have an ISR that updates variables. If you want your main loop to make use of these variables then you should use the 'volatile' keyword. You must always use that keyword when there are asynchronous updates to variables, i.e. when multiple threads or ISR+main loop interacts with the same variable.

Children