This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

lpc23xx uart fault data

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.

  • I'm using uart0 but other uart1 made settings. Follow code ,where the error . I can't found .

    struct buf_st {
      unsigned int in;          /* Next In Index */
      unsigned int out;         /* Next Out Index */
      char buf [RBUF_SIZE];     /* Buffer */
    };
    
    

    Follow code do not use

    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 this is still wrong:

    struct buf_st {
      unsigned int in;          /* Next In Index */
      unsigned int out;         /* Next Out Index */
      char buf [RBUF_SIZE];     /* Buffer */
    };
    

    You have one #define specifying the receive buffer size. And another #define specifying the transmit buffer size. So you should have two separate structures that makes use of the relevant #define'd values. Else everything will fail badly if you later decide to change RBUF_SIZE without also changing TBUF_SIZE.

    Next thing - maybe, just maybe - you could tell me how many characters you think this loop consumes for every iteration? And how many characters does it print?

    while (com_getchar0() >= 0) {
        for (i = 0; i < 5000; i++);
        com_putchar0(com_getchar0());
    }
    

    I can recommend that you consider debugging an important part of your software development work. You will never get anywhere unless you spend some time on improving your debugging skills. How to try to figure out which part of code that can be responsible for a problem. How to analyze that code and potentially divide it down into even smaller blocks while figuring out which block is broken.

    You have code that drops every second character received. I did show you a function that did consume two characters/iteration. Wouldn't that be enough clue for you to realize that you might have more than one piece of code with similar behavior?