NXP Semiconductors logo
LPCXpresso Logo

Reply
 
Thread Tools
  #1  
Old 08-11-2011, 03:25 PM
rattus rattus is offline
Junior Member
 
Join Date: May 2011
Location: CO
Posts: 21
rattus is on a distinguished road
Default LPC1769 ADC Read

Hi - I'm having problems reading adc channels other than 0 - they hang in the ADC_ChannelGetStatus loop for channels 1-7; doesn't mater which one. The channels are being initialized identically, I'm making my conversions the same way (and individually - not burst mode), and as far as I can tell, the initialization is being performed correctly.

Code:
        PinCfg.Funcnum = 1;
        PinCfg.OpenDrain = 0;
        PinCfg.Pinmode = 0;
        PinCfg.Pinnum = 23;
        PinCfg.Portnum = 0;
        PINSEL_ConfigPin(&PinCfg);
...etc.

        ADC_Init(LPC_ADC, 1000000);
        ADC_IntConfig(LPC_ADC,ADC_CHANNEL_0,DISABLE);
        ADC_ChannelCmd(LPC_ADC,ADC_CHANNEL_0,ENABLE);
        ADC_IntConfig(LPC_ADC,ADC_CHANNEL_1,DISABLE);
        ADC_ChannelCmd(LPC_ADC,ADC_CHANNEL_1,ENABLE);
        ADC_IntConfig(LPC_ADC,ADC_CHANNEL_2,DISABLE);
        ADC_ChannelCmd(LPC_ADC,ADC_CHANNEL_2,ENABLE);
...etc.

        ADC_StartCmd(LPC_ADC,ADC_START_NOW);
        while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_0,ADC_DATA_DONE)));
        ADC_Val[0] = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_0);
        while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_1,ADC_DATA_DONE)));
        ADC_Val[1] = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_1);
        while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_2,ADC_DATA_DONE)));
        ADC_Val[2] = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_2);
Only the Channel 0 conversion completes. If I comment out the Channel 0 read, Channel 1 hangs on ChannelGetStatus. Same with 2.

I'm obviously missing something here - any ideas?

Thanks,

Mike
Reply With Quote
  #2  
Old 08-11-2011, 03:34 PM
Zero Zero is offline
Senior Member
 
Join Date: Dec 2009
Location: far away
Posts: 2,625
Zero is on a distinguished road
Default

Did you check your Pinsel settings (Debugger: Peripherals View-> PCB) ?

Quote:
ADC_StartCmd(LPC_ADC,ADC_START_NOW);
should do something like:

LPC_ADC->ADCR = START_ADC | OPERATIONAL_ADC | SEL_AD0 ;

that should be stopped after reading AD0 and next channel should be started

Last edited by Zero; 08-11-2011 at 03:45 PM.
Reply With Quote
  #3  
Old 08-11-2011, 03:54 PM
rattus rattus is offline
Junior Member
 
Join Date: May 2011
Location: CO
Posts: 21
rattus is on a distinguished road
Default

Pins 0.23, 24, and 25 are set to AD0.0, 1 and 2, respectively.

I am using the functions in the (pretty sure latest) Lib_MCU...

Code:
void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode)
{
        CHECK_PARAM(PARAM_ADCx(ADCx));
        CHECK_PARAM(PARAM_ADC_START_OPT(start_mode));

        ADCx->ADCR &= ~ADC_CR_START_MASK;
        ADCx->ADCR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode);
}
where

#define ADC_CR_START_MASK ((7UL<<24))

Last edited by rattus; 08-11-2011 at 04:03 PM.
Reply With Quote
  #4  
Old 08-11-2011, 04:01 PM
Zero Zero is offline
Senior Member
 
Join Date: Dec 2009
Location: far away
Posts: 2,625
Zero is on a distinguished road
Default

You can also find a wonderful ADC read polling function in:

In NXP_LPCXpresso1769_MCB1700_2011-02-11.zip\ADC sample

