This commit is contained in:
Pavol Rusnak 2011-04-08 21:37:51 +02:00
parent 2b9ef9759b
commit f30c462567
2 changed files with 318 additions and 318 deletions

View file

@ -1,274 +1,274 @@
/**************************************************************************** /****************************************************************************
* $Id:: adc.c 3633 2010-06-01 23:03:16Z usb00423 $ * $Id:: adc.c 3633 2010-06-01 23:03:16Z usb00423 $
* Project: NXP LPC13xx ADC example * Project: NXP LPC13xx ADC example
* *
* Description: * Description:
* This file contains ADC code example which include ADC * This file contains ADC code example which include ADC
* initialization, ADC interrupt handler, and APIs for ADC * initialization, ADC interrupt handler, and APIs for ADC
* reading. * reading.
* *
**************************************************************************** ****************************************************************************
* Software that is described herein is for illustrative purposes only * Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the * which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties. * products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the * NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent, * use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors * copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without * reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or * notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified * warranty that such application will be suitable for the specified
* use without further testing or modification. * use without further testing or modification.
****************************************************************************/ ****************************************************************************/
#include "LPC13xx.h" /* LPC13xx Peripheral Registers */ #include "LPC13xx.h" /* LPC13xx Peripheral Registers */
#include "adc.h" #include "adc.h"
volatile uint32_t ADCValue[ADC_NUM]; volatile uint32_t ADCValue[ADC_NUM];
volatile uint32_t ADCIntDone = 0; volatile uint32_t ADCIntDone = 0;
#if BURST_MODE #if BURST_MODE
volatile uint32_t channel_flag; volatile uint32_t channel_flag;
#endif #endif
#if ADC_INTERRUPT_FLAG #if ADC_INTERRUPT_FLAG
/****************************************************************************** /******************************************************************************
** Function name: ADC_IRQHandler ** Function name: ADC_IRQHandler
** **
** Descriptions: ADC interrupt handler ** Descriptions: ADC interrupt handler
** **
** parameters: None ** parameters: None
** Returned value: None ** Returned value: None
** **
******************************************************************************/ ******************************************************************************/
void ADC_IRQHandler (void) void ADC_IRQHandler (void)
{ {
uint32_t regVal; uint32_t regVal;
regVal = LPC_ADC->STAT; /* Read ADC will clear the interrupt */ regVal = LPC_ADC->STAT; /* Read ADC will clear the interrupt */
if ( regVal & 0x0000FF00 ) /* check OVERRUN error first */ if ( regVal & 0x0000FF00 ) /* check OVERRUN error first */
{ {
regVal = (regVal & 0x0000FF00) >> 0x08; regVal = (regVal & 0x0000FF00) >> 0x08;
/* if overrun, just read ADDR to clear */ /* if overrun, just read ADDR to clear */
/* regVal variable has been reused. */ /* regVal variable has been reused. */
switch ( regVal ) switch ( regVal )
{ {
case 0x01: case 0x01:
regVal = LPC_ADC->DR0; regVal = LPC_ADC->DR0;
break; break;
case 0x02: case 0x02:
regVal = LPC_ADC->DR1; regVal = LPC_ADC->DR1;
break; break;
case 0x04: case 0x04:
regVal = LPC_ADC->DR2; regVal = LPC_ADC->DR2;
break; break;
case 0x08: case 0x08:
regVal = LPC_ADC->DR3; regVal = LPC_ADC->DR3;
break; break;
case 0x10: case 0x10:
regVal = LPC_ADC->DR4; regVal = LPC_ADC->DR4;
break; break;
case 0x20: case 0x20:
regVal = LPC_ADC->DR5; regVal = LPC_ADC->DR5;
break; break;
case 0x40: case 0x40:
regVal = LPC_ADC->DR6; regVal = LPC_ADC->DR6;
break; break;
case 0x80: case 0x80:
regVal = LPC_ADC->DR7; regVal = LPC_ADC->DR7;
break; break;
default: default:
break; break;
} }
LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */ LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */
ADCIntDone = 1; ADCIntDone = 1;
return; return;
} }
if ( regVal & ADC_ADINT ) if ( regVal & ADC_ADINT )
{ {
switch ( regVal & 0xFF ) /* check DONE bit */ switch ( regVal & 0xFF ) /* check DONE bit */
{ {
case 0x01: case 0x01:
ADCValue[0] = ( LPC_ADC->DR0 >> 6 ) & 0x3FF; ADCValue[0] = ( LPC_ADC->DR0 >> 6 ) & 0x3FF;
break; break;
case 0x02: case 0x02:
ADCValue[1] = ( LPC_ADC->DR1 >> 6 ) & 0x3FF; ADCValue[1] = ( LPC_ADC->DR1 >> 6 ) & 0x3FF;
break; break;
case 0x04: case 0x04:
ADCValue[2] = ( LPC_ADC->DR2 >> 6 ) & 0x3FF; ADCValue[2] = ( LPC_ADC->DR2 >> 6 ) & 0x3FF;
break; break;
case 0x08: case 0x08:
ADCValue[3] = ( LPC_ADC->DR3 >> 6 ) & 0x3FF; ADCValue[3] = ( LPC_ADC->DR3 >> 6 ) & 0x3FF;
break; break;
case 0x10: case 0x10:
ADCValue[4] = ( LPC_ADC->DR4 >> 6 ) & 0x3FF; ADCValue[4] = ( LPC_ADC->DR4 >> 6 ) & 0x3FF;
break; break;
case 0x20: case 0x20:
ADCValue[5] = ( LPC_ADC->DR5 >> 6 ) & 0x3FF; ADCValue[5] = ( LPC_ADC->DR5 >> 6 ) & 0x3FF;
break; break;
case 0x40: case 0x40:
ADCValue[6] = ( LPC_ADC->DR6 >> 6 ) & 0x3FF; ADCValue[6] = ( LPC_ADC->DR6 >> 6 ) & 0x3FF;
break; break;
case 0x80: case 0x80:
ADCValue[7] = ( LPC_ADC->DR7 >> 6 ) & 0x3FF; ADCValue[7] = ( LPC_ADC->DR7 >> 6 ) & 0x3FF;
break; break;
default: default:
break; break;
} }
#if BURST_MODE #if BURST_MODE
channel_flag |= (regVal & 0xFF); channel_flag |= (regVal & 0xFF);
if ( (channel_flag & 0xFF) == 0xFF ) if ( (channel_flag & 0xFF) == 0xFF )
{ {
/* All the bits in have been set, it indicates all the ADC /* All the bits in have been set, it indicates all the ADC
channels have been converted. */ channels have been converted. */
LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */ LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */
ADCIntDone = 1; ADCIntDone = 1;
} }
#else #else
LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */ LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */
ADCIntDone = 1; ADCIntDone = 1;
#endif #endif
} }
return; return;
} }
#endif #endif
/***************************************************************************** /*****************************************************************************
** Function name: ADCInit ** Function name: ADCInit
** **
** Descriptions: initialize ADC channel ** Descriptions: initialize ADC channel
** **
** parameters: ADC clock rate ** parameters: ADC clock rate
** Returned value: None ** Returned value: None
** **
*****************************************************************************/ *****************************************************************************/
void ADCInit( uint32_t ADC_Clk ) void ADCInit( uint32_t ADC_Clk )
{ {
uint32_t i; uint32_t i;
/* Disable Power down bit to the ADC block. */ /* Disable Power down bit to the ADC block. */
LPC_SYSCON->PDRUNCFG &= ~(0x1<<4); LPC_SYSCON->PDRUNCFG &= ~(0x1<<4);
/* Enable AHB clock to the ADC. */ /* Enable AHB clock to the ADC. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13); LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13);
for ( i = 0; i < ADC_NUM; i++ ) for ( i = 0; i < ADC_NUM; i++ )
{ {
ADCValue[i] = 0x0; ADCValue[i] = 0x0;
} }
/* Unlike some other pings, for ADC test, all the pins need /* Unlike some other pings, for ADC test, all the pins need
to set to analog mode. Bit 7 needs to be cleared according to set to analog mode. Bit 7 needs to be cleared according
to design team. */ to design team. */
LPC_IOCON->PIO0_11 &= ~0x8F; /* ADC I/O config */ LPC_IOCON->PIO0_11 &= ~0x8F; /* ADC I/O config */
LPC_IOCON->PIO0_11 |= 0x02; /* ADC IN0 */ LPC_IOCON->PIO0_11 |= 0x02; /* ADC IN0 */
#ifdef __JTAG_DISABLED #ifdef __JTAG_DISABLED
LPC_IOCON->R_PIO1_0 &= ~0x8F; LPC_IOCON->R_PIO1_0 &= ~0x8F;
LPC_IOCON->R_PIO1_0 |= 0x02; /* ADC IN1 */ LPC_IOCON->R_PIO1_0 |= 0x02; /* ADC IN1 */
LPC_IOCON->R_PIO1_1 &= ~0x8F; LPC_IOCON->R_PIO1_1 &= ~0x8F;
LPC_IOCON->R_PIO1_1 |= 0x02; /* ADC IN2 */ LPC_IOCON->R_PIO1_1 |= 0x02; /* ADC IN2 */
LPC_IOCON->R_PIO1_2 &= ~0x8F; LPC_IOCON->R_PIO1_2 &= ~0x8F;
LPC_IOCON->R_PIO1_2 |= 0x02; /* ADC IN3 */ LPC_IOCON->R_PIO1_2 |= 0x02; /* ADC IN3 */
#ifdef __SWD_DISABLED #ifdef __SWD_DISABLED
LPC_IOCON->SWDIO_PIO1_3 &= ~0x8F; LPC_IOCON->SWDIO_PIO1_3 &= ~0x8F;
LPC_IOCON->SWDIO_PIO1_3 |= 0x02; /* ADC IN4 */ LPC_IOCON->SWDIO_PIO1_3 |= 0x02; /* ADC IN4 */
#endif #endif
#endif #endif
LPC_IOCON->PIO1_4 &= ~0x8F; /* Clear bit7, change to analog mode. */ LPC_IOCON->PIO1_4 &= ~0x8F; /* Clear bit7, change to analog mode. */
LPC_IOCON->PIO1_4 |= 0x01; /* ADC IN5 */ LPC_IOCON->PIO1_4 |= 0x01; /* ADC IN5 */
LPC_IOCON->PIO1_10 &= ~0x8F; /* Clear bit7, change to analog mode. */ LPC_IOCON->PIO1_10 &= ~0x8F; /* Clear bit7, change to analog mode. */
LPC_IOCON->PIO1_10 |= 0x01; /* ADC IN6 */ LPC_IOCON->PIO1_10 |= 0x01; /* ADC IN6 */
LPC_IOCON->PIO1_11 &= ~0x8F; /* Clear bit7, change to analog mode. */ LPC_IOCON->PIO1_11 &= ~0x8F; /* Clear bit7, change to analog mode. */
LPC_IOCON->PIO1_11 |= 0x01; /* ADC IN7 */ LPC_IOCON->PIO1_11 |= 0x01; /* ADC IN7 */
LPC_ADC->CR = ( 0x01 << 0 ) | /* SEL=1,select channel 0~7 on ADC0 */ LPC_ADC->CR = ( 0x01 << 0 ) | /* SEL=1,select channel 0~7 on ADC0 */
(((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/ADC_Clk-1)<<8) | /* CLKDIV = Fpclk / 1000000 - 1 */ (((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/ADC_Clk-1)<<8) | /* CLKDIV = Fpclk / 1000000 - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */ ( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 3 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */ ( 3 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */
( 0 << 24 ) | /* START = 0 A/D conversion stops */ ( 0 << 24 ) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */ ( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */
/* If POLLING, no need to do the following */ /* If POLLING, no need to do the following */
#if ADC_INTERRUPT_FLAG #if ADC_INTERRUPT_FLAG
NVIC_EnableIRQ(ADC_IRQn); NVIC_EnableIRQ(ADC_IRQn);
LPC_ADC->INTEN = 0x1FF; /* Enable all interrupts */ LPC_ADC->INTEN = 0x1FF; /* Enable all interrupts */
#endif #endif
return; return;
} }
/***************************************************************************** /*****************************************************************************
** Function name: ADCRead ** Function name: ADCRead
** **
** Descriptions: Read ADC channel ** Descriptions: Read ADC channel
** **
** parameters: Channel number ** parameters: Channel number
** Returned value: Value read, if interrupt driven, return channel # ** Returned value: Value read, if interrupt driven, return channel #
** **
*****************************************************************************/ *****************************************************************************/
uint32_t ADCRead( uint8_t channelNum ) uint32_t ADCRead( uint8_t channelNum )
{ {
#if !ADC_INTERRUPT_FLAG #if !ADC_INTERRUPT_FLAG
uint32_t regVal, ADC_Data; uint32_t regVal, ADC_Data;
#endif #endif
/* channel number is 0 through 7 */ /* channel number is 0 through 7 */
if ( channelNum >= ADC_NUM ) if ( channelNum >= ADC_NUM )
{ {
channelNum = 0; /* reset channel number to 0 */ channelNum = 0; /* reset channel number to 0 */
} }
LPC_ADC->CR &= 0xFFFFFF00; LPC_ADC->CR &= 0xFFFFFF00;
LPC_ADC->CR |= (1 << 24) | (1 << channelNum); LPC_ADC->CR |= (1 << 24) | (1 << channelNum);
/* switch channel,start A/D convert */ /* switch channel,start A/D convert */
#if !ADC_INTERRUPT_FLAG #if !ADC_INTERRUPT_FLAG
while ( 1 ) /* wait until end of A/D convert */ while ( 1 ) /* wait until end of A/D convert */
{ {
regVal = *(volatile unsigned long *)(LPC_ADC_BASE regVal = *(volatile unsigned long *)(LPC_ADC_BASE
+ ADC_OFFSET + ADC_INDEX * channelNum); + ADC_OFFSET + ADC_INDEX * channelNum);
/* read result of A/D conversion */ /* read result of A/D conversion */
if ( regVal & ADC_DONE ) if ( regVal & ADC_DONE )
{ {
break; break;
} }
} }
LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */ LPC_ADC->CR &= 0xF8FFFFFF; /* stop ADC now */
if ( regVal & ADC_OVERRUN ) /* save data when it's not overrun, otherwise, return zero */ if ( regVal & ADC_OVERRUN ) /* save data when it's not overrun, otherwise, return zero */
{ {
return ( 0 ); return ( 0 );
} }
ADC_Data = ( regVal >> 6 ) & 0x3FF; ADC_Data = ( regVal >> 6 ) & 0x3FF;
return ( ADC_Data ); /* return A/D conversion value */ return ( ADC_Data ); /* return A/D conversion value */
#else #else
return ( channelNum ); /* if it's interrupt driven, the ADC reading is return ( channelNum ); /* if it's interrupt driven, the ADC reading is
done inside the handler. so, return channel number */ done inside the handler. so, return channel number */
#endif #endif
} }
/***************************************************************************** /*****************************************************************************
** Function name: ADC0BurstRead ** Function name: ADC0BurstRead
** **
** Descriptions: Use burst mode to convert multiple channels once. ** Descriptions: Use burst mode to convert multiple channels once.
** **
** parameters: None ** parameters: None
** Returned value: None ** Returned value: None
** **
*****************************************************************************/ *****************************************************************************/
void ADCBurstRead( void ) void ADCBurstRead( void )
{ {
if ( LPC_ADC->CR & (0x7<<24) ) if ( LPC_ADC->CR & (0x7<<24) )
{ {
LPC_ADC->CR &= ~(0x7<<24); LPC_ADC->CR &= ~(0x7<<24);
} }
/* Test channel 5,6,7 using burst mode because they are not shared /* Test channel 5,6,7 using burst mode because they are not shared
with the JTAG pins. */ with the JTAG pins. */
LPC_ADC->CR &= ~0xFF; LPC_ADC->CR &= ~0xFF;
/* Read all channels, 0 through 7. */ /* Read all channels, 0 through 7. */
LPC_ADC->CR |= (0xFF); LPC_ADC->CR |= (0xFF);
LPC_ADC->CR |= (0x1<<16); /* Set burst mode and start A/D convert */ LPC_ADC->CR |= (0x1<<16); /* Set burst mode and start A/D convert */
return; /* the ADC reading is done inside the return; /* the ADC reading is done inside the
handler, return 0. */ handler, return 0. */
} }
/********************************************************************************* /*********************************************************************************
** End Of File ** End Of File
*********************************************************************************/ *********************************************************************************/

View file

@ -1,44 +1,44 @@
/**************************************************************************** /****************************************************************************
* $Id:: adc.h 3633 2010-06-01 23:03:16Z usb00423 $ * $Id:: adc.h 3633 2010-06-01 23:03:16Z usb00423 $
* Project: NXP LPC13xx ADC example * Project: NXP LPC13xx ADC example
* *
* Description: * Description:
* This file contains ADC code header definition. * This file contains ADC code header definition.
* *
**************************************************************************** ****************************************************************************
* Software that is described herein is for illustrative purposes only * Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the * which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties. * products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the * NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent, * use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors * copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without * reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or * notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified * warranty that such application will be suitable for the specified
* use without further testing or modification. * use without further testing or modification.
****************************************************************************/ ****************************************************************************/
#ifndef __ADC_H #ifndef __ADC_H
#define __ADC_H #define __ADC_H
#define ADC_INTERRUPT_FLAG 0 /* 1 is interrupt driven, 0 is polling */ #define ADC_INTERRUPT_FLAG 0 /* 1 is interrupt driven, 0 is polling */
#define BURST_MODE 0 /* Burst mode works in interrupt driven mode only. */ #define BURST_MODE 0 /* Burst mode works in interrupt driven mode only. */
#define ADC_DEBUG 0 #define ADC_DEBUG 0
#define ADC_OFFSET 0x10 #define ADC_OFFSET 0x10
#define ADC_INDEX 4 #define ADC_INDEX 4
#define ADC_DONE 0x80000000 #define ADC_DONE 0x80000000
#define ADC_OVERRUN 0x40000000 #define ADC_OVERRUN 0x40000000
#define ADC_ADINT 0x00010000 #define ADC_ADINT 0x00010000
#define ADC_NUM 8 /* for LPC13xx */ #define ADC_NUM 8 /* for LPC13xx */
#define ADC_CLK 1000000 /* set to 1Mhz */ #define ADC_CLK 1000000 /* set to 1Mhz */
extern void ADC_IRQHandler( void ); extern void ADC_IRQHandler( void );
extern void ADCInit( uint32_t ADC_Clk ); extern void ADCInit( uint32_t ADC_Clk );
extern uint32_t ADCRead( uint8_t channelNum ); extern uint32_t ADCRead( uint8_t channelNum );
extern void ADCBurstRead( void ); extern void ADCBurstRead( void );
#endif /* end __ADC_H */ #endif /* end __ADC_H */
/***************************************************************************** /*****************************************************************************
** End Of File ** End Of File
******************************************************************************/ ******************************************************************************/