I want to interface MCB2140 with a pressure sensor which will give input for every 1 second.. I connected UART0 to pressure sensor output, UART1 to serial port of PC. The pressure sensor gives the integer value as output.The UART0 will receive data from sensor and should display in hyper terminal for every 1 minute..I wrote the following code..The code gets hanged in startup file at BX R0...Please let me know any other changes required #include <LPC21xx.H> void init_serial (void); int main(void) { init_serial();
while(1) { int getc_serial0; int putc_serial1; } } void init_serial (void) {
PINSEL0 = 0x00050005;
U0LCR = 0x00000083;
U0DLL = 98;
U0LCR = 0x00000003;
U1LCR = 0x00000083;
U1DLL = 98;
U1LCR = 0x00000003;
}
int getc_serial0(void)
{
while (!(U0LSR & 0x01));
return U0RBR;
} int putc_serial1(void)
while (!(U1LSR & 0x20));
U1THR=U0RBR;
return (U1THR);
So, it seems I need to repeat what I asked before:
"And what's R2 doing during this continuous loop?"
That was a hint for you - To see if you'd figure out what the loop was doing.
You need to put a breakpoint at 0x0000019C (i.e., on the following instruction) to see if it gets there. If it does, then you're past your continuous loop and you can single step further.
Till now i did not got to know, what is the need of changing the startup code?. Is there any bug in my application code or startup file.
If you have a loop:
int i; for (i = 0; i < 100; i++) { mem[i] = 0; }
and you single-step the above loop, it will seem like it is an infinite loop. But code that repeats are not automatically infinite.
If you notice that the loop counter is ticking, it would be obvious that it isn't an infinite loop.
Then there would be two alternatives available: 1) The loop ends when it has run the configured number of turns - best caught with a breakpoint on the first statement _after_ the loop.
2) The loop ends because it performs an invalid operation or invalid access. Best caugt by having breakpoints on the exception handlers and then backtrack where it came from and how far it got in the loop before the failure.
3) The loop may be intended to be infinite but actually be infinite because the loop body happens to have a side effect on the loop counter resulting in it never being able to reach the termination value.
It doesn't seem like you are trying to put any breakpoints after the loop and on the exception handlers. So if you just single-step, it can take a potentially very long time to get through the loop. And if you only have your next breakpoint inside main() and the loop can't end because of access problems, you will not find out.
Debugging is all about subdividing problems into smaller sub-problems to find out what is actually happening and when what is happening starts to deviate from what is expected to happen.
You are receiving a lot of hints what to look for, but you don't seem to try.
Thank you westermark for your kind advice..I am trying hard after your suggestions from 1st day of your guidance.Thanks for all..I will try to debug
A successful debugging experience to fix a certain problem is important to a beginner. But I think it might be too early to learn how to debug for the OP. I say so, because I think my skill level is closer to the OP.
To the OP: Maybe it would be better to start with something it does work; and try to study how it works. Then, you will get some knowledge about startup code, C main(), exception handler, UART, and how to trace a working well program. Then re-start to learn how to debug.
To the OP:
I quickly re-read the whole thread, I think you could start with a working well UART example project for your LPC2148.
1. Find one working well UART example project for your LPC2148. 2. Trace (Debug) it on your real hardware, to see how it works.
Please let me know if any bug is there in the code.
#include<lpc214x.h> #include<stdio.h> void init_serial(void) { PINSEL0 = 0x00050005; /* Enabling RxD0 and TxD0, RxD1 and TxD1 */ U0LCR = 0x00000083; /* 8 bits, no Parity, 1 Stop bit * for UART0*/ U0DLL = 98; U0FCR=0x01; /* To enable the Tx and Rx FIFO*/ U0IER=0; /*Disable all interrupts*/ U0LCR = 0x00000003; /* DLAB = 0 for UART0*/ U1LCR = 0x00000083; /* 8 bits, no Parity, 1 Stop bit for UART1*/ U1DLL = 98; U1LCR = 0x00000003; /* DLAB = 0 * for UART1*/ U1FCR=0x81; /*Enable the FIFO registers*/ U1IER=0; /*Disable all interrupts*/ } char receive() { if (U0LSR & 0x01) /* If U0LSR 1st bit contains valid data then return value of U0RBR*/ { if(U0RBR >=48 || U0RBR <=58) /*If data received is between 0 to 9 then only return that value to the fucntion receive()*/ return (U0RBR); } return '#'; /* If other than 0 to 9 data is recieved return #*/ } void transmit() { if(!(U1LSR & 0x20) && receive() != '#' ) /* Checking whether U1LSR 5th bit contains valid data or not and data is between 0 to 9*/ { U1THR=receive(); /* copying the receive() to U1THR*/ printf("%d",U1THR); /*print U1THR */ } else printf("z"); /*Print z */ } main(void) { init_serial(); /* Initailization of UART1 & UART2*/ while(1) /* Infinite loop*/ { receive(); /* function for receiving data from sensor */ transmit(); /* function for transmitting the data to PC hyperterminal*/ } }
"Please let me know if any bug is there in the code."
So, haven't you either tested the code and found that it seems to work? Or tested the code and found that it doesn't work, but after spent time debugging it failed to locate the problem?
No - your code is incorrect. When you return with information about what testing you have done and what problems you have seen, I will consider helping with some further notes about the code. But just some hints: - do you think you should read out data from the UART multiple times? - do you think you should have a receive() that returns a value and then sometimes call receive() without using the return value()? - do you think you should have a main loop that calls receive() and transmit() and also have transmit() call receive()? - does the user manual for the chip say that you can read from the transmitter holding register?
See comment in my first post (the second in this thread): "What have you done to find out what the problem may be?"
And you still don't seem to have considered posting code with good indentation - proper indentation makes the code way easier to read. And note that web forms have big problems with code indented with tab characters or that mixes tabs and spaces for identing.
#include "lpc214x.h" #include<stdio.h> void init_serial(void) { PINSEL0 = 0x00050005; /* Enabling RxD0 and TxD0, RxD1 and TxD1 */ U0LCR = 0x00000083; /* 8 bits, no Parity, 1 Stop bit * for UART0*/ U0DLL = 98; U0FCR=0x81; /*Enable the FIFO registers*/ U0LCR = 0x00000003; /* DLAB = 0 for UART0*/ U1LCR = 0x00000083; /* 8 bits, no Parity, 1 Stop bit for UART1*/ U1DLL = 98; U1LCR = 0x00000003; /* DLAB = 0 * for UART1*/ U1FCR=0x81; /*Enable the FIFO registers*/ } char receive()/*function for receiving data from sensor (reads byte by byte & returns value if exist, else #) */ { if (U0LSR & 0x01) /* If U0LSR 1st bit contains valid data, then return value of U0RBR*/ { if(U0RBR >=48 || U0RBR <=58) /*If data received is between 0 to 9 then only return that value to the fucntion receive()*/ return (U0RBR); } return '#'; /* If other than 0 to 9 data is recieved return #*/ } void transmit() { if(!(U1LSR & 0x20) && U1THR != '#' ) /* Checking whether U1LSR 5th bit contains valid data and data is between 0 to 9*/ U1THR=receive(); /* copying the receive() to U1THR*/ printf("%d",U1THR); /*print U1THR */ } main(void) { init_serial(); /* Initailization of UART1 & UART2*/ while(1) /*Infinite loop*/ { transmit(); /* function for transmitting the data to PC hyperterminal*/ } }
I changed the code as per your suggestion, westermerk. My data from the sensor is a floating point number.(eg.1257.65). How many times i have to read the full floating point data 1257.65 using the FIFOs present in LPC2148 I will explain clearly my problem.. After writing the code, i rebuilded the code and started debug. Then stopped code execution, the yellow pointer is pointing at SWI_Handler B SWI_Handler . After clicking RST pointer goes to Vectors LDR PC, Reset_Addr . Then i did single step , the pointer is moving over each line and finally hangs at BX R0 ; Enter the C code
IMPORT __main LDR R0, =__main
BX R0 The code always hangs in startup.s file
"Then i did single step , the pointer is moving over each line and finally hangs at BX R0"
A case of deja vu?
This is _not_ modified code. At least not code modified based on the comments you have received.
if (U0LSR & 0x01) { /* If U0LSR 1st bit contains valid data, then return value of U0RBR*/ if(U0RBR >=48 || U0RBR <=58) /*If data received is between 0 to 9 then only return that value to the fucntion receive()*/ return (U0RBR); } return '#'; /* If other than 0 to 9 data is recieved return #*/
You are _still_ reading U0RBR multiple times. My comment was: "do you think you should read out data from the UART multiple times?"
That should have been enough for you to start thinking on your own. If you have a FIFO with multiple characters receievd, and you call U0RBR first to check if you have a digit - will that digit really be still there when you get to the return statement?
Another thing is taht your function returns # both if it receives an invalid character or if no character was available. Was that rally what you intended? If it was, then your comment is lying since your comment do say: "If U0LSR 1st bit contains valid data, then return value of U0RBR". That comment does not take into account your extra test for '0' <= ch <= '9'.
Your code still ignores my comment: "do you think you should have a receive() that returns a value and then sometimes call receive() without using the return value()?"
Your code still ignores my comment: "do you think you should have a main loop that calls receive() and transmit() and also have transmit() call receive()?"
Your code still ignores my comment: "does the user manual for the chip say that you can read from the transmitter holding register?"
So what exactly do you mean with: "I changed the code as per your suggestion, westermerk."
I did point you at four problems, and all four problems are still there. Did you just waste bandwidth (and peoples times) by posting the same source code again?
I did not called receive() in main loop
No, but you seem to have switched to a completely different strange idea about how to read/write:
void transmit() { if(!(U1LSR & 0x20) && U1THR != '#' ) /* Checking whether U1LSR 5th bit contains valid data and data is between 0 to 9*/ U1THR=receive(); /* copying the receive() to U1THR*/ printf("%d",U1THR); /*print U1THR */ }
What is that first read of U1THR? That is not a correct replacement for the previous receive().
What a mess. You are experiencing program failure - probably not related to your inability to use a UART correctly. Solve the crash first!
"Solve the crash first!"
Yes. First off it's important to figure out if it's a problem with the source code or with the project settings or with the selected startup file.
A good way to do that is to have main() only enter an infinite loop, while toggling a processor pin. That should make sure that main() doesn't contain any invalid code that generates an exception.
The startup code must match the used processor, and the project dialog boxes specifying start address and size of each memory region, so that the startup code doesn't try to initialize memory that doesn't exist or try to use non-existant memory as stack space.
Given the huge problems of just understanding the difference between read-only and write-only SFR and the failure of trying to read out the same character multiple times from the UART, I would recommend starting with one of the sample programs.
First try to download an existing sample and check that it runs as expected.
Then rebuild and download and check that it still runs as expected.
Then add own code, rebuild, download and test.
But it really helps to learn how to use the debugger and the simulator. Just with the note that the simulator will mainly be useful for finding algorithmic errors while only the real hardware can be used to verify that the project really is correctly configured for the used hardware.
It's important to notice that the debugger is way more than just a way to single-step through code. All debugger commands are there for a reason, and all commands should be learned. How they are used, and why they are there i.e. what they are good for. Single-stepping a large program that doesn't fail for the first 10 minutes would be very, very boring since the processor runs so much faster than what single-stepping does.
One thing that is good to learn is how to have breakpoints in exception handlers and understand where the processor came from when it decided to enter the exception handler. An alternative is to learn how to modify code to bracket code regions and figure out which code stretch the execution had to have been in when it jumped to an exception handler. This may be done by having the main loop update a global variable between each call it does - that global variable would then tell which function call that failed, and the user may then drill down that call chain and perform further subdivision of the problem. A problem is of course that the line that results in an exception need not be the broken source line - it may just suffer from an earlier error but would at least indicate what pointers/indices/... that may have been corrupted.