Hi everyone, I have been working on this for about a week, looking at examples from all over the place and pouring through datasheets, but I cannot get this to work(or many ARM Features for that matter) I have worked with AVRs for a while and I love them, but I wanted to move up to ARM. I know a reasonable amount of C, and no assembler. I don't really want to get this example working as much as I want to learn what im not doing right. I really want to learn how to be able to do ARM programs on my own and not rely on forums to help me, so any tutorials or books would be greatly appreciated. So, I am trying to get the ADC working so it will print the 10-bit value of ADC0.3 over uart0 at 19200 baud. Here is my code:
1 | #include "LPC214x.h" |
2 | |
3 | #define ADC_CLK 1000000 /* set to 1Mhz */ |
4 | |
5 | #include "serial.h" |
6 | #include "rprintf.h" |
7 | #include "target.h" |
8 | |
9 | void delay_ms(int x); |
10 | |
11 | int main(void) |
12 | { |
13 | init_serial0(19200); |
14 | rprintf_devopen(putc_serial0); |
15 | rprintf("Hello!\n\n"); |
16 | |
17 | PINSEL0 = 0x10000000; |
18 | |
19 | AD0CR = (0x01 << 0) | |
20 | (1 << 3) | //Turn analog 3 on |
21 | (( Fpclk / ADC_CLK - 1 ) << 8) | |
22 | (0 << 16) | // BURST = 0, no BURST, software controlled |
23 | (0 << 17) | // CLKS = 000, 11 clocks/10 bits |
24 | (0 << 18) | //^ |
25 | (0 << 19) | //^ |
26 | (1 << 21) | // PDN = 1, normal operation |
27 | (0 << 22) | // TEST1:0 = 00 |
28 | (0 << 24); // START = 0 A/D conversion stops |
29 | |
30 | while(1) { |
31 | AD0CR |= (1 << 24); //Start Conversion |
32 | delay_ms(1); //Give it time to convert(I doubt this is necessary?) |
33 | rprintf("%luH", ((AD0DR3 >> 6) & 0x000003ff) * 0x40); |
34 | AD0CR &= (1 << 24); //Stop Conversion |
35 | delay_ms(50); |
36 | } |
37 | } |
38 | |
39 | void delay_ms(int x) |
40 | //Rough, not meant to be accurate |
41 | { |
42 | int a,b; |
43 | for(a=0;a<x;a++){ |
44 | for(b=0;b<3000;b++); |
45 | } |
46 | } |
And when I run the code this is all I get:
1 | Hello! |
2 | ÿ |
Any ideas for what I am doing wrong? Thanks!
After I posted this I thought I should mention that I am using an LPC2148, on the Olimex Header Board. I am compiling with GCC. I also just noticed you prefer code attached. Sorry for the large paste above.
Your delay loop is not going to work if you compile with optimization enabled (-Ox), because the compiler will detect an empty loop and remove it. Use volatile variables for the counter, then it won't get removed. If your controller hangs, the reason is usually an exception caused by an invalid memory access. Do you have a JTAG debugger? If yes, try to find out what the controller is doing after you have received the output (it is probably hanging at the abort handler), then rerun and use single step to locate the statement that's causing it. If you don't have a debugger, you can for example comment out lines until you have found the problem.
- Strange output might just be caused by missing functionality in rprintf. Since rprintf is not shown it's difficult to analyse. Test with a known uint32_t value first, see rprintf source and check for "l", test with "L", test with cast to uin32_t. Try to use sprintf from the newlib. - add volatile to counters definition (a,b) in delay-function.
You can try to read the Logomatic-v2 code from sparkfun electronic. It use the LPC2148 ADC, I have tested and it works very well with Uart output. Link to the Logomatic-v2 product info: http://www.sparkfun.com/commerce/product_info.php?products_id=8627 There is a link to get the source code (main firmware)
Thank you everyone! I do not have an ARM JTAG, dongle, but I do have a USB Xilinx FPGA one, would that work? I played around with it some more, commenting out lines until I got it working. I found that PINSEL0 = 0x10000000; was the problem, and by removing it it will now actually print the ADC value. The problem is, it always prints zero. I know that the ADC is actually reading zero because I did a test with if(adcval == 0), and it always returned true. I did like mthomas suggested as use sprintf from newlib, but unfortunately this did not help. I have attached the code and all other files I include(except the standard ones). Any help is greatly appreciated. Thank you!
Neal Le Moult: I looked at the Logomatic Code, but the ADC Part seemed really jumbled in with everything else, and what I am really looking for is learning how to use the ADC, which is hard when its combined with interrupts and timers and the like. Thanks anyway!
Here is an application note from Nxp about LPC21xx ADC http://www.vas.co.kr/nxp/support/technical_notes/tn06004.pdf