Receiving UART in LPC1768

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Receiving UART in LPC1768

2,709 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by albertleng1978 on Sat Nov 10 06:32:39 MST 2012
I'm working on a project in which the MCU LPC1768 will be connected to a host.

The host will send command message to UART1 of MCU LPC1768 and the MCU will reply with a predefined message. There are a series of command messages from the host.
The sequences are:
1) From Host to MCU: "UART_On"
    From MCU to Host: "UART_On_Done"

2) From Host to MCU: "UART_Off"
    From MCU to Host: "UART_Off_Done"
and etc...

What happens is that I send "UART_On" to the MCU and it replies with "UART_On_Done". Then, I send "UART_Off". The MCU will reply with "UART_On_Done" or "UART_On_DoneUART_On_Done".  What I want is like what I wrote above.

I wrote the code based on UART example of mcb1700.code.bundle.lpc17xx.keil.

My main codes are as below. I also attach my source code. Please kindly help to see what's wrong and give me any suggestions.
Thank you soooo much!

#include "lpc17xx.h"
#include "type.h"
#include "uart.h"
#include "string.h"
#include <stdlib.h>
#include <stdio.h>


extern volatile uint32_t UART1Count;
extern volatile uint8_t UART1Buffer[BUFSIZE];

uint8_t Dummy;
    

int main (void)
{

  SystemClockUpdate();
  UARTInit(1, 115200);    /* baud rate setting */

  while (1) 
  {                /* Loop forever */
    
    if ( UART1Count != 0 )
    {
      LPC_UART1->IER = IER_THRE | IER_RLS;            /* Disable RBR */
                  
        if (strstr((const char *)UART1Buffer, "UART_On")) {
            UARTSend( 1, "UART_On_Done", 12);
                    UART1Count = 0;
        }
        
        if (strstr((const char *)UART1Buffer, "UART_Off")) {
            UARTSend( 1, "UART_Off_Done", 13);
                UART1Count = 0;
        }
            
        LPC_UART1->IER = IER_THRE | IER_RLS | IER_RBR;    /* Re-enable RBR */
    
    }
  }
}
#include "lpc17xx.h"
#include "type.h"
#include "uart.h"

volatile uint32_t UART0Status, UART1Status;
volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1;
volatile uint8_t UART0Buffer[BUFSIZE], UART1Buffer[BUFSIZE];
volatile uint32_t UART0Count = 0, UART1Count = 0;

void UART0_IRQHandler (void) 
{
  uint8_t IIRValue, LSRValue;
  uint8_t Dummy = Dummy;
    
  IIRValue = LPC_UART0->IIR;
    
  IIRValue >>= 1;            /* skip pending bit in IIR */
  IIRValue &= 0x07;            /* check bit 1~3, interrupt identification */
  if ( IIRValue == IIR_RLS )        /* Receive Line Status */
  {
    LSRValue = LPC_UART0->LSR;
    /* Receive Line Status */
    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
    {
 
      UART0Status = LSRValue;
      Dummy = LPC_UART0->RBR;      
      return;
    }
    if ( LSRValue & LSR_RDR )    /* Receive Data Ready */            
    {
      UART0Buffer[UART0Count] = LPC_UART0->RBR;
      UART0Count++;
      if ( UART0Count == BUFSIZE )
      {
        UART0Count = 0;        /* buffer overflow */
      }    
    }
  }
  else if ( IIRValue == IIR_RDA )    /* Receive Data Available */
  {

    UART0Buffer[UART0Count] = LPC_UART0->RBR;
    UART0Count++;
    if ( UART0Count == BUFSIZE )
    {
      UART0Count = 0;        /* buffer overflow */
    }
  }
  else if ( IIRValue == IIR_CTI )    /* Character timeout indicator */
  {
    /* Character Time-out indicator */
    UART0Status |= 0x100;        /* Bit 9 as the CTI error */
  }
  else if ( IIRValue == IIR_THRE )    /* THRE, transmit holding register empty */
  {
    /* THRE interrupt */
    LSRValue = LPC_UART0->LSR;        /* Check status in the LSR to see if
                                    valid data in U0THR or not */
    if ( LSRValue & LSR_THRE )
    {
      UART0TxEmpty = 1;
    }
    else
    {
      UART0TxEmpty = 0;
    }
  }
    
}
void UART1_IRQHandler (void) 
{
  uint8_t IIRValue, LSRValue;
  uint8_t Dummy = Dummy;
    
  IIRValue = LPC_UART1->IIR;
    
  IIRValue >>= 1;            /* skip pending bit in IIR */
  IIRValue &= 0x07;            /* check bit 1~3, interrupt identification */
  if ( IIRValue == IIR_RLS )        /* Receive Line Status */
  {
    LSRValue = LPC_UART1->LSR;
    /* Receive Line Status */
    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
    {
      /* There are errors or break interrupt */
      /* Read LSR will clear the interrupt */
      UART1Status = LSRValue;
      Dummy = LPC_UART1->RBR;        /* Dummy read on RX to clear 
                                interrupt, then bail out */
      return;
    }
    if ( LSRValue & LSR_RDR )    /* Receive Data Ready */            
    {
      /* If no error on RLS, normal ready, save into the data buffer. */
      /* Note: read RBR will clear the interrupt */
      UART1Buffer[UART1Count] = LPC_UART1->RBR;
      UART1Count++;
      if ( UART1Count == BUFSIZE )
      {
        UART1Count = 0;        /* buffer overflow */
      }    
    }
  }
  else if ( IIRValue == IIR_RDA )    /* Receive Data Available */
  {
    /* Receive Data Available */
    UART1Buffer[UART1Count] = LPC_UART1->RBR;
    UART1Count++;
    if ( UART1Count == BUFSIZE )
    {
      UART1Count = 0;        /* buffer overflow */
    }
  }
  else if ( IIRValue == IIR_CTI )    /* Character timeout indicator */
  {
    /* Character Time-out indicator */
    UART1Status |= 0x100;        /* Bit 9 as the CTI error */
  }
  else if ( IIRValue == IIR_THRE )    /* THRE, transmit holding register empty */
  {
    /* THRE interrupt */
    LSRValue = LPC_UART1->LSR;        /* Check status in the LSR to see if
                                valid data in U0THR or not */
    if ( LSRValue & LSR_THRE )
    {
      UART1TxEmpty = 1;
    }
    else
    {
      UART1TxEmpty = 0;
    }
  }

}


uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate )
{
  uint32_t Fdiv;
  uint32_t pclkdiv, pclk;

  if ( PortNum == 0 )
  {
    LPC_PINCON->PINSEL0 &= ~0x000000F0;
    LPC_PINCON->PINSEL0 |= 0x00000050;  /* RxD0 is P0.3 and TxD0 is P0.2 */
    /* By default, the PCLKSELx value is zero, thus, the PCLK for
    all the peripherals is 1/4 of the SystemFrequency. */
    /* Bit 6~7 is for UART0 */
    pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
    switch ( pclkdiv )
    {
      case 0x00:
      default:
        pclk = SystemFrequency/4;
        break;
      case 0x01:
        pclk = SystemFrequency;
        break; 
      case 0x02:
        pclk = SystemFrequency/2;
        break; 
      case 0x03:
        pclk = SystemFrequency/8;
        break;
    }

    LPC_UART0->LCR = 0x83;        /* 8 bits, no Parity, 1 Stop bit */
    Fdiv = ( pclk / 16 ) / baudrate ;    /*baud rate */
    LPC_UART0->DLM = Fdiv / 256;                            
    LPC_UART0->DLL = Fdiv % 256;
    LPC_UART0->LCR = 0x03;        /* DLAB = 0 */
    LPC_UART0->FCR = 0x07;        /* Enable and reset TX and RX FIFO. */

       NVIC_EnableIRQ(UART0_IRQn);

    LPC_UART0->IER = IER_RBR | IER_THRE | IER_RLS;    /* Enable UART0 interrupt */
    return (TRUE);
  }
  else if ( PortNum == 1 )
  {
    LPC_PINCON->PINSEL4 &= ~0x0000000F;
    LPC_PINCON->PINSEL4 |= 0x0000000A;    /* Enable RxD1 P2.1, TxD1 P2.0 */
    
    /* By default, the PCLKSELx value is zero, thus, the PCLK for
    all the peripherals is 1/4 of the SystemFrequency. */
    /* Bit 8,9 are for UART1 */
    pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03;
    switch ( pclkdiv )
    {
      case 0x00:
      default:
        pclk = SystemFrequency/4;
        break;
      case 0x01:
        pclk = SystemFrequency;
        break; 
      case 0x02:
        pclk = SystemFrequency/2;
        break; 
      case 0x03:
        pclk = SystemFrequency/8;
        break;
    }

    LPC_UART1->LCR = 0x83;        /* 8 bits, no Parity, 1 Stop bit */
    Fdiv = ( pclk / 16 ) / baudrate ;    /*baud rate */
   LPC_UART1->DLM = Fdiv / 256;                            
   LPC_UART1->DLL = Fdiv % 256;
    LPC_UART1->LCR = 0x03;        /* DLAB = 0 */
    LPC_UART1->FCR = 0x07;        /* Enable and reset TX and RX FIFO. */

       NVIC_EnableIRQ(UART1_IRQn);

    LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS;    /* Enable UART1 interrupt */
    return (TRUE);
  }
  return( FALSE ); 
}

void UARTSend( uint32_t portNum, uint8_t *BufferPtr, uint32_t Length )
{
  if ( portNum == 0 )
  {
    while ( Length != 0 )
    {
      /* THRE status, contain valid data */
      while ( !(UART0TxEmpty & 0x01) );    
      LPC_UART0->THR = *BufferPtr;
      UART0TxEmpty = 0;    /* not empty in the THR until it shifts out */
      BufferPtr++;
      Length--;
    }
  }
  else
  {
    while ( Length != 0 )
    {
      /* THRE status, contain valid data */
      while ( !(UART1TxEmpty & 0x01) );    
      LPC_UART1->THR = *BufferPtr;
      UART1TxEmpty = 0;    /* not empty in the THR until it shifts out */
      BufferPtr++;
      Length--;
    }
  }
  return;
}
0 Kudos
4 Replies

1,145 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fjrg76 on Mon Nov 12 23:33:58 MST 2012
Have you ever tried to debug and set a breakpoint just before the strstr() function?
0 Kudos

1,145 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by albertleng1978 on Sun Nov 11 20:26:26 MST 2012
Thanks for pointing that out.

I thought both LPCXpresso and Keil use the same code.
0 Kudos

1,145 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Sun Nov 11 07:51:45 MST 2012
This is a LPCXpresso forum ;)

You can find a Keil Discussion Forum here: http://www.keil.com/forum/threads.asp
0 Kudos

1,145 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by albertleng1978 on Sun Nov 11 07:39:34 MST 2012
Hi help anyone? Thanks again.
0 Kudos