/*****************************************************************************************
硬件串口
配置:
115200 1个停止位 无校验
LPC1788 TXD 引脚号202 P02
RXD 引脚号204 P03
LPC1756 TXD 引脚号XXX P02
RXD 引脚号XXX P03
2013年4月2日 keill v4
*****************************************************************************************/
/*****************************防止二次定义***********************************************/
#ifndef __BSPUART0_H__
#define __BSPUART0_H__
#include "bsptype.h"
/************************缓冲区大小******************************************************/
/************************函数声明********************************************************/
void BspUsart0Test(void);
int BspUsart0Init(void);
void BspUsart0Itoa(unsigned int n);
void BspUsart0String(unsigned char *str);
int BspUsart0Sends (unsigned char *sddata,unsigned cnt);
int BspUsart0Recvs (unsigned char *rddata,unsigned int cnt,unsigned int timeout);
/***********************防止二次定义*****************************************************/
#endif
/*****************************************************************************************
* 硬件串口接收发送数据
*文 件:bspuart0.c
*说 明:使用循环缓冲器作为FIFO
* 每发送/接收一个字节中断一次
115200时,一个字节的中断时间==86.8uS
当接收/发送的字节数超过缓冲器大小时将丢失
*编 者:张永辉 2012年10月2日
*修 改:张永辉 2013年4 月2日
*****************************************************************************************/
#define __BSPUART0_C__ //文件标识
#include "LPC17xx.h"
#include "system_LPC17xx.h"
#include "lpc17xx_pinsel.h"
#include "lpc17xx_uart.h"
#include "BspUart0.h"
#include "bsptime.h"
#include "math1.h"
//*******************************UART0变量及缓冲区****************************************
void UART0_IRQHandler(void);
unsigned char SendingFlg; //正在发送数据标志,在发送函数置位,中断清0
unsigned char RecvingFlg;
//*******************************循环缓冲区***********************************************
#define URT0_FIFO_LEN 64 //FIFO长度 字节
#define URT0_FIFO_TYPE unsigned char //FIFO数据类型
#define URT0_FIFO_NUM_TYPE unsigned int //FIFO数据计数器类型
//发送循环缓冲区
void UrtTxFifoInit(void);
void UrtTxFifoTest(void);
URT0_FIFO_NUM_TYPE UrtTxFifoPut (URT0_FIFO_TYPE* buff, URT0_FIFO_NUM_TYPE len);
URT0_FIFO_NUM_TYPE UrtTxFifoGet (URT0_FIFO_TYPE* buff, URT0_FIFO_NUM_TYPE len);
URT0_FIFO_NUM_TYPE UrtTxFifoPutByte(URT0_FIFO_TYPE buff);
URT0_FIFO_NUM_TYPE UrtTxFifoGetByte(URT0_FIFO_TYPE* buff);
URT0_FIFO_NUM_TYPE UrtTxFifoGetDataNum(void);
//接收循环缓冲器
void UrtRxFifoInit(void);
void UrtRxFifoTest(void);
URT0_FIFO_NUM_TYPE UrtRxFifoPut (URT0_FIFO_TYPE* buff, URT0_FIFO_NUM_TYPE len);
URT0_FIFO_NUM_TYPE UrtRxFifoGet (URT0_FIFO_TYPE* buff, URT0_FIFO_NUM_TYPE len);
URT0_FIFO_NUM_TYPE UrtRxFifoPutByte(URT0_FIFO_TYPE buff);
URT0_FIFO_NUM_TYPE UrtRxFifoGetByte(URT0_FIFO_TYPE* buff);
URT0_FIFO_NUM_TYPE UrtRxFifoGetDataNum(void);
/****************************************************************************************/
void BspUsart0Test(void)
{
int a = 0;
unsigned char s[20];
BspUsart0Init();
while(1)
{
a = BspUsart0Recvs(s,20,500);
if(a != 0)
{
BspUsart0Sends(s,a);
}else
{
BspUsart0Sends("NO data==",9);
BspUsart0Sends("NO data\r\n",9);
}
}
}
/*****************************************************************************************
发送,接收扩展函数
*****************************************************************************************/
void BspUsart0Itoa(unsigned int n)
{
int i;
unsigned char s[12];
for( i = 10;i >= 0;i--)
{
s[i] = ((n%10) + '0');
n = n /10;
}
//s[11]='\n';
BspUsart0Sends(s,11);
}
void BspUsart0String(unsigned char *str)
{
int len;
len = MathStrLen((const char*)str);
if(len ==0)
{return;}
BspUsart0Sends(str,len);
}
/*****************************************************************************************
发送,接收基本函数
*****************************************************************************************/
int BspUsart0Sends(unsigned char *sddata,unsigned cnt)
{
int i = 0;
unsigned char tmp;
while(cnt > 0)
{
//存入一个数据
if(UrtTxFifoPutByte(*sddata++)==0)
{
break;
}
cnt--;
i++;
}
//正在发送,则不需要启动发送了
if(SendingFlg==1)
{
return i;
}
//启动发送第一个数据
if(UrtTxFifoGetByte(&tmp)!=0)
{
UART_SendByte(LPC_UART0,tmp);
SendingFlg = 1;
}
return i; //返回个数
}
int BspUsart0Recvs(unsigned char *rddata,unsigned int cnt,unsigned int timeout)
{
unsigned int i;
unsigned char tmp;
//在规定的时间内等待
while(0 == UrtRxFifoGetDataNum() )
{
//时间到,退出
if(timeout-- == 0)
{
return 0;
}
BspTimeDelayMs(1);
}
//连续接收数据
while(cnt--)
{
if( 0==UrtRxFifoGetByte(&tmp))
{ //没有数据了
break;
}
*rddata++ = tmp;
i++;
//至少等待一个字节的时间
BspTimeDelayMs(1);
}
return i;
}
/*****************************************************************************************
串口0初始化
*****************************************************************************************/
int BspUsart0Init(void)
{
UART_CFG_Type UARTConfigStruct;
PINSEL_CFG_Type PINSELCfgStruct;
//缓冲器初始化
UrtTxFifoInit();
UrtRxFifoInit();
SendingFlg = 0;
RecvingFlg = 0;
//引脚功能配置
PINSELCfgStruct.Portnum = PINSEL_PORT_0; //P02 使用第一功能
PINSELCfgStruct.Pinnum = PINSEL_PIN_2;
PINSELCfgStruct.Funcnum = PINSEL_FUNC_1;
PINSELCfgStruct.Pinmode = PINSEL_PINMODE_PULLUP;
PINSELCfgStruct.OpenDrain = PINSEL_PINMODE_OPENDRAIN;
PINSEL_ConfigPin(&PINSELCfgStruct); //P0.02 TXD PIN79
PINSELCfgStruct.Pinnum = PINSEL_PIN_3;
PINSEL_ConfigPin(&PINSELCfgStruct); //P0.03 RXD PIN80
UART_ConfigStructInit(&UARTConfigStruct); //初始化配置,默认115200 bps,8 data bit,1 Stop bit,None parity
UARTConfigStruct.Baud_rate = 115200; //修改默认配置
UART_Init((LPC_UART_TypeDef *)LPC_UART0, &UARTConfigStruct); //下发配置
//使能接收、发送中断
UART_IntConfig(LPC_UART0,UART_INTCFG_RBR,ENABLE);
UART_IntConfig(LPC_UART0,UART_INTCFG_THRE,ENABLE);
//设置优先级
NVIC_SetPriority(UART0_IRQn, ((0x01<<3)|0x01));
//使能中断
NVIC_EnableIRQ(UART0_IRQn);
//UART0发送使能
UART_TxCmd((LPC_UART_TypeDef *)LPC_UART0, ENABLE);
return 0;
}
/*****************************************************************************************
中断函数
*****************************************************************************************/
void UART0_IRQHandler(void)
{
uint8_t tmp;
uint32_t intsrc;
intsrc = UART_GetIntId(LPC_UART0); //退出中断服务程序之前,必须读取 UnIIR 来清除中断
//发送缓冲区空中断
if(intsrc & 0x02)
{
//------------------------发送一个字节函数--------------------------
//发送数据段
//能获取到数据才继续发送,即直到将数据发送完毕
if(UrtTxFifoGetByte(&tmp) ==1)
{
UART_SendByte(LPC_UART0,tmp);
}else
{ //缓冲器的数据发送完毕
SendingFlg = 0;
}
}
//接收FIFO满中断
if(intsrc & 0x04)
{
//-----------------------接收一个字节函数---------------------------
tmp = UART_ReceiveByte(LPC_UART0);
UrtRxFifoPutByte(tmp); //若满了则存不进去。
}
//其他中断,暂时忽略
}
//====================================循环缓冲区==========================================
struct fifo
{
URT0_FIFO_TYPE FifoBuffer[URT0_FIFO_LEN];
URT0_FIFO_NUM_TYPE FifoNum; //FIFO未取走的数据个数
URT0_FIFO_NUM_TYPE FifoIn; //指向下次要放入数据的地方。
URT0_FIFO_NUM_TYPE FifoOut; //指向下次要取出数据的地方。
}UrtTxFifo,UrtRxFifo;
/*****************************************************************************************
函数功能: 初始化函数
使用前,先调用此函数
*****************************************************************************************/
void UrtTxFifoInit(void)
{
//初始化
UrtTxFifo.FifoNum = 0;
UrtTxFifo.FifoIn = 0;
UrtTxFifo.FifoOut = 0;
}
void UrtRxFifoInit(void)
{
//初始化
UrtRxFifo.FifoNum = 0;
UrtRxFifo.FifoIn = 0;
UrtRxFifo.FifoOut = 0;
}
/*****************************************************************************************
向FIFO存入一个数据
参数:buff 要存的数据
返回:成功存入数据的个数
*/
URT0_FIFO_NUM_TYPE UrtTxFifoPutByte(URT0_FIFO_TYPE buff)
{
//LOCK
//若此处无锁,若2线程同时 达到此处,都判断到未,同时加入数据则出问题了。
if(UrtTxFifo.FifoNum >= URT0_FIFO_LEN)
{
return 0;
}
//UNLOCK
UrtTxFifo.FifoBuffer[UrtTxFifo.FifoIn] = buff;
if (++UrtTxFifo.FifoIn >= URT0_FIFO_LEN)
{
UrtTxFifo.FifoIn = 0;
}
UrtTxFifo.FifoNum++;
return 1;
}
URT0_FIFO_NUM_TYPE UrtRxFifoPutByte(URT0_FIFO_TYPE buff)
{
//LOCK
//若此处无锁,若2线程同时 达到此处,都判断到未,同时加入数据则出问题了。
if(UrtRxFifo.FifoNum >= URT0_FIFO_LEN)
{
return 0;
}
//UNLOCK
UrtRxFifo.FifoBuffer[UrtRxFifo.FifoIn] = buff;
if (++UrtRxFifo.FifoIn >= URT0_FIFO_LEN)
{
UrtRxFifo.FifoIn = 0;
}
UrtRxFifo.FifoNum++;
return 1;
}
/*****************************************************************************************
从FIFO获取一个数据
参数:buff 要存数据的地址
返回:取得数据的个数
*/
URT0_FIFO_NUM_TYPE UrtTxFifoGetByte(URT0_FIFO_TYPE* buff)
{
//LOCK
if(UrtTxFifo.FifoNum <= 0)
{ //UNLOCK
return 0; //空的,直接返回
}
*buff = UrtTxFifo.FifoBuffer[UrtTxFifo.FifoOut];
if (++UrtTxFifo.FifoOut >= URT0_FIFO_LEN)
{
UrtTxFifo.FifoOut = 0;
}
UrtTxFifo.FifoNum--;
return 1;
}
URT0_FIFO_NUM_TYPE UrtRxFifoGetByte(URT0_FIFO_TYPE* buff)
{
//LOCK
if(UrtRxFifo.FifoNum <= 0)
{ //UNLOCK
return 0; //空的,直接返回
}
*buff = UrtRxFifo.FifoBuffer[UrtRxFifo.FifoOut];
if (++UrtRxFifo.FifoOut >= URT0_FIFO_LEN)
{
UrtRxFifo.FifoOut = 0;
}
UrtRxFifo.FifoNum--;
return 1;
}
/*****************************************************************************************
查询FIFO中已有数据个数
参数:无
返回:数据的个数
*/
URT0_FIFO_NUM_TYPE UrtTxFifoGetDataNum(void)
{
return UrtTxFifo.FifoNum;
}
URT0_FIFO_NUM_TYPE UrtRxFifoGetDataNum(void)
{
return UrtRxFifo.FifoNum;
}