微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机多机通信协议

51单片机多机通信协议

时间:11-30 来源:互联网 点击:
做自己以前没做过的东西,总会有各种踌躇,害怕做不出来,其实要是真的开始去做了,问题就解决大半了。 在家没网,就开始写了, 熬了两夜,加一个半天,总算是完成了通信协议,经调试,可以正常工作。 如果有孩子也要做这个,可以参考一下哈! 别的不多说,贴代码。

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

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

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

#include "basic.h"

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

//宏定义

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

#define EN_DATASEND TB8=0;//发送数据

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

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

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

#define S_MOK 0xf3//从到主准备完成,主机发送的反馈信息

#define STOP 0xf4//主机到从机发送结束

#define ERROR 0xf5//错误

#define Response 0xf6//应答信号

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

#define OK 0xf8

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

//数据定义

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

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

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

uchar Address;//呼叫从机地址

uchar temp=0;//SBUF缓存

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

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

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

void Uart1_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;

void SendByte (uchar date)

{

//EN_DATASEND;//TB8=0;

TB8=1;

SBUF=date;

while(!TI);

TI=0;

}

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

//寻址从机

void Search(uchar ADD)

{

//EN_ADDSEND;

TB8=1;

SBUF=ADD;

while(!TI);

TI=0;

}

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

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

{

state=1;

ES=1;

Position=m;

Search(add);

}

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

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

{

state=4;

ES=1;

Position=m;

Search(add);

}

void M_S_Send(uchar add,uchar *m)//主机到从机整个过程

{

M_S_Protocol(add,m);

while(state);

ES=0;

}

void S_M_Send(uchar add,uchar *m)//从机到主机的整个过程

{

S_M_Protocol(add,m);

while(state);

ES=0;

}

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

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

void main()

{

Uart1_Init();

while(1)

{

S_M_Send(0x01,CMD);

}

}

void UART1() interrupt 4

{

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

temp=SBUF;

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

{

switch(state)

{

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

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

case 1:

{

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

{

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

state=2; //转换状态

break;

}

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

{

state=0;

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

break;

}*/

break;

}

case 2:

{

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

{

state=3;

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

break;

}

break;

}

case 3:

{

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

{

if(Position-CMD<19)//数组长度判断

{

Position++;

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

break;

}

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

{

state=0;

SendByte(STOP);

break;

}

}

break;

}

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

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

case 4:

{

if(temp==Response

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top