51单片机多机通信协议.docx

上传人:b****8 文档编号:9339857 上传时间:2023-02-04 格式:DOCX 页数:16 大小:17.61KB
下载 相关 举报
51单片机多机通信协议.docx_第1页
第1页 / 共16页
51单片机多机通信协议.docx_第2页
第2页 / 共16页
51单片机多机通信协议.docx_第3页
第3页 / 共16页
51单片机多机通信协议.docx_第4页
第4页 / 共16页
51单片机多机通信协议.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

51单片机多机通信协议.docx

《51单片机多机通信协议.docx》由会员分享,可在线阅读,更多相关《51单片机多机通信协议.docx(16页珍藏版)》请在冰豆网上搜索。

51单片机多机通信协议.docx

51单片机多机通信协议

51单片机多机通信协议

做自己以前没做过的东西,总会有各种踌躇,害怕做不出来,其实要是真的开始去做了,问题就解决大半了。

 在家没网,就开始写了, 熬了两夜,加一个半天,总算是完成了通信协议,经调试,可以正常工作。

 如果有孩子也要做这个,可以参考一下哈!

 别的不多说,贴代码。

//-------------------------------------------------

//主机程序,主机座控制,用中断法

//-----------------------------------------------

#include"basic.h"

//---------------------------------------------------

//宏定义

#defineEN_ADDSEND TB8=1;//发送寻址,搜寻从机

#defineEN_DATASENDTB8=0;//发送数据

#defineM_S    0Xf0//握手后的命令字,主机到从机

#defineS_M    0Xf1//握手后的命令字,从机到主机

#defineM_SOK   0Xf2//主到从准备完成,从机发送的反馈信息

#defineS_MOK0xf3//从到主准备完成,主机发送的反馈信息

#defineSTOP0xf4//主机到从机发送结束

#defineERROR0xf5//错误

#defineResponse0xf6//应答信号

#defineCONTINUE0xf7//接受数据之后给对方发送的反馈,请求继续

#defineOK0xf8

//--------------------------------------------------

//数据定义

ucharDATA[20]={0};//从机返回的状态值

ucharCMD[20]={0x44,0x44,0x44,0x55,0x55,0x55,0x47,0x45,0x65,0x35,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,};//主机给从机发送的命令

ucharstate=0;//状态值,进行中断判断

ucharAddress;//呼叫从机地址

uchartemp=0;//SBUF缓存

uchar*Position=0;//数据指针,指定数据更新的位置

//---------------------------------------------

//串口1初始化,用于和从机通讯

voidUart1_Init(void)//9600bps@11.0592MHz

{

PCON&=0x7F;//波特率不倍速

SCON=0xD0;//9位数据,可变波特率

AUXR|=0x40;//定时器1时钟为Fosc,即1T

AUXR&=0xFE;//串口1选择定时器1为波特率发生器

TMOD&=0x0F;//清除定时器1模式位

TMOD|=0x20;//设定定时器1为8位自动重装方式

TL1=0xDC;//设定定时初值

TH1=0xDC;//设定定时器重装值

ET1=0;//禁止定时器1中断

TR1=1;//启动定时器1

EA=1;//总中断启动

SM2=0;

ES=1;

}

//------------------------------------------

//查询法发送一个数据,TB8=0;

voidSendByte(uchardate)

{

//EN_DATASEND;//TB8=0;

TB8=1;

SBUF=date;

while(!

TI);

TI=0;

}

//-----------------------------------

//寻址从机

voidSearch(ucharADD)

{

//EN_ADDSEND;

TB8=1;

SBUF=ADD;

while(!

TI);

TI=0;

}

//主机向从机发送命令 //因为主机为控制端,为便于控制从机,所以选择用查询法而不选用中断

voidM_S_Protocol(ucharadd,uchar*m)//三个参量分别为从机地址,命令的字节数,命令的位置

{

state=1;

ES=1;

Position=m;

Search(add);

}

//主机接收从机状态,同样也为查询法不用中断

voidS_M_Protocol(ucharadd,uchar*m)//三个参量分别为从机地址,命令的字节数,命令的位置

{

state=4;

ES=1;

Position=m;

Search(add);

}

voidM_S_Send(ucharadd,uchar*m)//主机到从机整个过程

{

M_S_Protocol(add,m);

while(state);

ES=0;

}

voidS_M_Send(ucharadd,uchar*m)//从机到主机的整个过程

{

S_M_Protocol(add,m);

while(state);

ES=0;

}

//-----------------------------

//主函数,主机主函数主要用于与GPRS和从机之间做桥接

voidmain()

{

Uart1_Init();

while

(1)

{

S_M_Send(0x01,CMD);

}

}

voidUART1()interrupt4

