一个非常不错的串口程序
扫描二维码
随时随地手机看文章
//PC读MCU指令结构:(中断方式,ASCII码表示)
//帧:帧头标志| 帧类型| 器件地址| 启始地址| 长度n| 效验和| 帧尾标志
//值:’n’ ’y’ | ’ r’ |0x01| x|x |x| 0x130x10
//字节数:2|1|1|1|1|1|2
//求和:
/////////////////////////////////////////////////////////////////////
//功能描述:中断方式:本程序为mcu的串口通讯提供(贞结构)函数接口,包括具体协议部分
//其他说明:只提供对AT89c51具体硬件的可靠访问接口
//版本:1.0
//信息:
/////////////////////////////////////////////////////////////////////
#include
#include
//预定义
//帧
#defineF_ST10x6e//帧头标志n
#defineF_ST20x79//帧头标志y
#defineF_R0x72//帧类型读
r
#defineF_W0x77//帧类型写
w
#defineF_D0x64//帧类型数据帧d
#defineF_B0x62//帧类型写回应帧b
#defineF_C0x63//帧类型重发命令帧c
#defineF_Q0x71//帧类型放弃帧q
#defineF_ADDR0x31//器件地址0-9
#defineF_END0x7a//帧尾标志z
#defineF_SPACE0x30//空标志0
#defineF_ERR10x31//错误标志1,flagerr1
#defineF_ERR20x32//错误标志2
2
//常数
#defineS_MAXBUF16//接收/发送数据的最大缓存量
#defineFIELD_MAXBUF48//最小场缓存,可以大于48字节,因为协议是以20字节为单
位传输的
#definecommunicationingP1_7//正在通讯(1)标志
#defineERRFRAME_MAX5//连续NOFRAME_CNT次帧不正确
#defineERR_NOCNTMAX_RESENDif(++errframe_cnt<=ERRFRAME_MAX)resend_frame();
elseerrframe_cnt=communicationing=0;
//若超过
ERRFRAME_MAX次则令通讯停止ERR_NOCNTMAX_RESEND
//public变量
unsignedchardatabuf[FIELD_MAXBUF],errframe_cnt;
//函数
/////////////////////////////////////////////////////////////////////
//函数名:send()
//功能描述:向串口发送一个字符
//函数说明:
//调用函数:
//全局变量:
//输入:ch-要发送的ASCII字符
//返回:无
//设计者:牛毅
//修改者:
//版本:
/////////////////////////////////////////////////////////////////////
voidsend(unsignedcharch)
{SBUF=ch;while(TI==0);TI=0;}
/////////////////////////////////////////////////////////////////////
//函数名:receive()
//功能描述:从串口接收一个字符
//函数说明:
//调用函数:
//全局变量:
//输入:无
//返回:一个ASCII字符
//设计者:牛毅
//修改者:
//版本:
/////////////////////////////////////////////////////////////////////
unsignedcharreceive(void)
{while(RI==0);RI=0;returnSBUF;}
/////////////////////////////////////////////////////////////////////
//函数名:CharToHex()
//功能描述:把ASCII字符转换为16进制
//函数说明:
//调用函数:
//全局变量:
//输入:ASCII字符
//返回:16进制
//设计者:牛毅
//修改者:
//版本:
/////////////////////////////////////////////////////////////////////
unsignedcharCharToHex(unsignedcharbChar){
if((bChar>=0x30)&&(bChar<=0x39))
bChar-=0x30;
elseif((bChar>=0x41)&&(bChar<=0x46))//大写字母
bChar-=0x37;
elseif((bChar>=0x61)&&(bChar<=0x66))//小写字母
bChar-=0x57;
elsebChar=0xff;
returnbChar;
}
/////////////////////////////////////////////////////////////////////
//函数名:HexToChar()
//功能描述:把16进制转换为ASCII字符
//函数说明:
//调用函数:
//全局变量:
//输入:16进制
//返回:ASCII字符
//设计者:牛毅
//修改者:
//版本:
/////////////////////////////////////////////////////////////////////
unsignedcharHexToChar(unsignedcharbHex){
if((bHex>=0)&&(bHex<=9))
bHex+=0x30;
elseif((bHex>=10)&&(bHex<=15))//大写字母
bHex+=0x37;
elsebHex=0xff;
returnbHex;
}
/////////////////////////////////////////////////////////////////////
//函数名:com_int()
//功能描述:初始化串口
//函数说明:默认其他参数为[baud_rate],n,8,1
//调用函数:
//全局变量:
//输入:baud_rate波特率
//返回:无
//设计者:牛毅
//修改者:
//版本:
/////////////////////////////////////////////////////////////////////
voidcom_init(unsignedintbaud_rate){
EA=1;ES=1;//ET1=1;
SCON=0x50;/*0x52;//SCON*/
TMOD=0x20;/*0x20;//TMOD*/
TCON=0x60;/*0x60;//TCON*/
PCON=PCON&0x7f;
switch(baud_rate){//波特率设置
case1200:
TL1=0xe8;TH1=0Xe8;break;//1200
case2400:
TL1=0xf4;TH1=0Xf4;break;//2400
case4800:
TL1=0xfa;TH1=0Xfa;break;//4800
case9600:
TL1=0xfd;TH1=0Xfd;break;//9600
case19200:
PCON=PCON|0x80;TL1=0xfd;TH1=0Xfd;break;//19200
case38400:
PCON=PCON|0x80;TL1=0xfe;TH1=0Xfe;break;//38400
default:
TL1=0xfd;TH1=0Xfd;break;//9600
}
}
/////////////////////////////////////