lpcware

LPCXpresso-LPC1769  ADC work not correctly!

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by zad on Thu Dec 12 07:00:14 MST 2013
Hello,

I'm using the LPCXpresso target LPC1769-Board.
My goal is to read 3 inputs voltage via  ADC0.0, ADC0.1 and ADC0.2 Channels in software controlled mode.
When I run the program, It  seems to work well but there are some results that I was not expected.
For example, when the input voltage is 0V.  The adc_count is 0, but some times it is 0xFFF or 0x8EF or another value.
Also  I treid to use Burst mode, but the result was the same result.

My program code is as follows:

(ADC_CLK is 1MHz)

uint32_t ADCInit( uint32_t ADC_Clk )
{
  uint32_t pclkdiv, pclk;

  /* Enable CLOCK into ADC controller */
  LPC_SC->PCONP |= (1 << 12);

  /* all the related pins are set to ADC inputs, AD0.0~2 */

  LPC_PINCON->PINSEL1 &= ~0x000FC000;// P0.23~25, ADC0.0~ADC0.2 function 01
  LPC_PINCON->PINSEL1 |= 0x00054000;

  LPC_PINCON->PINMODE1 &=~(3<<14);
  LPC_PINCON->PINMODE1 |= (2<<14);        // P0.23 has neither pull up nor pull down
  LPC_PINCON->PINMODE1 &=~(3<<16);
  LPC_PINCON->PINMODE1 |= (2<<16);        // P0.24 has neither pull up nor pull down
  LPC_PINCON->PINMODE1 &=~(3<<18);
  LPC_PINCON->PINMODE1 |= (2<<18);        // P0.25 has neither pull up nor pull down

   pclkdiv = (LPC_SC->PCLKSEL0 >> 24) & 0x03;
  switch ( pclkdiv )
  {
case 0x00:
default:
  pclk = SystemCoreClock/4;
break;
case 0x01:
  pclk = SystemCoreClock;
break;
case 0x02:
  pclk = SystemCoreClock/2;
break;
case 0x03:
  pclk = SystemCoreClock/8;
break;
  }


  LPC_ADC->ADCR = ( 0x01 << 0 ) | /* SEL=1,select channel 0 on ADC0 */
( ( (pclk  / ADC_Clk) - 1 ) << 8 ) |  /* CLKDIV = Fpclk / ADC_Clk - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 1 << 21 ) |  /* PDN = 1, normal operation */
( 0 << 24 ) |  /* START = 0 A/D conversion stops */
( 0 << 27 );/* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */

   return (TRUE);
}

uint32_t ADC0Read( uint8_t channelNum )
{

  uint32_t regVal, ADC_Data;


  /* channel number is 0 through 7 */
  if ( channelNum >= ADC_NUM )
  {
channelNum = 0;/* reset channel number to 0 */
  }
  LPC_ADC->ADCR &= 0xFFFFFF00;

  LPC_ADC->ADCR |= (1 << channelNum);
  LPC_ADC->ADCR |= (1 << 24) ;

/* switch channel,start A/D convert */

  while ( 1 )/* wait until end of A/D convert */
  {

regVal = *(volatile unsigned long *)(LPC_ADC_BASE
+ ADC_OFFSET + ADC_INDEX * channelNum);
/* read result of A/D conversion */
if ( regVal & ADC_DONE )
{
  break;
}

  }
       
  LPC_ADC->ADCR &= 0xF8FFFFFF;/* stop ADC now */
  if ( regVal & ADC_OVERRUN )/* save data when it's not overrun, otherwise, return zero */
  {
return ( 0 );
  }

  ADC_Data = ( regVal >> 4 ) & 0xFFF;
  return ( ADC_Data );/* return A/D conversion value */

}

Is there anybody who had the same problem?
Thanks!

Outcomes