Dear all, I am new to LPC2378..Currently i am developing code for sending a character in serial port....Below i mentioned the code what i have written..but this is not working...i am using keil uvision4...Can anybody help me in this code????
This is my code...
#include <LPC23xx.H> #include <stdio.h> void delay(int); int main (void) { PCONP |= 0x00000010; PCLKSEL0 |= 0x00000300; PINSEL0 |= 0x40000000; /* Enable TxD1 */ PINSEL1 |= 0x00000001; /* Enable RxD1 */ U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ U1DLM = 0x00; U1DLL = 0x34; /* 9600 Baud Rate @ 12MHz Clock */ U1FDR = 0x21; /* U1FDR[[7:4]=MULVAL,U1FDR[[3:0]=DIVADDVAL,for baud rate generation */ U1LCR = 0x03; /* DLAB = 0 */ U1FCR = 0x07; /* enable TX amp RX FIFO ,clears TX amp RX FIFO */ while(1) { U1THR = 'A'; while (!(U1LSR && 0x20)); } }
No need to start new threads - you could have added a new post to the previous thread.
Without looking at every bit you write to your registers, you do have a big error in this line:
while (!(U1LSR && 0x20));
&& is a logic operation, and you want to operate on individual bits of the U1LSR register. The '&' is the required bit operator, to extract one or more bits from an integer.
Another thing. Try to avoid magic numbers, and try to present how you decided on specific bit values when you initialize registers.
For example:
PCONP |= 0x00000010; PCLKSEL0 |= 0x00000300;
There is no information what the above two lines does. You probably knew what they did when you wrote the lines - but will you remember 6 months from now what device that gets powered up by the assign to PCONP?
Note that many peripherial pins are available on multiple locations - your chip have _two_ TXD1 and _two_ RXD1. Shouldn't the comment tell which specific pin you enable for use as TXD1 and as RXD1?
PINSEL0 |= 0x40000000; /* Enable TxD1 */ PINSEL1 |= 0x00000001; /* Enable RxD1 */
Why not present the calculation? The compiler can even perform the calculation directly in the source code - it will result in a constant value so it will not cost any extra code space or execution time:
U1DLL = 0x34; /* 9600 Baud Rate @ 12MHz Clock */
0x34 = 52. Baudrate clock must be 16 times faster than baudrate. So 52 * 16 * 9600 is about 8MHz. You mention 9600 baud @ 12 MHz clock - but do you really have a 8MHz PCLK?
below i commented the pupose of those two lines...
PCONP |= 0x00000010; /* To Enable the power/clock control bit for UART1 */ PCLKSEL0 |= 0x00000300; /* To Enable the Peripheral clock selection for UART1*/
I am using TxD1 and RxD1 in P0.i commented below..
PINSEL0 |= 0x40000000; /* Enable TxD1 in P0.15 */ PINSEL1 |= 0x00000001; /* Enable RxD1 in P0.16 */
Now i changed the U1DLL value...
U1DLL = 78; /* 9600 Baud Rate @ 12MHz Clock */
But still my code is not working...i dont know where i had mistake...
Sorry...My code is working...
This is the code....
#include <LPC23xx.H> #include <stdio.h> void delay(int); int main (void) { PINSEL0 |= 0x40000000; /* Enable TxD1 in P0.15 */ PINSEL1 |= 0x00000001; /* Enable RxD1 in P0.16 */ U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ U1DLM = 0x00; U1DLL = 78; /* 9600 Baud Rate @ 12MHz Clock */ U1LCR = 0x03; /* DLAB = 0 */ U1FCR = 0x07; /* enable TX amp RX FIFO ,clears TX amp RX FIFO */ while(1) { U1THR = 'A'; while (!(U1LSR & 0x20)); } }
But If i use printf function in my code its not working..May i know why??Below i mentioned the code...
#include <LPC23xx.H> #include <stdio.h> void delay(int); int main (void) { PINSEL0 |= 0x40000000; /* Enable TxD1 in P0.15 */ PINSEL1 |= 0x00000001; /* Enable RxD1 in P0.16 */ U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ U1DLM = 0x00; U1DLL = 78; /* 9600 Baud Rate @ 12MHz Clock */ U1LCR = 0x03; /* DLAB = 0 */ U1FCR = 0x07; /* enable TX amp RX FIFO ,clears TX amp RX FIFO */ printf("tesing..."); while(1) { U1THR = 'A'; while (!(U1LSR & 0x20)); } }
"But still my code is not working...i dont know where i had mistake..."
But what would happen if you instead wrote:
enum { PCLK_UART1 = 12000000 // Note that the different peripherials can have different PCLK }; ... U1DLL = (PCLK_UART1 / 9600 + 8) / 16; // +8 to round to nearest instead of truncating answer
That also gives the value 78, but you let the compiler perform the computation for you, and you will still get a correct baudrate if you later change PCLK_UART1 to another frequency. And a reader would be able to see how you computed your baudrate instead of just seeing a magic value 78.
If you want to, you can ignore the fractional baudrate divider register since you have a low-enough baudrate that you get quite a good baudrate match without it.
Did you check your '&&' in the while statement?
And remember - I have not spent any time trying to follow up all your individual bits you set in the different registers. And which order you do it.
And you say "isn't working" but not in what way. Don't you get any data at all on the serial port? Not even a single character? Some bit output but with wrong baudrate?
What do you expect printf() to do? Note that for an embedded product, there are no automatic "correct" behaviour for printf(). If you want printf() to send data to a specific serial port, you can do that.
On the other hand - if printf() is directed to send characters to uart1, then your while loop can't assume that U1THR is directly available for receiving more data - you have to consider if you want to test the state of the UART before or after you try to send characters to the port.
Ya...I have checked that in the while...In the both conditions (that is && and also &) while loop is working fine..But i am using bitwise AND(&) only....
Using printf: Actually i have to read the port values and have to display in the serail port like..
for example..
temp = FIO1SET0; printf("port value = %x",temp);
that's why i need the printf function also in my code only for testing purpose only....
See now my code is workig....as i already posted in my previous post...please see that..
this is my code...I am sending a char 'A' continously in serial port...
To implement printf you need to provide the low-level definitions for the c library functions that printf uses.
Here is a simple example for uart:
void uart_write_char(uint8_t byte) { while ((U0LSR & TX_HOLDING_REG_EMPTY) == 0 ); U0THR = byte; } uint8_t uart_read_char(void) { while ((U0LSR & RX_DATA_READY) == 0); return (uint8_t)U0RBR; } //************************************************************* // // C Lib - LOW-LEVEL CHARACTER INPUT AND OUTPUT // //************************************************************* struct __FILE { int handle; }; /* FILE is typedef’d in stdio.h. */ FILE __stdout; FILE __stdin; FILE __stderr; int fgetc(FILE *f) { /* Your implementation of fgetc(). */ return uart_read_char(); }; int fputc(int ch, FILE *stream) { uart_write_char((uint8_t)ch); return ch; } int ferror(FILE *stream) { /* Your implementation of ferror(). */ return 0; } long int ftell(FILE *stream) { /* Your implementation of ferror(). */ return 0; } int fclose(FILE *f) { /* Your implementation of ferror(). */ return 0; } int fseek(FILE *f, long nPos, int nMode) { /* Your implementation of ferror(). */ return 0; } int fflush(FILE *f) { /* Your implementation of ferror(). */ return 0; }
Hope this helps...