51單片機多機通信協議
//-------------------------------------------------
//主機程序,主機座控制,用中斷法
//-----------------------------------------------
#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;
關鍵詞:
51單片機多機通信協
評論