📄 uart.c
字号:
/*****************************************************************************
* uart.c: UART API file for NXP LPC210x Family Microprocessors
*
* Copyright(C) 2006, NXP Semiconductor
* All rights reserved.
*
* History
* 2005.10.01 ver 1.00 Prelimnary version, first Release
******************************************************************************/
#include "LPC210x.H" /* LPC21xx definitions */
#include "type.h"
#include "target.h"
#include "irq.h"
#include "uart.h"
#include "i2c.h"
DWORD UART1Status;
BYTE UART1TxEmpty = 1;
DWORD UART1Count; // Uart buffer counter - shows amount of data in Uart buffer
DWORD write_to_buf_ptr; // write counter - used when buffer is written by I2C host
DWORD read_from_buf_ptr; // read counter - used when buffer read by I2C host
BYTE UART1Buffer[BUFSIZE];
BYTE rts_flag = 0;
/*****************************************************************************
** Function name: UART1Handler
** Description: UART1 interrupt handler
** Parameter: None
** Returned value: None
*****************************************************************************/
void UART1_Handler(void) __irq
{
BYTE IIRValue, LSRValue;
IENABLE; // Handles nested interrupt
IIRValue = U1IIR;
IIRValue >>= 1; // Skip pending bit in IIR
IIRValue &= 0x07; // Check bits 1~3, interrupt identification
if( IIRValue == IIR_RLS ) /* Receive Line Status */
{
if( U1LSR & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
{
LSRValue = U1LSR;
IDISABLE;
VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
}
else if( IIRValue == IIR_RDA ) /* Receive Data Available */
{
while( U1LSR & LSR_RDR )
{
if( UART1Count < (BUFSIZE-1) )
{
UART1Buffer[write_to_buf_ptr] = U1RBR;
write_to_buf_ptr++;
if( write_to_buf_ptr == (BUFSIZE-1) )
{
write_to_buf_ptr = 0; // Ring buffer
}
UART1Count++;
}
else if( UART1Count >= (BUFSIZE-1) )
{
VICIntEnClr = 1 << UART1_INT; // Disable Interrupt
rts_flag = 1;
break;
}
}
}
else if( IIRValue == IIR_CTI ) /* Character Timeout Indicator */
{
UART1Status |= 0x100; // Bit 9 as the CTI error
while( U1LSR & LSR_RDR )
{
if( UART1Count < (BUFSIZE-1)) // Append data in ring buffer
{
UART1Buffer[write_to_buf_ptr] = U1RBR;
write_to_buf_ptr++;
if( write_to_buf_ptr == (BUFSIZE-1) )
{
write_to_buf_ptr = 0; // Ring buffer
}
UART1Count++;
}
else if(UART1Count >= (BUFSIZE-1))
{
VICIntEnClr = 1 << UART1_INT; // Disable Interrupt
rts_flag = 1;
break;
}
}
}
else if( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */
{
/* THRE interrupt */
LSRValue = U1LSR; // Check status in the LSR to see if valid data in U1THR or not
if( LSRValue & LSR_THRE )
{
UART1TxEmpty = 1; // U1THR is empty
}
else
{
UART1TxEmpty = 0; // U1THR contains valid data
}
}
/* Auto baud interrupt handling */
if( U1IIR == 0x10 ) // ABEOInt: Auto-baud has finished successfully
{
U1ACR |= 0x10; // ABEOIntClr: Clear the corresponding interrupt in the U1IIR
}
else if (U1IIR == 0x20 ) // ABTOInt: Auto-baud has timed out
{
U1ACR |= 0x20; // ABTOIntClr: Clear the corresponding interrupt in the U1IIR
}
IDISABLE;
VICVectAddr = 0; // Acknowledge Interrupt
} // UART1_Handler
/*****************************************************************************
** Function name: UARTInit
** Description: Initialize UART1 port, setup pin select,
** clock, parity, stop bits, FIFO, etc.
** Parameter: UART baudrate
** Returned value: true or false, return false only if the interrupt
** handler cannot be installed to the VIC table
*****************************************************************************/
DWORD UART_Init( DWORD baudrate )
{
DWORD Fdiv;
UART1Count = 0;
write_to_buf_ptr = 0;
read_from_buf_ptr = 0;
PINSEL0 |= 0x00550000; // Set P0.8 as TXD1, P0.9 as RXD1, P0.10 as RTS1 and P0.11 as CTS1
U1LCR = 0x83; // 8 data bits, 1 Stop bit, no Parity, Enable access to Divisor Latches
Fdiv = (Fpclk/16)/baudrate;
U1DLM = Fdiv/256;
U1DLL = Fdiv%256;
U1LCR = 0x03; // 8 data bits, 1 Stop bit, no Parity, Disable access to Divisor Latches
U1FCR = 0xC7; // Enable and Clear UART1 TX and RX FIFO; Set 14 character Rx Trigger Level
U1MCR |= 0x00000040; // Enable auto-RTS flow control
U1ACR = 0x07; // Initiate auto-baud; Auto-baud Mode 0 select; Configure auto-baud restart (in case of timeout)
if( install_irq( UART1_INT, (void *)UART1_Handler ) == FALSE )
{
return (FALSE);
}
U1IER = IER_RBR | IER_THRE | IER_RLS; // Enables RDA, THRE and Rx Line Status interrupts for UART1
U1IER |= IER_ABT | IER_ABE; // Enables auto-baud timeout interrupt and end of auto-baud operation interrupt
return (TRUE);
} // UART_Init
/*****************************************************************************
** Function name: UART_Send
** Description: Send a block of data to the UART 1 port based on the
** data length
** Parameter: buffer pointer, data length
** Returned value: None
*****************************************************************************/
void UART_Send(BYTE *BufferPtr, DWORD Length )
{
while( Length != 0 )
{
while( !(UART1TxEmpty & 0x01) ); /* THRE status, contain valid data */
U1THR = *BufferPtr;
UART1TxEmpty = 0; /* not empty in the THR until it shifts out */
BufferPtr++;
Length--;
}
} // UART_Send
/*****************************************************************************
** Function name: UartGet1ByteData
** Description: Get 1 byte of data from ring buffer UART1Buffer
** Parameter: None
** Returned value: 1 data byte from UART1Buffer
*****************************************************************************/
BYTE UartGet1ByteData( void )
{
BYTE data;
/* Receive Data Available */
data = UART1Buffer[read_from_buf_ptr];
read_from_buf_ptr++;
if( read_from_buf_ptr == (BUFSIZE-1) )
{
read_from_buf_ptr = 0; /* ring buffer */
}
UART1Count--;
if(rts_flag == 1)
{
VICIntEnable = 1 << UART1_INT; /* Enable Interrupt */
}
return data;
} // UartGet1ByteData
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -