欢迎来到天天文库
浏览记录
ID:10900168
大小:131.50 KB
页数:22页
时间:2018-07-08
《51单片机实现的485通讯程序》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、51单片机实现的485通讯程序#ifndef__485_C__#define__485_C__#include#include#defineunsignedcharuchar#defineunsignedintuint/*通信命令*/#define__ACTIVE_0x01//主机询问从机是否存在#define__GETDATA_0x02//主机发送读设备请求#define__OK_0x03//从机应答#define__STATUS_0x04//从机发送设备状态信息#define__MAXSIZE0x08
2、//缓冲区长度#define__ERRLEN12//任何通信帧长度超过12则表示出错uchardbuf[__MAXSIZE];//该缓冲区用于保存设备状态信息uchardev;//该字节用于保存本机设备号sbitM_DE=P1^0;//驱动器使能,1有效sbitM_RE=P1^1;//接收器使能,0有效voidget_status();//调用该函数获得设备状态信息,函数代码未给出voidsend_data(uchartype,ucharlen,uchar*buf);//发送数据帧bitrecv_cmd(uchar*type);//接收主机命
3、令,主机请求仅包含命令信息voidsend_byte(ucharda);//该函数发送一帧数据中的一个字节,由send_data()函数调用voidmain(){uchartype;ucharlen;/*系统初始化*/P1=0xff;//读取本机设备号dev=(P1>>2);TMOD=0x20;//定时器T1使用工作方式2TH1=250;//设置初值TL1=250;TR1=1;//开始计时PCON=0x80;//SMOD=1SCON=0x50;//工作方式1,波特率9600bps,允许接收ES=0;//关闭串口中断IT0=0;//外部中断0使
4、用电平触发模式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);//发送设备状态
5、信息break;default:break;//命令类型错误,丢弃当前帧后返回}}}voidREADSTATUS()interrupt0using1//产生外部中断0时表示设备状态发生改变,该函数使用寄存器组1{get_status();//获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一字节置0表示数据结束}/*该函数接收一帧数据并进行检测,无论该帧是否错误,函数均会返回*函数参数type保存接收到的命令字*当接收到数据帧错误或其地址位不为0时(非主机发送帧),函数返回0,反之返回1*/bitrecv_cmd(uchar*typ
6、e){bitdb=0;//当接收到的上一个字节为0xdb时,该位置位bitc0=0;//当接收到的上一个字节为0xc0时,该位置位uchardata_buf[__ERRLEN];//保存接收到的帧uchartmp;ucharecc=0;uchari;M_DE=0;//置发送禁止,接收允许M_RE=0;/*接收一帧数据*/i=0;while(!c0)//循环直至帧接收完毕{RI=0;while(!RI);tmp=SBUF;RI=0;if(db==1)//接收到的上一个字节为0xdb{switch(tmp){case0xdd:data_buf[i
7、]=0xdb;//0xdbdd表示0xdbecc=ecc^0xdb;db=0;break;case0xdcdata_buf[i]=0xc0;//0xdbdc表示0xc0ecc=ecc^0xc0;db=0;break;defaultreturn0;//帧错误,返回}i++;}switch(tmp)//正常情况{case0xc0://帧结束c0=1;break;case0xdb://检测到转义字符db=1;break;default://普通数据data_buf[i]=tmp;//保存数据ecc=ecc^tmp;//计算校验字节i++;}if(i
8、==__ERRLEN)//帧超长,错误,返回return0;}/*判断帧是否错误*/if(i<4)//帧过短,错误,返回return0;if(ecc!=0)//校验
此文档下载收益归作者所有