/****************************************************************************

* $Id:: adc.c 6089 2011-01-06 04:38:09Z nxp12832
$
* Project: NXP LPC17xx ADC example
*
* Description:
*
This file contains ADC code example which include ADC
*
initialization, ADC interrupt handler, and APIs for ADC
*
reading.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
****************************************************************************/
#include "lpc17xx.h"
#include "type.h"
#include "adc.h"
#ifndef _BV
#define _BV(_x_) (1UL << (_x_))
#endif
volatile
volatile
volatile
volatile

uint32_t
uint32_t
uint32_t
uint32_t

ADCValue[ADC_NUM];
ADCIntDone = 0;
BurstCounter = 0;
OverRunCounter = 0;

#if BURST_MODE
volatile uint32_t channel_flag = 0;
#endif
#if ADC_INTERRUPT_FLAG
/******************************************************************************
** Function name:
ADC_IRQHandler
**
** Descriptions:
ADC interrupt handler
**
** parameters:
None
** Returned value:
None
**
******************************************************************************/
void ADC_IRQHandler (void)
{
uint32_t regVal;
volatile uint32_t dummy;
int i;
regVal = LPC_ADC->STAT;
/* Read ADC will clear the interrupt */
if ( regVal & 0x0000FF00 )
/* check OVERRUN error first */
{
OverRunCounter++;
for ( i = 0; i < ADC_NUM; i++ )
{

just read ADDR to clear */ /* regVal variable has been reused. i++ ) { if ( regVal & _BV(i) ) { ADCValue[i] = ( LPC_ADC->DR[i] >> 4 ) & 0xFFF. /* stop ADC now */ ADCIntDone = 1. /* if overrun. i < ADC_NUM. } #endif /***************************************************************************** ** Function name: ADCInit ** ** Descriptions: initialize ADC channel ** ** parameters: ADC clock rate ** Returned value: None ** *****************************************************************************/ void ADCInit( uint32_t ADC_Clk ) { uint32_t i. } for ( i = 0. stop ADC now */ channel_flag = 0. pclkdiv. /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12).regVal = (regVal & 0x0000FF00) >> 0x08. } } LPC_ADC->CR &= ~((0x7<<24)|(0x1<<16)). /* stop ADC now. /* Clear BURST mode. */ ADCIntDone = 1. */ if ( regVal & _BV(i) ) { dummy = LPC_ADC->DR[i]. i < ADC_NUM. if ( (channel_flag & 0xFF) == 0xFF ) { /* All the bits in have been set. pclk. i++ ) { ADCValue[i] = 0x0. */ LPC_ADC->CR &= ~(0x1<<16). return. channel_flag |= (regVal & 0xFF). turn off BURST bit. } } #if BURST_MODE BurstCounter++. . } #else LPC_ADC->CR &= ~(0x7<<24). ADCIntDone = 1. for ( i = 0. #endif return. it indicates all the ADC channels have been converted.

1 ) << 8 ) | /* CLKDIV = Fpclk / ADC_Clk ) | /* BURST = 0. } LPC_ADC->CR = ( 0x01 << ( ( pclk . no need to do the following */ #if ADC_INTERRUPT_FLAG NVIC_EnableIRQ(ADC_IRQn). AD0. function 01 */ LPC_PINCON->PINSEL1 |= 0x00154000.trig /* If POLLING. case 0x02: pclk = SystemFrequency/2.select channel 0~7 on ADC0 */ / ADC_Clk . LPC_PINCON->PINMODE0 |= 0x000000A0. /* P0. LPC_PINCON->PINSEL3 |= 0xF0000000. LPC_PINCON->PINMODE3 |= 0xA0000000. break.6~7. */ LPC_PINCON->PINMODE0 &= ~0x000000F0. A0.1 */ ( 0 << 16 led */ ( 0 << 17 ( 1 << 21 ( 0 << 24 ( 0 << 27 ger A/D conversion) */ 0 ) | /* SEL=1.23~26. switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4.} /* all the related pins are set to ADC inputs. thus. the PCLK for all the peripherals is 1/4 of the SystemFrequency. function 10 */ LPC_PINCON->PINSEL0 |= 0x000000A0. normal operation */ START = 0 A/D conversion stops */ EDGE = 0 (CAP/MAT singal falling. the PCLKSELx value is zero. A0. } . break. 11 clocks/10 bits */ PDN = 1. case 0x01: pclk = SystemFrequency. /* Enable all interrupts */ #endif #endif return.30~31.4~5. /* /* /* /* CLKS = 0. break. function 11 */ /* No pull-up no pull-down (function 10) on these ADC pins. software control ) | ) | ) | ). LPC_PINCON->PINSEL1 &= ~0x003FC000. break. /* P0. A0. no BURST. /* By default. */ /* Bit 24~25 is for ADC */ pclkdiv = (LPC_SC->PCLKSEL0 >> 24) & 0x03.0~3.0~7 */ LPC_PINCON->PINSEL0 &= ~0x000000F0.2~3. LPC_PINCON->PINMODE1 &= ~0x003FC000. LPC_PINCON->PINMODE3 &= ~0xF0000000. /* Enable all interrupts */ #else LPC_ADC->INTEN = 0x1FF. LPC_PINCON->PINMODE1 |= 0x002A8000. /* P1. case 0x03: pclk = SystemFrequency/8. #if BURST_MODE LPC_ADC->INTEN = 0xFF.

/***************************************************************************** ** 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. ** ** parameters: None ** Returned value: None ** *****************************************************************************/ . /* switch channel. the ADC reading is done inside the handler. } ADC_Data = ( regVal >> 4 ) & 0xFFF. /* return A/D conversion value */ #else return ( channelNum ). otherwise. return channel number */ #endif } /***************************************************************************** ** Function name: ADC0BurstRead ** ** Descriptions: Use burst mode to convert multiple channels once . ADC_Data. /* stop ADC now */ if ( regVal & ADC_OVERRUN ) /* save data when it's not overrun. r eturn zero */ { return ( 0 ). return ( ADC_Data ). /* read result of A/D conversion */ if ( regVal & ADC_DONE ) { break.start A/D convert */ #if !ADC_INTERRUPT_FLAG while ( 1 ) /* wait until end of A/D convert */ { regVal = LPC_ADC->DR[channelNum]. } } LPC_ADC->CR &= 0xF8FFFFFF. /* if it's interrupt driven. LPC_ADC->CR |= (1 << 24) | (1 << channelNum). so. #endif /* channel number is 0 through 7 */ if ( channelNum >= ADC_NUM ) { channelNum = 0. /* reset channel number to 0 */ } LPC_ADC->CR &= 0xFFFFFF00.

*/ } /******************************************************************************* ** ** End Of File ******************************************************************************** */ . 0 through 7. /* the ADC reading is do ne inside the handler. /* Read all channels. } LPC_ADC->CR &= ~0xFF.void ADCBurstRead( void ) { /* Start bits need to be zero before BURST mode can be set. LPC_ADC->CR |= (0x1<<16). /* Set burst mode and start A/D convert */ return. */ LPC_ADC->CR |= 0xFF. return 0. */ if ( LPC_ADC->CR & (0x7<<24) ) { LPC_ADC->CR &= ~(0x7<<24).