{

RI=0;//清除中断标志

temp=SBUF;

if(state)//处于传输状态

{

switch(state)

{

//-----------------------------------------------------------------

//---------------------M_S部分--------------------------------

case1:

{

if(temp==Response)//寻址成功

{

SendByte(M_S);//发送M_S命令

state=2; //转换状态

break;

}

/*else//寻址不成功,通信结束,转换为非通信状态

{

state=0;

SendByte(STOP);//发送通信停止命令

break;

}*/

break;

}

case2:

{

if(temp==M_SOK)//M_S得到回应

{

state=3;

SendByte(*Position);//发送第一字节

break;

}

break;

}

case3:

{

if(temp==CONTINUE)//从机继续要求数据

{

if(Position-CMD

{

Position++;

SendByte(*Position);//发送数据

break;

}

else//数组溢出,停止通信

{

state=0;

SendByte(STOP);

break;

}

}

break;

}

//-----------------------------------------------------------------------

//----------------接收部分---------------------------------------------

case4:

{

if(temp==Response)//呼叫从机得到回应

{

state=5;//转换状态

SendByte(S_M);//发送从机到主机命令

break;

}

/*else//无回应,停止此次传输

{

state=0;

SendByte(STOP);

break;

}*/

else

break;

}

case5:

{

if(temp==OK)//发送S_M得到回应

{

state=6;//转换状态

SendByte(S_MOK);//准备完成

break;

}

/*else//无回应,停止通信

{

state=0;

SendByte(STOP); //发送停止命令

break;

}*/

else

break;

}

case6:

{

if(Position-CMD

{

*Position=temp;//接收数据

Position++;

SendByte(CONTINUE);//要求从机继续发送数据

break;

}

else//超出数组,停止通信

{

state=0;

SendByte(STOP);

break;

}

}

default:

break;

}

}

}

//-----------------------------------------------

//从机程序,从机接收信息,所以用中断法会更便于反馈和执行命令

//-------------------------------

#include"basic.h"

//---------------------------------------------------

//宏定义

#defineEN_ADDSEND TB8=1;//发送寻址,搜寻从机

#defineEN_DATASENDTB8=0;//发送数据

#defineM_S    0Xf0//握手后的命令字,主机到从机

#defineS_M    0Xf1//握手后的命令字,从机到主机

#defineM_SOK   0Xf2//主到从准备完成,从机发送的反馈信息

#defineS_MOK0xf3//从到主准备完成,主机发送的反馈信息

#defineSTOP0xf4//主机到从机发送结束

#defineERROR0xf5//错误

#defineResponse0xf6//应答信号

#defineCONTINUE0xf7//接受数据之后给对方发送的反馈,请求继续

#defineOK0xf8

sbitkey=P3^7;

//--------------------------------------------------

//数据定义

ucharDATA[20]={0x12,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,};//从机返回的状态值

ucharCMD[20]={0};//主机给从机发送的命令

ucharstate=0;//状态值,进行中断判断

ucharADDR;//呼叫从机地址

uchartemp=0;//SBUF缓存

uchar*Position=0;//数据指针,指定数据更新的位置

//------------------------------------------

//STC12具有7字节全球唯一ID,将7位的ID加和作为从机地址.(有可能从机地址会重复)

ucharSet_Add()

{

uchar*p;

uchari;

ucharaddr=0;

p=0xf1;//上电后唯一ID起始地址

for(i=0;i

{

addr+=*p;

}

return(addr);

}

//---------------------------------------------

//串口1初始化,用于和从机通讯

voidUart1_Init(void)//9600bps@11.0592MHz

{

PCON&=0x7F;//波特率不倍速

SCON=0xD0;//9位数据,可变波特率

AUXR|=0x40;//定时器1时钟为Fosc,即1T

AUXR&=0xFE;//串口1选择定时器1为波特率发生器

TMOD&=0x0F;//清除定时器1模式位

TMOD|=0x20;//设定定时器1为8位自动重装方式

TL1=0xDC;//设定定时初值

TH1=0xDC;//设定定时器重装值

ET1=0;//禁止定时器1中断

TR1=1;//启动定时器1

}

voidAll_Init()

{

Uart1_Init();

ADDR=Set_Add();

EA=1;//打开总中断

ES=1;//打开串口中断

}

//------------------------------------------

//查询法发送一个字

voidSendByte(uchardate)

{

ES=0;//关断串口中断

EN_DATASEND;

SBUF=date;

while(!

TI);

TI=0;

ES=1;//打开串口中断

}

//主函数,可以用大循环只执行全局数组命令,而中断接收并修改全局命令命令

voidmain()

{

All_Init();

Position=DATA;

//SendCmd(DATA);

while

(1);

{

}

}

//串口1中断服务程序,用state进行状态判断处理

voidUART1()interrupt4

{

RI=0;

temp=SBUF;//读取数据

if(state)

{

switch(state)

{

case1:

if(temp==M_S)//主机发送到从机,从机准备好接收数据

{

SendByte(M_SOK);//发送应答

state=2;//更换状态

break;

}

elseif(temp==S_M)//主机要求从机发数据

{

SendByte(OK);//回应主机

state=3;//转换状态

Position=DATA;

break;

}

elseif(temp==STOP)

{

SM2=1;

state=0;

break;

}

break;

case2:

{

if(temp==STOP)//停止符判定,回到待机状态

{

state=0;

SM2=1;

break;

}

DATA[1]=temp;//接收数据

SendByte(CONTINUE);//接收数据后回应

//SendByte(DATA[1]);//串口测试用的

break;

}

case3:

{

switch(temp)

{

caseS_MOK:

//主机准备完成

{

SendByte(*Position);//发送数据

break;

}

caseCONTINUE:

{

Position++;

SendByte(*Position);//发送数据

break;

}

caseSTOP:

//停止命令,返回待机状态

{

state=0;

SM2=1;

break;

}

}

}

}

}

if(RB8==1)//判断寻址

{

if(temp==ADDR)//进行地址判断

{

SM2=0;//从机响应,清除SM2

SendByte(Response);//发送应答

state=1;//更换状态

}

else//用于主机呼叫从机之后,错误的呼叫其他从机,则使该机处于待机状态

{

SM2=1;

state=0;

}

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1