资源预览内容
第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
亲,该文档总共5页全部预览完了,如果喜欢就下载吧!
资源描述
#ifndef _485_C_#define _485_C_#include #include #define unsigned char uchar#define unsigned int uint/* 通信命令 */#define _ACTIVE_ 0x01 / 主机询问从机是否存在#define _GETDATA_ 0x02 / 主机发送读设备请求#define _OK_ 0x03 / 从机应答#define _STATUS_ 0x04 / 从机发送设备状态信息#define _MAXSIZE 0x08 / 缓冲区长度#define _ERRLEN 12 / 任何通信帧长度超过12则表示出错uchar dbuf_MAXSIZE; / 该缓冲区用于保存设备状态信息uchar dev; / 该字节用于保存本机设备号sbit M_DE = P10; / 驱动器使能,1有效sbit M_RE = P11; / 接收器使能,0有效void get_status(); / 调用该函数获得设备状态信息,函数代码未给出void send_data(uchar type, uchar len, uchar *buf); / 发送数据帧bit recv_cmd(uchar *type); / 接收主机命令,主机请求仅包含命令信息void send_byte(uchar da); / 该函数发送一帧数据中的一个字节,由send_data()函数调用void main()uchar type;uchar len;/* 系统初始化 */P1 = 0xff; / 读取本机设备号dev = (P12);TMOD = 0x20; / 定时器T1使用工作方式2TH1 = 250; / 设置初值TL1 = 250;TR1 = 1; / 开始计时PCON = 0x80; / SMOD = 1SCON = 0x50; / 工作方式1,波特率9600bps,允许接收ES = 0; / 关闭串口中断IT0 = 0; / 外部中断0使用电平触发模式EX0 = 1; / 开启外部中断0EA = 1; / 开启中断/* 主程序流程 */while(1) / 主循环 if(recv_cmd(&type) = 0) / 发生帧错误或帧地址与本机地址不符,丢弃当前帧后返回 continue; switch(type) case _ACTIVE_: / 主机询问从机是否存在 send_data(_OK_, 0, dbuf); / 发送应答信息,这里buf的内容并未用到 break; case _GETDATA_: len = strlen(dbuf); send_data(_STATUS_, len, dbuf); / 发送设备状态信息 break; default: break; / 命令类型错误,丢弃当前帧后返回 void READSTATUS() interrupt 0 using 1 / 产生外部中断0时表示设备状态发生改变,该函数使用寄存器组1get_status(); / 获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一字节置0表示数据结束/* 该函数接收一帧数据并进行检测,无论该帧是否错误,函数均会返回* 函数参数type保存接收到的命令字* 当接收到数据帧错误或其地址位不为0时(非主机发送帧),函数返回0,反之返回1*/bit recv_cmd(uchar *type)bit db = 0; / 当接收到的上一个字节为0xdb时,该位置位bit c0 = 0; / 当接收到的上一个字节为0xc0时,该位置位uchar data_buf_ERRLEN; / 保存接收到的帧uchar tmp;uchar ecc = 0;uchar i;M_DE = 0; / 置发送禁止,接收允许M_RE = 0;/* 接收一帧数据 */i = 0;while(!c0) / 循环直至帧接收完毕 RI = 0; while(!RI); tmp = SBUF; RI = 0; if(db = 1) / 接收到的上一个字节为0xdb switch(tmp) case 0xdd: data_bufi = 0xdb; / 0xdbdd表示0xdb ecc = ecc0xdb; db = 0; break; case 0xdc data_bufi = 0xc0; / 0xdbdc表示0xc0 ecc = ecc0xc0; db = 0; break; default return 0; / 帧错误,返回 i+; switch(tmp) / 正常情况 case 0xc0: / 帧结束 c0 = 1; break; case 0xdb: / 检测到转义字符 db = 1; break; default: / 普通数据 data_bufi = tmp; / 保存数据 ecc = ecctmp; / 计算校验字节 i+; if(i = _ERRLEN) / 帧超长,错误,返回 return 0;/* 判断帧是否错误 */if(i4) / 帧过短,错误,返回 return 0;if(ecc != 0) / 校验错误,返回 return 0;if(data_buf0 != dev) / 非访问本机命令,错误,返回 return 0;*type = data_buf1; / 获得命令字return 1; / 函数成功返回/* 该函数发送一帧数据帧,参数type为命令字、len为数据长度、buf为要发送的数据内容 */void send_data(uchar type, uchar len, uchar *buf)uchar i;uchar ecc = 0; / 该字节用于保存校验字节M_DE = 1; / 置发送允许,接收禁止M_RE = 1;send_byte(dev); / 发送本机地址ecc = dev;send_byte(type); / 发送命令字ecc = ecctype;send_byte(len); / 发送长度ecc = ecclen;for(i=0; ilen; i+) / 发送数据 send_byte(*buf); ecc = ecc(*buf); buf+;send_byte(ecc); / 发送校验字节TI = 0; / 发送帧结束标志SBUF = 0xc0;while(!TI);TI = 0;/* 该函数发送一个数据字节,若该字节为0xdb,则发送0xdbdd,若该字节为0xc0则,发送0xdbdc */void send_byte(uchar da)switch(da) case 0xdb: / 字节为0xdb,发送0xdbdd TI = 0; SBUF = 0xdb; while(!TI); TI = 0; SBUF = 0xdd; while(!TI) TI = 0; break; case 0xc0: / 字节为0xc0,发送0xdbdc TI = 0; SBUF = 0xdb; while(!TI); TI = 0; SBUF = 0xdc; while(!TI) TI = 0; break; default: / 普通数据则直接发送 TI = 0; SBUF = da; while(!TI); TI = 0;#endif
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号