LPC1769 ADC code

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

LPC1769 ADC code

3,299 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by cynicalsy on Thu Mar 14 02:08:18 MST 2013
Hi, I am currently trying to implement ADC using LPC1769.
I need to use 2 different channels (0 & 2) as I have two separate analog input signals.

When I only used one channel, it was working perfectly. So I basically copied the previously-working code and changed the channel number to 2 as following:


static void init_ADC_PINS1(void)
{
PINSEL_CFG_Type PinCfg;

PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 2;
PinCfg.Portnum = 0;
PinCfg.Pinnum = 23;
PINSEL_ConfigPin(&PinCfg);
}

static void init_ADC_PINS2(void)
{
PINSEL_CFG_Type PinCfg;

PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 2;
PinCfg.Portnum = 0;
PinCfg.Pinnum = 25;
PINSEL_ConfigPin(&PinCfg);
}


int ADC_Val1, ADC_Val2;
double v1,v2;

init_ADC_PINS1();
init_ADC_PINS2();

ADC_Init(LPC_ADC, 10000);
LPC_ADC->ADGDR &= ~(1<<31);

ADC_ChannelCmd (LPC_ADC, ADC_CHANNEL_0, ENABLE);
ADC_ChannelCmd (LPC_ADC, ADC_CHANNEL_2, ENABLE);

while(1)
{
ADC_StartCmd(LPC_ADC, ADC_START_NOW);

while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_0,ADC_DATA_DONE)));
ADC_Val1 = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_0);
v1 = (3.15/4096)*ADC_Val1;
printf("FSR voltage is %.2lf\n", v1);

while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_2,ADC_DATA_DONE)));

//##########  STUCK  ############

ADC_Val2 = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_2);
v2 = (3.15/4096)*ADC_Val2;
printf("IR voltage is %.2lf\n", v2);

Timer0_Wait(2000);

}


Measurements + ADC need to happen continuously (hence infinite loop). However, after 1st iteration (yes, it successfully goes through the loop for the first time), the system gets stuck in the infinite loop of the 2nd channel (CHANNEL_2). It seems that the system has no problem getting through the 1st channel (CHANNEL_0), but get stuck in the 2nd channel.

Does anyone know how to solve this problem

OR

can think of better/more efficient ways to implement this?

Please note that I am relatively new in LPCxpresso

Thanks in advance
0 Kudos
Reply
7 Replies

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by frame on Thu Mar 14 09:36:26 MST 2013

Quote:
Yes, blame the chip :)
Fortunately there are guys here with coding strength ;)



The STM32 ADC is more complex, and more capable.
Just the right thing for a guy with coding weakness ...;)

I only miss individual result registers.
0 Kudos
Reply

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ex-kayoda on Thu Mar 14 09:18:38 MST 2013
Yes, blame the chip :)

Fortunately there are guys here with coding strength ;)
0 Kudos
Reply

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by frame on Thu Mar 14 08:58:29 MST 2013
Sorry, but:
Every time I deal with ADC-related topic on a LPC1xxx for some project,
I switch over to a STM32 based device shortly afterwards.:(

It is definitely not a strength of LPC's ...
0 Kudos
Reply

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Mar 14 06:36:03 MST 2013
Your problem is that you are not allowed to set 2 channels if you are not in burst mode :eek:

[COLOR=Red]ADC_ChannelCmd (LPC_ADC, ADC_CHANNEL_0, ENABLE);
ADC_ChannelCmd (LPC_ADC, ADC_CHANNEL_2, ENABLE);[/COLOR]
If you set single channels and start a conversion, it's working also

UM10360 Table 531: A/D Control Register (AD0CR - address 0x4003 4000) bit description:

Quote:

7:0 SEL Selects which of the AD0.7:0 pins is (are) to be sampled and converted. For AD0, bit 0 selects Pin AD0.0, and bit 7 selects pin AD0.7. In software-controlled mode, [B][COLOR=Red]only one of these bits should be 1[/COLOR][/B]. In hardware scan mode, any value containing 1 to 8 ones is allowed. All zeroes is equivalent to 0x01.

[COLOR=Red]LPC_ADC->ADCR &= ~0xFF;            //reset channel
ADC_ChannelCmd (LPC_ADC, ADC_CHANNEL_0, ENABLE);
ADC_StartCmd(LPC_ADC, ADC_START_NOW);[/COLOR]
//ADC_BurstCmd(LPC_ADC,ENABLE);
while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_0,ADC_DATA_DONE)));
ADC_Val1 = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_0);
v1 = (3.15/4096)*ADC_Val1;
printf("ADC0: %.2lf\n", v1);
[COLOR=Red]LPC_ADC->ADCR &= ~0xFF;            //reset channel
ADC_ChannelCmd (LPC_ADC, ADC_CHANNEL_2, ENABLE);
ADC_StartCmd(LPC_ADC, ADC_START_NOW);[/COLOR]
while (!(ADC_ChannelGetStatus(LPC_ADC,ADC_CHANNEL_2,ADC_DATA_DONE )));
ADC_Val2 = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_2);
v2 = (3.15/4096)*ADC_Val2;
printf("ADC2: %.2lf\n", v2);
0 Kudos
Reply

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Mar 14 05:41:04 MST 2013

Quote: cynicalsy
...the ADC conversion takes place continuously regardless of edges or clocks.


  :confused:

Did you try Burst mode already?

//ADC_StartCmd(LPC_ADC, ADC_START_NOW);
ADC_BurstCmd(LPC_ADC,ENABLE);
0 Kudos
Reply

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by cynicalsy on Thu Mar 14 03:41:14 MST 2013
hi zero,

I have used the functions from the LPC17xx library.

/*********************************************************************//**
* @brief Set start mode for ADC
* @param[in]ADCx pointer to LPC_ADC_TypeDef
* @param[in]start_mode Start mode choose one of modes in
* 'ADC_START_OPT' enumeration type definition
* @return None
*********************************************************************/
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);
}



by setting the parameter for "start_mode" to be ADC_START_NOW, the ADC conversion takes place continuously regardless of edges or clocks.
0 Kudos
Reply

2,564 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Mar 14 03:03:43 MST 2013
:confused:

How do you start ADC conversion = what is ADC_StartCmd(LPC_ADC, ADC_START_NOW)  :confused::confused:
0 Kudos
Reply