/***************************************************************************************************
基本串口使用
LPC1114 硬件:
P1.6-RXD
P1.7-TXD
GND -GND
VCC -3.3
配置 8bit数据 1stop 无校验
实现方法:
1 使用1字节硬件FIFO。(相当于没用),每1字节中断一次,时间隔86uS
2 使用软件BUFF,长度可配置
3 收发函数可立即返回
编 者 张永辉 2012年11月29日
***************************************************************************************************/
#ifndef __UART0_H
#define __UART0_H
/*******************************配置***************************************************************/
#define UART0_BUF_TYPE unsigned char //接收的数据类型。都是8位就按此类型了
#define UART0_DATA_CNT unsigned char //若设置buf长度超过255,则需要改变此类型。
#define UART0_SENDBUF_LEN 32 //发送数据BUF长度
#define UART0_RECVBUF_LEN 32 //接收数据BUF长度
/*******************************函数声明***********************************************************/
UART0_DATA_CNT Uart0Recv(UART0_BUF_TYPE * buff,UART0_DATA_CNT len);
UART0_DATA_CNT Uart0Send(UART0_BUF_TYPE * buff,UART0_DATA_CNT len);
void UartTest(void);
void UartInit(void);
void UART_IRQHandler(void);
/**************************************************************************************************/
#endif
/***************************************************************************************************
本文件功能: 串口
***************************************************************************************************/
#define __UART0_C
#include "LPC11xx.h"
#include "systick.h"
#include "uart.h"
/*******************************声明***************************************************************/
UART0_BUF_TYPE Uart0SendBuf[UART0_SENDBUF_LEN];
UART0_DATA_CNT Uart0SendIn = 0;
UART0_DATA_CNT Uart0SendOut = 0;
UART0_BUF_TYPE Uart0RecvBuf[UART0_RECVBUF_LEN];
UART0_DATA_CNT Uart0RecvIn = 0;
UART0_DATA_CNT Uart0RecvOut = 0;
void Uart0SendByte_server(void);
void Uart0RecvByte_server(void);
/***************************************************************************************************
函数功能:UART测试
***************************************************************************************************/
void UartTest(void)
{
unsigned char a[5]="12345";
UartInit();
while(1)
{
Uart0Send(a,5);
SYSTICKDelay10ms(10);
a[0] = Uart0Recv(a,5);
a[0] += 0x30;
}
}
/***************************************************************************************************
函数功能:UART初始化
参 数:固定波特率 115200
***************************************************************************************************/
void UartInit(void)
{
NVIC_DisableIRQ(UART_IRQn); //先禁止UART中断
//引脚配置,仅使用RXD TXD引脚
LPC_IOCON->PIO1_6 &= ~0x07; //配置引脚为UART模式
LPC_IOCON->PIO1_6 |= 0x01; //UART RXD
LPC_IOCON->PIO1_7 &= ~0x07;
LPC_IOCON->PIO1_7 |= 0x01; //UART TXD
//AHBCLKCTRL 对UART开关
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); //即开启UART. 关闭此位可以降低功耗
LPC_SYSCON->UARTCLKDIV = 0x1; //USART时钟使能,=0除能
//波特率由UARTCLKDIV控制
//波特率使用115200,如下配置实际为115384,误差0.16%
LPC_UART->LCR |= (0X80); //DLAB=1 允许对除数锁存器的访问
LPC_UART->FDR = 0x85; //需要DLAB=1
LPC_UART->DLM = 0; //需要DLAB=1
LPC_UART->DLL = 16;
LPC_UART->LCR &= ~(0X80); //DLAB=0 禁止对除数锁存器的访问
LPC_UART->LCR |= (0X03); //8bits,1个停止位,无校验,禁止间隔发送
//中断控制
//LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;
LPC_UART->IER = 0x03; //允许RBR THRE中断
LPC_UART->FCR = 0x01; //使能FIFO 收满1字节触发中断.U0FCR对FIFO无影响
//发送使能位
LPC_UART->TER &= ~(0X80); //除能发送
NVIC_EnableIRQ(UART_IRQn); //使能UART中断
}
/***************************************************************************************************
函数功能:接收数据函数
参数:buff 接收数据指针
len 最大数据长度
返回:接收到的个数
***************************************************************************************************/
UART0_DATA_CNT Uart0Recv(UART0_BUF_TYPE * buff,UART0_DATA_CNT len)
{
//能够接收多少个数据
len = (len < Uart0RecvIn) ? len : Uart0RecvIn;
Uart0RecvOut = 0;
//接收数据
while(len--)
{
*buff++ = Uart0RecvBuf[Uart0RecvOut++];
}
//清空Buf bug:若len < Uart0RecvBuf 则丢失接收到的数据了
Uart0RecvIn = 0;
return Uart0RecvOut;
}
/***************************************************************************************************
函数功能:发送数据
参数:buff 发送数据指针
len 最大数据长度
返回:发送的个数
***************************************************************************************************/
UART0_DATA_CNT Uart0Send(UART0_BUF_TYPE * buff,UART0_DATA_CNT len)
{
//不能 发送0个数据 或者有数据正在发送
if(0==len || Uart0SendOut != 0)
{
return 0;
}
//应该最大发送长度
len = (len < UART0_SENDBUF_LEN) ? len : UART0_SENDBUF_LEN;
//数据复制
while(len--)
{
Uart0SendBuf[Uart0SendOut++] = *buff++;
}
//装载第一个数据
LPC_UART->THR = Uart0SendBuf[0];
Uart0SendIn++;
//发送使能,会中断一次,立即发送数据。
LPC_UART->TER = (0X80);
//返回发送的数据个数
return (Uart0SendOut);
}
/***************************************************************************************************
函数功能:中断处理函数
***************************************************************************************************/
void UART_IRQHandler(void)
{
uint8_t IIRValue;
uint8_t LSRValue;
//只读 中断标志寄存器
IIRValue = LPC_UART->IIR; //==0x02 THER ==0X40接收数据可用
//IIR == 0x03 接收线状态
// 02 接收数据可用
// 06 字符超时指示器
// 01 THRE 中断
// 00 modle
IIRValue = IIRValue;
//线状态寄存器
LSRValue = LPC_UART->LSR;
//byte0 = 1 U0RBR有数据
//byte5 = 1 U0THR为空
//发生数据空 也可以判断IIRValue
if(LSRValue & (1<<5))
{
Uart0SendByte_server();
}
if(LSRValue & 0x01)
{ //读数据会清空中断标志
Uart0RecvByte_server();
}
}
void Uart0SendByte_server(void)
{
//一次数据发送完成
if(Uart0SendIn >= Uart0SendOut)
{
Uart0SendIn = 0;
Uart0SendOut = 0;
LPC_UART->TER &= ~(0X80); //除能发送,否则会继续中断
return;
}
//装载数据
LPC_UART->THR = Uart0SendBuf[Uart0SendIn++];
}
void Uart0RecvByte_server(void)
{
UART0_BUF_TYPE rev;
rev = LPC_UART->RBR; //读数据会清空中断标志
//接收满了直接返回
if(Uart0RecvIn >= UART0_RECVBUF_LEN)
{
return;
}
//接收数据
Uart0RecvBuf[Uart0RecvIn++] = rev;
}