⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uartcom.c

📁 51实战工程级源码
💻 C
字号:
/*
*************************************************************************************************************
*                                                Kingst-51
*                                        Development board samples
*
*                                 (c) Copyright 2009-2012, Kingst Studio
*                                           All Rights Reserved
*
*                                          http://www.kingst.org
* 文件名:UartCom.c
* 描  述:串口通信驱动文件
* 版本号:1.0.0
* 备  注:本驱动提供可按数据块操作的串口写入和读取功能函数,
*         并按照设定的超时时间,自动判断是否接收完一帧数据,在接收完时设置状态标志
*************************************************************************************************************
*/

#define _UART_COM_C
#include "config.h"
#include "main.h"
#include "UartCom.h"


/*
********************************************************************************
* ----------------------- Local defines  ---------------------------------------
********************************************************************************
*/
/* 接收、发送缓冲区容量设置(最大不能超过126) */
#define RX_BUFF_SIZE    50
#define TX_BUFF_SIZE    30


/* 帧间隔设定,即超过此时间时认定为一帧数据传输结束 */
#define FRAME_SPACE_TIME    50  //单位ms


/*
********************************************************************************
* ----------------------- Local variables  -------------------------------------
********************************************************************************
*/
/* 通信状态控制 */
typedef struct {	 
    int8  rxbtm;
    int8  rxcnt;
    int8  txbtm;	   
    int8  txtop;
} sComSta;
static sComSta ComSta;
static uint8 xdata RxBuff[RX_BUFF_SIZE];
static uint8 xdata TxBuff[TX_BUFF_SIZE];


/*
********************************************************************************
* ----------------------- Globle variables  ------------------------------------
********************************************************************************
*/
eUartRxSta UartRxSta = RX_NONE; //串口接收状态


/*
***************************************************************************************************
* ---------------------------------- Source codes  ------------------------------------------------
***************************************************************************************************
*/

/*
* 函数名:UartComInit
* 描  述:初始化串口通信配置
*/
void UartComInit(void)
{
	/* 配置T1为波特率发生器 */
    TMOD &= 0x0F;
    TMOD |= 0x20;
	TH1 = 244; //波特率2400,计算公式如下:
	TL1 = 244; //256 - 时钟频率/(12*32*波特率)
	ET1 = 0;
	
	/* 配置串口工作模式 */
	SCON = 0x50;
	TR1 = 1;
	ES = 1;
}


/*
* 函数名:UartWrite
* 描  述:UART发送函数,向缓冲区写入指定长度的数据,并启动发送
* 输  入:buff - 待写入数据块的指针
*         len  - 待写入数据块的长度
* 输  出:返回值 - 实际写入的数据长度
*/
int8 UartWrite(const void *buff, int8 len)
{
    int8 i, end;
    const uint8 *src;

    /* 获取实际可写入长度 */
    EA = 0;
    i = ComSta.txtop - ComSta.txbtm;
    EA = 1;		   
    if (i < 0) {
        i += TX_BUFF_SIZE;
    }
    i = TX_BUFF_SIZE - i;
    if (len > i) {
        return 0;
    }

    /* 拷贝数据到缓冲区中 */
    src = (const uint8 *)buff;
    i = ComSta.txtop;
    end = i + len;
    if (end < TX_BUFF_SIZE) {
        for (; i<end; i++) {
            TxBuff[i] = *src++;
        }
    }
    else {
        for (; i<TX_BUFF_SIZE; i++) {
            TxBuff[i] = *src++;
        }
        end -= TX_BUFF_SIZE;
        for (i=0; i<end; i++) {
            TxBuff[i] = *src++;
        }
    }

    /* 修改缓冲区指向信息 */
    EA = 0;
    if (ComSta.txbtm == ComSta.txtop) {
        TI = 1;
    }
    ComSta.txtop = end;
    EA = 1;

    return len;
}

/*
* 函数名:UartRead
* 描  述:UART接收缓冲区读取函数,读取指定长度的数据
* 输  出:在指针上输出数据,返回实际读到的数据长度,错误时返回-1
* 输  入:buff - 数据读取的接收指针
*         len  - 读取的数据块长度(-1为全部读出)
* 输  出:buff - 在此指针上输出读到的数据
*         返回值 - 实际读到的数据长度
*/
int8 UartRead(void *buff, int8 len)
{
    int8 i, end;
    uint8 *dest;

    /* 获取实际可读取长度 */
    EA = 0;
    if ((len>ComSta.rxcnt) || (len<0)) {
        len = ComSta.rxcnt;
    }
    EA = 1;

    /* 从缓冲区拷贝数据 */
    dest = (uint8 *)buff;
    i = ComSta.rxbtm;
    end  = i + len;
    if (end < RX_BUFF_SIZE) {
        for (; i<end; i++) {
            *dest++ = RxBuff[i];
        }
    }
    else {
        for (; i<RX_BUFF_SIZE; i++) {
            *dest++ = RxBuff[i];
        }
        end -= RX_BUFF_SIZE;
        for (i=0; i<end; i++) {
            *dest++ = RxBuff[i];
        }
    }

    /* 修改缓冲区指向信息 */
    EA = 0;
    ComSta.rxbtm = end;
    ComSta.rxcnt -= len;
    EA = 1;

    return len;
}

/*
* 函数名:UartRxMonitor
* 描  述:UART通信接收的监控函数,用于判定一帧数据的接收完成
* 输  入:ms - 本函数调用的间隔时间,单位ms
* 输  出:无
*/
void UartRxMonitor(uint8 ms)
{
    uint8 cnt;
    static uint8 cntbkp;
    static uint8 idletmr;
    static uint8 sigpost;

    cnt = ComSta.rxcnt;
    if (cnt == 0) {
        cntbkp = 0;
        return;
    }
    if (cnt != cntbkp) {
        idletmr = 0;
        sigpost = 0;
        cntbkp  = cnt;
        return;
    }
    if (sigpost != 0) {	     //保证接收完成标志只推送一次
        return;
    }
    idletmr += ms;
    if (idletmr >= FRAME_SPACE_TIME) {
        sigpost = 1;
        UartRxSta = RX_FINISH;
    }
}

/*
* 函数名:Serial_ISR
* 描  述:串口中断服务函数
*/
void Serial_ISR() interrupt 4
{
    uint8 chr;
    int8  top;

	/* 接收字符,保存到接收缓冲区中 */
	if (RI == 1) {
		RI = 0;
        chr = SBUF;
        if (ComSta.rxcnt < RX_BUFF_SIZE) {
            top = ComSta.rxbtm + ComSta.rxcnt;
            if (top >= RX_BUFF_SIZE) {
                top -= RX_BUFF_SIZE;
            }
            RxBuff[top] = chr;
            ComSta.rxcnt++;
        }
	}
	
	/* 由发送缓冲区中提取字符,并发送 */
	if (TI == 1) {
		TI = 0;
        if (ComSta.txbtm != ComSta.txtop) {
            SBUF = TxBuff[ComSta.txbtm];
            ComSta.txbtm++;
            if (ComSta.txbtm >= TX_BUFF_SIZE) {
                ComSta.txbtm = 0;
            }
        }
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -