51单片机通信协议
bHex += 0x30; else if((bHex>=10)&&(bHex<=15))//大写字母 bHex += 0x37; else bHex = 0xff; return bHex; }
///////////////////////////////////////////////////////////////////// //函 数 名:com_int() //功能描述:初始化串口 //函数说明:默认其他参数为[baud_rate],n,8,1 //调用函数: //全局变量: //输 入:baud_rate 波特率 //返 回:无 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// void com_init(unsigned int baud_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) { //波特率设置 case 1200: TL1=0xe8;TH1=0Xe8;break; //1200 case 2400: TL1=0xf4;TH1=0Xf4;break; //2400 case 4800: TL1=0xfa;TH1=0Xfa;break; //4800 case 9600: TL1=0xfd;TH1=0Xfd;break; //9600 case 19200: PCON=PCON|0x80;TL1=0xfd;TH1=0Xfd;break; //19200 case 38400: PCON=PCON|0x80;TL1=0xfe;TH1=0Xfe;break; //38400 default: TL1=0xfd;TH1=0Xfd;break;//9600 } }
///////////////////////////////////////////////////////////////////// //公司名称:*** //模 块 名:protocol.c //创 建 者:牛毅 //修 改 者: //功能描述:中断方式:本程序为 mcu 的串口通讯提供(贞结构)函数接口,包括具体协议部 分 //其他说明:只提供对 AT89c51 具体硬件的可靠访问接口 //版 本:1.0 //信 息:QQ 75011221 /////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// //函 数 名:HexToChar() //功能描述:把 16 进制转换为 ASCII 字符 //函数说明: //调用函数: //全局变量: //输 入:16 进制 //返 回:ASCII 字符 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// unsigned char HexToChar(unsigned char bHex) { if((bHex>=0)&&(bHex<=9))
while(RI==0); RI=0; return SBUF; }
///////////////////////////////////////////////////////////////////// //函 数 名:CharToHex() //功能描述:把 ASCII 字符转换为 16 进制 //函数说明: //调用函数: //全局变量: //输 入:ASCII 字符 //返 回:16 进制 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// unsigned char CharToHex(unsigned char bChar) { if((bChar>=0x30)&&(bChar<=0x39)) bChar -= 0x30; else if((bChar>=0x41)&&(bChar<=0x46))//大写字母 bChar -= 0x37; else if((bChar>=0x61)&&(bChar<=0x66))//小写字母 bChar -= 0x57; else bChar = 0xff; return bChar; }
///////////////////////////////////////////////////////////////////// //函 数 名:resend_frame() //功能描述:发送重发帧 //函数说明:通知 PC 重发 //调用函数: //全局变量: //输 入:无 //返 回:无 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// void resend_frame(void) { send(F_ST1); send(F_ST2); send(F_C); send(F_SPACE); send(F_SPACE);//发送效验和 send(F_END); }
//public 变量 unsigned char databuf[FIELD_MAXBUF],errframe_cnt; //函数
///////////////////////////////////////////////////////////////////// //函 数 名:send() //功能描述:向串口发送一个字符 //函数说明: //调用函数: //全局变量: //输 入:ch-要发送的 ASCII 字符 //返 回:无 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// void send(unsigned char ch) { SBUF=ch; while(TI==0); TI=0; }
///////////////////////////////////////////////////////////////////// //函 数 名:receive() //功能描述:从串口接收一个字符 //函数说明: //调用函数: //全局变量: //输 入:无 //返 回:一个 ASCII 字符 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// unsigned char receive(void) {
//常数 #define S_MAXBUF 16 #define FIELD_MAXBUF 48
//接收/发送数据的最大缓存量 //最小场缓存,可以大于 48 字节,因为协议是以 20 字节为
单位传输的 #define communicationing P1_7 //正在通讯(1)标志 #define ERRFRAME_MAX 5 //连续 NOFRAME_CNT 次帧不正确 #define ERR_NOCNTMAX_RESEND if(++errframe_cnt<=ERRFRAME_MAX)resend_frame(); else errframe_cnt=communicationing=0; //若超过 ERRFRAME_MAX 次则令通讯停止 ERR_NOCNTMAX_RESEND
///////////////////////////////////////////////////////////////////// //函 数 名:quit_frame() //功能描述:发送放弃帧 //函数说明:通知 PC 放弃通讯 //调用函数: //全局变量: //输 入:无 //返 回:无 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// void quit_frame(void) { send(F_ST1); send(F_ST2); send(F_Q); send(F_ERR1); send(F_ERR1);//发送效验和 send(F_END); }
51 串口通信协议(新型篇)
C51 编程:这是网友牛毅编的一个 C51 串口通讯程序!
//PCຫໍສະໝຸດ Baidu读 MCU 指令结构:(中断方式,ASCII 码表示) //帧: 帧头标志|帧类型|器件地址|启始地址|长度 n|效验和|帧尾标志 //值: 'n' 'y'| 'r' | 0x01 | x | x | x |0x13 0x10 //字节数: 2 | 1 | 1 | 1 | 1 | 1 | 2 //求和:
#include <reg51.h>
#include <config.h> //预定义 //帧 #define F_ST1 0x6e //帧头标志 n #define F_ST2 0x79 //帧头标志 y #define F_R 0x72 //帧类型 读 r #define F_W 0x77 //帧类型 写 w #define F_D 0x64 //帧类型 数据帧 d #define F_B 0x62 //帧类型 写回应帧 b #define F_C 0x63 //帧类型 重发命令帧 c #define F_Q 0x71 //帧类型 放弃帧 q #define F_ADDR 0x31 //器件地址 0-9 #define F_END 0x7a //帧尾标志 z #define F_SPACE 0x30 //空标志 0 #define F_ERR1 0x31 //错误标志 1,flagerr 1 #define F_ERR2 0x32 //错误标志 2 2
///////////////////////////////////////////////////////////////////// //函 数 名:com_int() //功能描述:串口中断 //函数说明: //调用函数: //全局变量: //输 入:无 //返 回:无 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// void com_int()interrupt 4 { unsigned char i,csaddr,clen,csum,tempbuf[S_MAXBUF]; csum=0; if(receive()==F_ST1) {//是侦 if(receive()==F_ST2) {//头判断完 communicationing=1;//设置通讯状态为正常 即启动通讯 switch(receive()) { case F_R://是读指令帧 r if(receive()==F_ADDR) { P1_2=!P1_2;//地址正确 csaddr=CharToHex(receive())<<4; csaddr+=CharToHex(receive()); clen=CharToHex(receive())<<4;clen+=CharToHex(receive()); csum=csaddr+clen; i=CharToHex(receive())<<4;i+=CharToHex(receive()); if(i==csum) {//效验和正确 if(receive()==F_END) {//结束标志正确 //开始发送数据帧 csum=0; send(F_ST1); send(F_ST2); send(F_D); send(HexToChar((clen&0xf0)>>4)); send(HexToChar(clen&0x0f)); csum+=clen; for(i=0;i<clen;i++)