SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By Ace
#139693
I've been beating my head against the wall for a couple of days now. I have a Logomatic V2 and can read my ADC channel (AD0.3)with the software given by SFE, but I can't get this code to work and, dang it, it's identical!!! The result of this code is that it either writes empty strings or 0 to the SD card. Any help would be much appreciated.
Code: Select all
	IODIR0 &= 0xBFFFFFFF; //This makes sure that P0.30 is 0 (input) 
	PINSEL1 |= 0x10000000; // set p0.30 to adc0.3
	PINSEL1 &= 0xDFFFFFFF; // clear bit 29

 void readTemp ( void )
 {
 unsigned short int val;
 char str_data[10];
 
 AD0CR = 0x00020FF08; // AD0.3
 AD0CR |= 0x01000000; // start conversion
 log_string("conversion started\n\r");
 while (1) {
	if (AD0GDR & 0x80000000) break;
	}
	string_printf(str_data,"0x%x\n\r",AD0GDR);
log_string(str_data);
 val = AD0DR;
 val = ((val>>6)& 0x03FF);
 string_printf(str_data,"%u\n\r",val);
 log_string(str_data);
 }
By UhClem
#139703
I am confused by something. You test for conversion complete by testing the done bit in the AD0 global data register and that is fine. But then you read the data from something called AD0DR. Something that isn't defined in the LPC214x.h file that defines AD0GDR.

Another little detail is that your code isn't identical. The description of the data register says that the RESULT field contains the conversion result when DONE=1. It is silent on what is there when DONE=0. Yet you reset DONE by reading it in the loop. When you read the data register (one can only hope it is the data register) DONE will be zero.

Try:
do {
temp = AD0GDR;
} while ((temp&0x80000000)) == 0;

temp = (temp >> 6) & 0x3ff;
By Ace
#139751
Thanks for the help.

Leon: It's an extra leading zero - doesn't matter. But changed.

David: I had tried that code before (I think I even copied some code you posted), but I put that in my code snippet above and still got a zero back. I had wondered about the point you brought up and re-read the manual looking for a "read data first before you check the DONE flag" but never found it.

The AD0DR was copied from some other code (maybe SFE) but I had to add the definition because it isn't in the LPC214x.n file.
#define AD0DR (*((volatile unsigned long *) 0xE0034004))

This is all very odd. I'm sure it's something small and stupid. SFE's code works great but when i try to modify it (take out the software buffers and the interrupts) I get zero's again.
By UhClem
#139755
Ace wrote: The AD0DR was copied from some other code (maybe SFE) but I had to add the definition because it isn't in the LPC214x.n file.
#define AD0DR (*((volatile unsigned long *) 0xE0034004))
That is because there is no register named that on the LPC2148. Why don't you use AD0DR3?
By Ace
#139756
AD0DR is the same as AD0GDR which has a place for the RESULT. I did notice the ADODR3. I couldn't find a description of the difference of the two - why would they put the ADC results in two different memory locations(oxE0034004 and 0xE003401C)?

Anyways, I tried grabbing that result as well with no luck. Came back 0.
By UhClem
#139757
Ace wrote:AD0DR is the same as AD0GDR which has a place for the RESULT. I did notice the ADODR3. I couldn't find a description of the difference of the two - why would they put the ADC results in two different memory locations(oxE0034004 and 0xE003401C)?
What if you configured it to convert multiple channels in BURST mode with an interrupt only when the last channel is complete? The extra registers let you do this and read the individual results. Otherwise you have to have an interrupt for each individual conversion which is tedious and time consuming.