#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;
}
}