/*****************************************************************************
** Function name: ADCInit
**
** Descriptions: initialize ADC channel
**
** parameters: ADC clock rate
** Returned value: None
**
*****************************************************************************/
void ADCInit( uint32_t ADC_Clk )
{
/* Enable CLOCK into ADC controller */
LPC_SC->PCONP |= (1 << 12);
/* all the related pins are set to ADC inputs, AD0.0~7 */
LPC_PINCON->PINSEL0 &= ~0x000000F0; /* P0.2~3, A0.6~7, function 10 */
LPC_PINCON->PINSEL0 |= 0x000000A0;
LPC_PINCON->PINSEL1 &= ~0x003FC000; /* P0.23~26, A0.0~3, function 01 */
LPC_PINCON->PINSEL1 |= 0x00154000;
LPC_PINCON->PINSEL3 |= 0xF0000000; /* P1.30~31, A0.4~5, function 11 */
/* No pull-up no pull-down (function 10) on these ADC pins. */
LPC_PINCON->PINMODE0 &= ~0x000000F0;
LPC_PINCON->PINMODE0 |= 0x000000A0;
LPC_PINCON->PINMODE1 &= ~0x003FC000;
LPC_PINCON->PINMODE1 |= 0x002A8000;
LPC_PINCON->PINMODE3 &= ~0xF0000000;
LPC_PINCON->PINMODE3 |= 0xA0000000;
/* By default, the PCLKSELx value is zero, thus, the PCLK for
all the peripherals is 1/4 of the SystemFrequency. */
/* Bit 24~25 is for ADC */
LPC_ADC->ADCR = ( 0x01 << 0 ) | /* SEL=1,select channel 0~7 on ADC0 */
( ( 25000000 / ADC_Clk - 1 ) << 8 ) | /* CLKDIV = Fpclk / ADC_Clk - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */
( 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;
}
/*****************************************************************************
** Function name: ADCRead
**
** Descriptions: Read ADC channel
**
** parameters: Channel number
** Returned value: Value read
**
*****************************************************************************/
uint32_t ADCRead( uint8_t channelNum )
{
uint32_t regVal, ADC_Data;
/* channel number is 0 through 7 */
LPC_ADC->ADCR &= 0xFFFFFF00;
LPC_ADC->ADCR |= (1 << 24) | (1 << channelNum);
/* switch channel,start A/D convert */
while ( 1 ) /* wait until end of A/D convert */
{
regVal = LPC_ADC->ADGDR;
/* 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 */
}
|