《通信程序单片机.doc》由会员分享,可在线阅读,更多相关《通信程序单片机.doc(8页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、#include#include#define uchar unsigned char #define uint unsigned int/*通信命令*/#define _ACTIVE_ 0x01 / 主机询问从机是否存在#define _GETDATA_ 0x02 /主机发送读设备请求#define _OK_ 0x03 /从机应答#define _STATUS_ 0x04 /从机发送设备状态信息#define _MAXSIZE 0x08 /缓冲区长度#define _ERRLEN 12 /任何通信帧长度超过12那么表示出错uchar dbufMAXSIZE ;/该缓冲区用于保存设备状态信息u
2、char 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 typ
3、e; uchar len; /*系统初始化*/ P1 = 0xff ; /读取本机设备号 dev = (P12); TMOD = 0x20; /定时器T1使用方式2 TH1 = 250; TL1 = 250; TR1 = 1; /开场计时 PCON = 0x80; /SMOD = 1; SCON = 0x50; /工作方式1,波特优选法9600bps,允许接收 ES = 0; / 关闭串品中断 IT0 = 0; /外部中断0使有电平触发模式 EX0 = 1; / 开启外部中断0 EA = 0; /开启总中断 /*主程序流程*/ while(1) if(recv_cmd(&type) =0) /
4、发送帧错误或帧地址与本机地址不符,丢弃当前帧后返回 continue; switch(type) case _ACTIVE_: /主机询问从机是否存在 send_data(_OK_,0,dbuf); / 发送应答信息,这里的buf 的内容并未用到 break; case _GETDATA_: /主机发送读设备请求 len = strlen(dbuf); snd_data(_STATUS_,len,dbuf) ; / 发送设备信息 break; default: break; /命令类型错误,丢弃当前帧返回void READSTATUS() interrput 0 using 1 /产生外部中断
5、0时表示设备状态发生改变,该函数使用存放器组1 get_status(); /获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一个字节置0表示数据完毕/*该函数接收一帧数据度进展检测,无论该帧是否错误,函数均会返回。*函数参数type保存接收到的命令字*当接收的数扭帧错误或其地址位不为0时非主机发送帧,快活数返回0,反之返回1bit recv_cmd(uchar *type) bit db = 0; /当接收到的上一个字节为0xdb时,该位置位 bit c0 = 0; /当接慢到的上一个字节为0xc0时,该位置位 uchar data_buf_ERRLEN; /保存接收到的帧 uch
6、ar 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 swithc(tmp) case 0xdd: data_bufi = 0xdb; /0xdbdd 表示0xdbecc = ecc0xdb;db = 0;break; case 0xdc: data_bufi = 0xc0; /0xdbdc 表示0xc0ecc = 0
7、;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) /校验错误,返回 re
8、turn 0; if(data_bufi!= 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);
9、/发送命令字 ecc = ecctype; send_byte(len); / 发送长度 ecc = ecclen; for(i =0;ilen;i+) send_byte(*buf); ecc = ecc(*buf); buff+; 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;第 8 页
限制150内