LPC1769 ADC Problem

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

LPC1769 ADC Problem

639 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by andretendi on Mon Mar 18 23:12:00 MST 2013
Hi guys, I'm trying to use the ADC function on LPC1769 but for some reason, I can't make it work.
I am using software controlled ADC from AD0.0 to read in an analog voltage between 0-3.3V.

When I run the program, however, the ADC never starts at all. My program gets stuck at the 'while' loop waiting for bit DONE to be set, which indicates that ADC is completed. It never did. I wonder if any of you can point my mistakes and set me on the right track

I understand that I have to configure the following:
[LIST=1]1. PINSEL1: Set P0.23 as AD0.0[/LIST]
[LIST=2]2. PINMODE1: Set P0.23 as neither pull-up or pull-down resistor enabled[/LIST]
[LIST=3]3. PCONP: Enable PCADC[/LIST]
[LIST=4]4. ADCR: Select AD0.0[/LIST]
[LIST=5]5. ADCR: CLKDIV set to 4. Hence, ADC clock -> (100MHz/4)/(4+1) = 5MHz[/LIST]
[LIST=6]6. ADCR: Burst = 0 for software controlled[/LIST]
[LIST=7]7. ADCR: Enable PDN[/LIST]
[LIST=8]8. ADCR: START = 001 to start conversion[/LIST]
[LIST=9]9. ADDR0: wait for DONE to be set[/LIST]
[LIST=10]10. ADDR0: Read RESULT[/LIST]


My program code is as follows:

#include "LPC17xx.h"

//****** ADC variables and arrays ******//
unsigned int adc_result[5];//adc_result array to store results from the different channels

int main(void)
{
//A/D Converter is powered on
LPC_SC->PCONP |= 1<<12;

//set P0.23 as AD0.0
LPC_PINCON->PINSEL1 |= (0x1 << 14);

//Set PINMODE of AD0.0 as no pull-up/down resistors
LPC_PINCON->PINMODE1 |= (0x2 << 14);

//select AD0.0, CLKDIV = 4+1 => 25MHz/5 = 5MHz < 13MHz, power on
LPC_ADC->ADCR |= (1 << 0) | (4 << 8) | (1 << 21);

//start conversion
LPC_ADC->ADCR |= (1 << 24);

//wait for conversion to finish by checking ADGDR.31
while((LPC_ADC->ADDR0 & (1<<31)) == 0);

//return conversion result
adc_result[0] = ((LPC_ADC->ADDR0 >> 4) & 0xFFF);

// Enter an infinite loop, just incrementing a counter
volatile static int i = 0 ;

while(1) {
i++ ;
}

return 0 ;
}



Any inputs are much appreciated.
0 Kudos
6 Replies

516 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu May 23 05:49:55 MST 2013

Quote: guidam313

Does it make a difference or not? :confused:



A 3 is a 3. Regardless how you write it: decimal (3) or hexadecimal (0x3) or octal (03) or binary (0b11).

Of course binary is helping us to see which bits are set. But that's not too helpful in 32bit systems.

Therefore I prefer hexadecimal like 0x1000 instead of 010000 or 0b1000000000000 for larger numbers.

And often it's possible (as in this sample) to shift. That's making the code more readable.

But anyway, you are free to write your numbers how you like it :)
0 Kudos

516 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by cfb on Thu May 23 04:41:32 MST 2013

Quote: guidam313

Since  I learned micro-controller in assembly language I'm more comfortable writing the same line as:
LPC_PINCON->PINSEL1 |=  (0b11<<14);
Does it make a difference or not? :confused:


Yes - it does make a difference. You are setting bit 15 and bit 14. For the AD0.0 function you should clear bit 15 and set bit 14.

Zero's code clears both bits before setting bit 14.
0 Kudos

516 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Alex_ivanovich on Wed May 22 16:54:25 MST 2013
interesting topic , I agree with you ...
0 Kudos

516 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by guidam313 on Wed May 22 09:15:31 MST 2013
Hi Zero
I've been around this forum for somme time now as a non-registered guest. I've seen you reply to so many topics and helped me through these replies.
Thank you! :)  
The reason why I take the time to reply about this one is because I had the same problem as andretendi. I havent't done the modification you suggested yet but I'm pretty sure it will be enough. The correction you're doing are as follow:

//set P0.23 as AD0.0
[COLOR=Red]LPC_PINCON->PINSEL1 &= ~(3<<14);[/COLOR]
LPC_PINCON->PINSEL1 |=  (1<<14);  

Since  I learned micro-controller in assembly language I'm more comfortable writing the same line as:
LPC_PINCON->PINSEL1 |=  (0b11<<14);
Does it make a difference or not? :confused:
0 Kudos

516 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by andretendi on Wed Mar 20 09:06:36 MST 2013
Hi Zero,

Thank you, the program works now. Both version seems to be working.
Apparently my LPC board had some issues. When I replaced the board with a new one, it works fine.

Thank you for the reply.

Cheers
0 Kudos

516 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Mar 19 00:03:56 MST 2013
Try this:

//A/D Converter is powered on
LPC_SC->PCONP |= 1<<12;

//set P0.23 as AD0.0
[COLOR=Red]LPC_PINCON->PINSEL1 &= ~(3<<14);[/COLOR]
LPC_PINCON->PINSEL1 |=  (1<<14);

//Set PINMODE of AD0.0 as no pull-up/down resistors
[COLOR=Red]LPC_PINCON->PINMODE1 &= ~(3<<14);[/COLOR]
LPC_PINCON->PINMODE1 |=  (2<<14);

//select AD0.0, CLKDIV = 4+1 => 25MHz/5 = 5MHz < 13MHz, power on
LPC_ADC->ADCR[COLOR=Red]  = [/COLOR](1 << 0) | (4 << 8) | (1 << 21);

//start conversion
LPC_ADC->ADCR |= (1 << 24);

//wait for conversion to finish by checking ADGDR.31
while((LPC_ADC->ADDR0 & (1<<31)) == 0);

//return conversion result
adc_result[0] = ((LPC_ADC->ADDR0 >> 4) & 0xFFF);
0 Kudos