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

51单片机多机通信协议

时间:11-30 来源:互联网 点击:

)//呼叫从机得到回应

{

state=5;//转换状态

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

break;

}

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

{

state=0;

SendByte(STOP);

break;

} */

else

break;

}

case 5:

{

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

{

state=6;//转换状态

SendByte(S_MOK);//准备完成

break;

}

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

{

state=0;

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

break;

}*/

else

break;

}

case 6:

{

if(Position-CMD<20) //数组溢出判断

{

*Position=temp;//接收数据

Position++;

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

break;

}

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

{

state=0;

SendByte(STOP);

break;

}

}

default:

break;

}

}

}

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

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

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

#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

sbit key=P3^7;

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

//数据定义

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

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

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

uchar ADDR;//呼叫从机地址

uchar temp=0;//SBUF缓存

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

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

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

uchar Set_Add()

{

uchar *p;

uchar i;

uchar addr=0;

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

for(i=0;i<7;i++)

{

addr+=*p;

}

return (addr);

}

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

//串口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

}

void All_Init()

{

Uart1_Init();

ADDR=Set_Add();

EA=1;//打开总中断

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

}

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

//查询法发送一个字

void SendByte (uchar date)

{

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

EN_DATASEND;

SBUF=date;

while(!TI);

TI=0;

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

}

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

void main()

{

All_Init();

Position=DATA;

//SendCmd(DATA);

while(1);

{

}

}

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

void UART1() interrupt 4

{

RI=0;

temp=SBUF;//读取数据

if (state)

{

switch (state)

{

case 1:

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

{

SendByte(M_SOK);//发送应答

state=2;//更换状态

break;

}

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

{

SendByte(OK);//回应主机

state=3;//转换状态

Position=DATA;

break;

}

else if(temp==STOP)

{

SM2=1;

state=0;

break;

}

break;

case 2:

{

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

{

state=0;

SM2=1;

break;

}

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

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

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

break;

}

case 3:

{

switch(temp)

{

case S_MOK://主机准备完成

{

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

break;

}

case CONTINUE:

{

Position++;

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

break;

}

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

{

state=0;

SM2=1;

break;

}

}

}

}

}

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

{

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

{

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

SendByte(Response);//发送应答

state=1;//更换状态

}

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

{

SM2=1;

state=0;

}

}

}

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

网站地图

Top