We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi , I have uart problem . I want to do ; computer to send data to the mcu(same data) than mcu to pc. Examples
13.12.2012 14:30:08.72 [TX] - 1234567890 13.12.2012 14:30:08.72 [RX] - 1234567890
but I'm having problems receiving data
13.12.2012 14:30:08.72 [TX] - 1234567890 13.12.2012 14:30:08.72 [RX] - 24680
follow code.
Notes: I'm sorry bad english spelling.
#include "lpc23xx.h" #include <stdio.h> typedef unsigned char U8; typedef unsigned int U32; typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef unsigned int BOOL; #define TBUF_SIZE 256 /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/ #define RBUF_SIZE 256 /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/ /*------------------------------------------------------------------------------ ------------------------------------------------------------------------------*/ #if TBUF_SIZE < 2 #error TBUF_SIZE is too small. It must be larger than 1. #elif ((TBUF_SIZE & (TBUF_SIZE-1)) != 0) #error TBUF_SIZE must be a power of 2. #endif #if RBUF_SIZE < 2 #error RBUF_SIZE is too small. It must be larger than 1. #elif ((RBUF_SIZE & (RBUF_SIZE-1)) != 0) #error RBUF_SIZE must be a power of 2. #endif #define __FALSE 0 #define __TRUE (!__FALSE) struct buf_st { unsigned int in; /* Next In Index */ unsigned int out; /* Next Out Index */ char buf [256]; /* Buffer */ }; static struct buf_st rbuf = { 0, 0, }; #define SIO_RBUFLEN ((unsigned short)(rbuf.in - rbuf.out)) static struct buf_st tbuf = { 0, 0, }; #define SIO_TBUFLEN ((unsigned short)(tbuf.in - tbuf.out)) static unsigned int tx_restart = 1; /* NZ if TX restart is required */ static struct buf_st rbuf; static struct buf_st tbuf; static unsigned tx_active; void InitUART0(void) { DWORD Fdiv; rbuf.in = 0; rbuf.out = 0; tbuf.in = 0; tbuf.out = 0; tx_active = __FALSE; PINSEL0 = 0x40000050; PINSEL1 = 0x00000001; IODIR1 = 0x00000700; FIO2DIR = 0x00002010; Fdiv = ( 12000000 / 16 ) / 19200 ; /*baud rate */ U1DLM = Fdiv / 256; U1DLL = Fdiv % 256; U0FCR = 0x07; U0LCR = 0x80; U0DLM = Fdiv / 256; U0DLL = Fdiv % 256; U0LCR = 0x03; //U0FDR = (14 << 4) + 4; U0IER = 0x07; U1FCR = 0x07; U1LCR = 0x80; U1DLM = Fdiv / 256; U1DLL = Fdiv % 256; U1LCR = 0x03; //U1FDR = (14 << 4) + 4; U1IER = 0x07; } __irq void UART0_IRQHandler(void) { volatile char dummy; volatile char IIR; struct buf_st *p; /*------------------------------------------------ Repeat while there is at least one interrupt source. ------------------------------------------------*/ while (((IIR = U0IIR) & 0x01) == 0) { switch (IIR & 0x0E) { case 0x06: /* Receive Line Status */ dummy = U0LSR; /* Just clear the interrupt source */ VICVectAddr = 0; /* Acknowledge Interrupt */ break; case 0x04: /* Receive Data Available */ case 0x0C: /* Character Time-Out */ p = &rbuf; if (((p->in - p->out) & ~(RBUF_SIZE-1)) == 0) { p->buf [p->in & (RBUF_SIZE-1)] = U0RBR; p->in++; } break; case 0x02: /* THRE Interrupt */ p = &tbuf; if (p->in != p->out) { U0THR = p->buf [p->out & (TBUF_SIZE-1)]; p->out++; tx_restart = 0; } else { tx_restart = 1; } break; case 0x00: /* Modem Interrupt */ // dummy = U0MSR; /* Just clear the interrupt source */ break; default: break; } } VICVectAddr = 0; /* Acknowledge Interrupt */ } int com_putchar0 (int c) { struct buf_st *p = &tbuf; /*------------------------------------------------ If the buffer is full, return an error value. ------------------------------------------------*/ if (SIO_TBUFLEN >= TBUF_SIZE) return (-1); /*------------------------------------------------ Add the data to the transmit buffer. If the transmit interrupt is disabled, then enable it. ------------------------------------------------*/ if (tx_restart) { tx_restart = 0; U0THR = c; } else { p->buf [p->in & (TBUF_SIZE - 1)] = c; p->in++; } return (0); } /*--------------------------- com_getchar0 -----------------------------------*/ int com_getchar0 (void) { struct buf_st *p = &rbuf; if (SIO_RBUFLEN == 0) return (-1); return (p->buf [(p->out++) & (RBUF_SIZE - 1)]); } int usart_oku (int *veri) { struct buf_st *p = &rbuf; if (SIO_RBUFLEN == 0) return (-1); *veri=(p->buf [(p->out++) & (RBUF_SIZE - 1)]); return (p->buf [(p->out++) & (RBUF_SIZE - 1)]); } /*--------------------------- putStr0--------------------------------------*/ void putStr0(const char *str) { for ( ; str && *str; str++) com_putchar0(*str); } BOOL com_tx_active (void) { /* Return status Transmitter active/not active. */ /* When transmit buffer is empty, 'tx_active' is FALSE. */ return (tx_active); } int com_getchar (void) { int c; c=com_getchar0(); return c; } int main(void) { volatile unsigned i = 0; volatile unsigned k = 0; int ver; VICVectAddr6 = (unsigned long) UART0_IRQHandler; /* set interrupt vector 6 */ VICVectPriority6 = 0 ; /* default priority is 15 (lowest), can be set between 0-15 */ VICIntEnable |= (1UL<<6); /* Enable UART0 Interrupt */ InitUART0(); for (i = 0; i < 500000U; i++); putStr0("its ok!\r\n"); while(1) { while (com_getchar0() >= 0) { for (i = 0; i < 5000; i++); com_putchar0(com_getchar0()); } //putchar1(getchar1()); } }
You have nice constants:
#define TBUF_SIZE 256 /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/ #define RBUF_SIZE 256 /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/
So why do you then use a hard-coded value here:
struct buf_st { unsigned int in; /* Next In Index */ unsigned int out; /* Next Out Index */ char buf [256]; /* Buffer */ };
And why do you have so hard to know what UART you are working with - isn't it enough to set one single baudrate in InitUART0()?
Fdiv = ( 12000000 / 16 ) / 19200 ; /*baud rate */ U1DLM = Fdiv / 256; <= OOPS - this isn't UART0 so why play with wrong registers? U1DLL = Fdiv % 256; ... U0DLM = Fdiv / 256; <= Now you seem to have found UART0 registers. U0DLL = Fdiv % 256; ... U1DLM = Fdiv / 256; <= Suddenly busy playing with UART1 again - why??? U1DLL = Fdiv % 256;
Your code is a mis-match of cut and paste. I'm not even convinced that the code you pasted is the same as you have been running.
But here is an interesting function:
int usart_oku (int *veri) { struct buf_st *p = &rbuf; if (SIO_RBUFLEN == 0) return (-1); *veri=(p->buf [(p->out++) & (RBUF_SIZE - 1)]); return (p->buf [(p->out++) & (RBUF_SIZE - 1)]); }
Note that the *veri assign consumes one received character. And the return consumes yet another received character. Do I need to say how bad that is?
Work a bit slower, and instead try to make sure that you spend time thinking about every single line of code you write.