Code:
/*****************************************************************************
** Function name:        ADCRead
**
** Descriptions:        Read ADC channel
**
** parameters:            Channel number
** Returned value:        Value read, if interrupt driven, return channel #
** 
*****************************************************************************/
uint32_t ADCRead( uint8_t channelNum )
{
#if !ADC_INTERRUPT_FLAG
  uint32_t regVal, ADC_Data;
#endif

  /* channel number is 0 through 7 */
  if ( channelNum >= ADC_NUM )
  {
    channelNum = 0;        /* reset channel number to 0 */
  }
  LPC_ADC->CR &= 0xFFFFFF00;
  LPC_ADC->CR |= (1 << 24) | (1 << channelNum);    
                /* switch channel,start A/D convert */
#if !ADC_INTERRUPT_FLAG
  while ( 1 )            /* wait until end of A/D convert */
  {
    regVal = LPC_ADC->DR[channelNum];
    /* read result of A/D conversion */
    if ( regVal & ADC_DONE )
    {
      break;
    }
  }    
        
  LPC_ADC->CR &= 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 */
#else
  return ( channelNum );    /* if it's interrupt driven, the ADC reading is 
                            done inside the handler. so, return channel number */
#endif
}
Anyway, using debugger to read ADC->ADCR register (bit 7:0 = selected AD channel) while your program is hanging will show you which channel is selected

I'm not familiar with the funny example you are using, but I think ADC_ChannelCmd is selecting the channel and therefore has to be called each time before ADC_StartCmd (which just starts the selected channel) is used

Last edited by Zero; 08-11-2011 at 04:20 PM.
Reply With Quote
  #5  
Old 08-11-2011, 04:27 PM
rattus rattus is offline
Junior Member
 
Join Date: May 2011
Location: CO
Posts: 21
rattus is on a distinguished road
Default

Thanks Zero - you obviously have a different header file.

What are the values of ADC_DONE and ADC_OVERRUN?
Reply With Quote
  #6  
Old 08-11-2011, 04:31 PM
Zero Zero is offline
Senior Member
 
Join Date: Dec 2009
Location: far away
Posts: 2,625
Zero is on a distinguished road
Default

Quote:
Originally Posted by rattus View Post
What are the values of ADC_DONE and ADC_OVERRUN?
Described in adc.h:

Code:
#define ADC_DONE            0x80000000
#define ADC_OVERRUN    0x40000000
#define ADC_ADINT           0x00010000
Reply With Quote
  #7  
Old 08-11-2011, 04:55 PM
rattus rattus is offline
Junior Member
 
Join Date: May 2011
Location: CO
Posts: 21
rattus is on a distinguished road
Default

In your header file, yes. in my LPC17xx_adc.h, sadly not...

They're named ADC_DR_DONE_FLAG and ADC_DR_OVERRUN_FLAG in lpc17xx_adc.h

From which distribution are your header files sourced? Mine come out of the Lib_MCU and were authored by NXP.

Thanks, the conversions now work great. As the ADDRs are separate in my lpc17xx.h header, I had to use a switch statement instead of the channelNum array index, but no problem.
Reply With Quote
  #8  
Old 08-11-2011, 05:01 PM
Zero Zero is offline
Senior Member
 
Join Date: Dec 2009
Location: far away
Posts: 2,625
Zero is on a distinguished road
Default

Quote:
Originally Posted by rattus View Post
From which distribution are your header files sourced?
NXP_LPCXpresso1769_MCB1700_2011-02-11.zip\ADC sample
Reply With Quote
  #9  
Old 06-23-2012, 08:14 PM
federoasio federoasio is offline
Junior Member
 
Join Date: Sep 2011
Location: Argentina
Posts: 1
federoasio is on a distinguished road
Default

Hi rattus, I'm having exactly the same problem you did, but I can't undestand how did you fix it. Would you help me please?
Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT +2. The time now is 06:06 PM.