您的位置 首页 技术

485通讯程序(51单片机)

#include#include#defineucharunsignedchar#defineuintunsignedint/*通信命令*/#define_ACTIVE_0x01//主机询问从机是否存

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

/*通讯指令*/

#define_ACTIVE_0x01//主机问询从机是否存在

#define_GETDATA_0x02//主机发送读设备恳求

#define_OK_0x03//从机应对

#define_STATUS_0x04//从机发送设备状况信息

#define_MAXSIZE0x08//缓冲区长度

#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);//接纳主机指令,主机恳求包括指令信息。

voidsend_byte(ucharda);//该函数发送一帧数据中的一个字节,由send_data()函数调用

voidmain()

{

uchartype;

ucharlen;

/*体系初始化*/

P1=0xff;//读取本机设备号

dev=(P1>>2);

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)//发送帧过错或帧地址与本机地址不符,丢掉当时帧后回来

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;//指令类型过错,丢掉当时帧回来

}

}

}

voidREADSTATUS()interrput0using1//产生外部中止0时表明设备状况产生改动,该函数运用寄存器组1

{

get_status();//取得设备状况信息,并将其存入dbuf指向的存储区,数据最终一个字节置0表明数据完毕

}

/*该函数接纳一帧数据度进行检测,不管该帧是否过错,函数均会回来。

*函数参数type保存接纳到的指令字

*当接纳的数扭帧过错或其地址位不为0时(非主机发送帧),快活数回来0,反之回来1

*/

bitrecv_cmd(uchar*type)

{

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

{

swithc(tmp)

case0xdd:

data_buf[i]=0xdb;//0xdbdd表明0xdb

ecc=ecc^0xdb;

db=0;

break;

case0xdc:

data_buf[i]=0xc0;//0xdbdc表明0xc0

ecc=0;

db=0;

break;

default:

return0;//帧过错,回来

i++;

}

switch(tmp)//正常情况下

{

case0xc0://帧完毕

c0=1;

break;

case0xdb: //检测到转义字符

db=1;

break;

default://一般数据

data_buf[i]=tmp;//保存数据

ecc=ecc^tmp;//核算校验字节

i++;

}

if(i==_ERRLEN)//帧超长,过错,回来

return0;

/*判别帧是否过错*/

if(i<4)//帧过短,过错,回来

return0;

if(ecc!=0)//校验过错,回来

return0;

if(data_buf[i!=dev) //非拜访本机指令,过错,回来

return0;

*type=data_buf[1];//取得指令字

return1;//函数成功回来

}

/*该函数发送一数据帧,参数type为指令字,len为数据长度,buf为要发送的数据内容*/

voidsend_data(uchartype,ucharlen,uchar*buf)

{

uchari;

ucharecc=0;

M_DE=1;//置发送答应,接纳制止

M_RE=1;

send_byte(dev);//发送本机地址

ecc=dev;

send_byte(type);//发送指令字

ecc=ecc^type;

send_byte(len);//发送长度

ecc=ecc^len;

for(i=0;i

{

send_byte(*buf);

ecc=ecc^(*buf);

buff++;

}

send_byte(ecc);//发送校验字节

TI=0;//发送帧完毕标志

SBUF=0xc0;

while(!TI);

TI=0;

}

/*该函数发送一个数据字节,若该字节为0xdb,则发送0xdbdd,若该字节为0xc0,则发送0xdbdc*/

voidsend_byte(ucharda)

{

switch(da)

{

case0xdb://字节为0xdb,发送0xdbdd

TI=0;

SBUF=0xdb;

while(!TI);

TI=0;

SBUF=0xdd;

while(!TI);

TI=0;

break;

case0xc0://字节为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;

}

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/jishu/275281.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部