现在的位置: 首页 > 综合 > 正文

LPC1756_C_串口收发_循环缓冲区

2013年11月26日 ⁄ 综合 ⁄ 共 9658字 ⁄ 字号 评论关闭

/*****************************************************************************************
                                 硬件串口
配置:
 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;
}

抱歉!评论已关闭.