ADC channel mux speed

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ADC channel mux speed

278 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tweber on Wed Apr 03 05:33:11 MST 2013
I am using CMSIS to get values from internal ADC and I am polling (software control) the ADC.
Using interrupts is not an option.

What is the maximum speed for reading the ADC channels when muxing?

I have to add some nops between the calls of this function to get results.
If I call this function too early, the ChannelGetStatus never returns.

uint32_t foo(uint8_t channel)
{
    ADC_ChannelCmd((LPC_ADC_TypeDef *)LPC_ADC, channel, ENABLE);
       
    /* start integrated ADC */
    ADC_StartCmd((LPC_ADC_TypeDef *)LPC_ADC, ADC_START_NOW);

    /* wait for completion of sampling */
    while (!(ADC_ChannelGetStatus((LPC_ADC_TypeDef *)LPC_ADC, channel, ADC_DATA_DONE)));

    ADC_ChannelCmd((LPC_ADC_TypeDef *)LPC_ADC, channel, DISABLE);

    return ADC_ChannelGetData((LPC_ADC_TypeDef *)LPC_ADC, channel);
}
Labels (1)
0 Kudos
1 Reply

245 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Thu Apr 04 11:06:53 MST 2013
As I understand the user's manual (for the LPC1788), you can have 12-bit conversion rates of 400kHz, which means 2.5usecs...
I have tested the error at a variety of rates, and found that 100kHz gives me the best performance.

(but that's for my board, in my environment - your results will vary)

A very simple piece of software I used during testing is as follows:

<code>
// ------------------------------------------------------------------------------------------- //
// LOCAL PROTOTYPES                                                                            //
// ------------------------------------------------------------------------------------------- //
#define A2D_RATE 100000    // Note:  I tested this at 2Mhz, 1Mhz, 400khz, 100khz, and 10khz...
                           // All function with highest error at 2Mhz - others are pretty equal
                           // Since there's no need for rapid conversion, I selected 100khz



// ------------------------------------------------------------------------------------------- //
// FUNCTION:                                                                                   //
//                                                                                             //
// DESCRIPTION:                                                                                //
// ------------------------------------------------------------------------------------------- //
void Init_A2D( void )
   {
   uint32_t Temp, ControlWord;

   PERIPHERAL_ON( PCADC );                   // Make sure the peripherial I/O is turned on...        
   LPC_IOCON->P0_24 = (1<<1);                // sets P0[24] = A2D_IN                        
   LPC_IOCON->P0_26 &= ~(1<<7);              // resets bit 7 (digital mode)-makes analog mode
   LPC_ADC->CR = 0;

   ControlWord = ((1UL<<21));

   SystemCoreClockUpdate();                  // insure value is up to date for system clock...       

   Temp = A2D_RATE * 31;
   Temp = ( PeripheralClock * 2 + Temp )/( 2 * Temp ) -1;
   ControlWord |= (Temp<<8);
   LPC_ADC->CR = ControlWord;
   }

// ------------------------------------------------------------------------------------------- //
// FUNCTION:                                                                                   //
//                                                                                             //
// DESCRIPTION:                                                                                //
// ------------------------------------------------------------------------------------------- //
uint32_t Read_A2D( uint32_t ChannelNumber )
   {
   uint32_t iTemp = 0;

   LPC_ADC->CR |= (1UL<<ChannelNumber);                     // set channel number...  
   LPC_ADC->CR |= (1UL<<24);                                // start conversion...
   while( !(LPC_ADC->STAT & (1UL<<ChannelNumber)) );        // wait for conversion complete...
   iTemp = *(uint32_t *) ((&LPC_ADC->DR[0])+ChannelNumber);
   iTemp >>= 4;
   return( iTemp & 0x00000FFF );
   }

</code>

You are welcome to give this a try and post your results...
0 Kudos