新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)多機(jī)通信協(xié)議

51單片機(jī)多機(jī)通信協(xié)議

作者: 時(shí)間:2016-11-30 來(lái)源:網(wǎng)絡(luò) 收藏
做自己以前沒(méi)做過(guò)的東西,總會(huì)有各種躊躇,害怕做不出來(lái),其實(shí)要是真的開(kāi)始去做了,問(wèn)題就解決大半了。 在家沒(méi)網(wǎng),就開(kāi)始寫了, 熬了兩夜,加一個(gè)半天,總算是完成了通信協(xié)議,經(jīng)調(diào)試,可以正常工作。 如果有孩子也要做這個(gè),可以參考一下哈! 別的不多說(shuō),貼代碼。


本文引用地址:http://butianyuan.cn/article/201611/324031.htm
//-------------------------------------------------
//主機(jī)程序,主機(jī)座控制,用中斷法
//-----------------------------------------------

#include "basic.h"


//---------------------------------------------------
//宏定義

#define EN_ADDSEND TB8=1;//發(fā)送尋址,搜尋從機(jī)
#define EN_DATASEND TB8=0;//發(fā)送數(shù)據(jù)

#define M_S 0Xf0//握手后的命令字,主機(jī)到從機(jī)
#define S_M 0Xf1//握手后的命令字,從機(jī)到主機(jī)
#define M_SOK 0Xf2//主到從準(zhǔn)備完成,從機(jī)發(fā)送的反饋信息
#define S_MOK 0xf3//從到主準(zhǔn)備完成,主機(jī)發(fā)送的反饋信息
#define STOP 0xf4//主機(jī)到從機(jī)發(fā)送結(jié)束

#define ERROR 0xf5//錯(cuò)誤
#define Response 0xf6//應(yīng)答信號(hào)
#define CONTINUE 0xf7//接受數(shù)據(jù)之后給對(duì)方發(fā)送的反饋,請(qǐng)求繼續(xù)
#define OK 0xf8

//--------------------------------------------------
//數(shù)據(jù)定義
uchar DATA[20]={0};//從機(jī)返回的狀態(tài)值

uchar CMD[20]= {0x44,0x44,0x44,0x55,0x55,0x55,0x47,0x45,0x65,0x35,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,};// 主機(jī)給從機(jī)發(fā)送的命令
uchar state=0;//狀態(tài)值,進(jìn)行中斷判斷
uchar Address;//呼叫從機(jī)地址
uchar temp=0;//SBUF緩存
uchar *Position=0;//數(shù)據(jù)指針,指定數(shù)據(jù)更新的位置

//---------------------------------------------
//串口1初始化,用于和從機(jī)通訊
void Uart1_Init(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0xD0; //9位數(shù)據(jù),可變波特率
AUXR |= 0x40; //定時(shí)器1時(shí)鐘為Fosc,即1T
AUXR &= 0xFE; //串口1選擇定時(shí)器1為波特率發(fā)生器
TMOD &= 0x0F; //清除定時(shí)器1模式位
TMOD |= 0x20; //設(shè)定定時(shí)器1為8位自動(dòng)重裝方式
TL1 = 0xDC; //設(shè)定定時(shí)初值
TH1 = 0xDC; //設(shè)定定時(shí)器重裝值
ET1 = 0; //禁止定時(shí)器1中斷
TR1 = 1; //啟動(dòng)定時(shí)器1
EA=1; //總中斷啟動(dòng)
SM2=0;
ES=1;
}

//------------------------------------------
//查詢法發(fā)送一個(gè)數(shù)據(jù),TB8=0;
void SendByte (uchar date)
{

//EN_DATASEND;//TB8=0;
TB8=1;
SBUF=date;
while(!TI);
TI=0;
}

//-----------------------------------
//尋址從機(jī)
void Search(uchar ADD)
{
//EN_ADDSEND;
TB8=1;
SBUF=ADD;
while(!TI);
TI=0;
}


//主機(jī)向從機(jī)發(fā)送命令 //因?yàn)橹鳈C(jī)為控制端,為便于控制從機(jī),所以選擇用查詢法而不選用中斷
void M_S_Protocol(uchar add,uchar *m)//三個(gè)參量分別為從機(jī)地址,命令的字節(jié)數(shù),命令的位置
{
state=1;
ES=1;
Position=m;
Search(add);
}
//主機(jī)接收從機(jī)狀態(tài),同樣也為查詢法不用中斷
void S_M_Protocol(uchar add,uchar *m)//三個(gè)參量分別為從機(jī)地址,命令的字節(jié)數(shù),命令的位置
{
state=4;
ES=1;
Position=m;
Search(add);
}
void M_S_Send(uchar add,uchar *m)//主機(jī)到從機(jī)整個(gè)過(guò)程
{
M_S_Protocol(add,m);
while(state);
ES=0;
}
void S_M_Send(uchar add,uchar *m)//從機(jī)到主機(jī)的整個(gè)過(guò)程
{
S_M_Protocol(add,m);
while(state);
ES=0;
}
//-----------------------------
//主函數(shù),主機(jī)主函數(shù)主要用于與GPRS和從機(jī)之間做橋接
void main()
{
Uart1_Init();
while(1)
{
S_M_Send(0x01,CMD);
}
}
void UART1() interrupt 4
{
RI=0;//清除中斷標(biāo)志
temp=SBUF;
if(state)//處于傳輸狀態(tài)
{
switch(state)
{
//-----------------------------------------------------------------
//---------------------M_S部分--------------------------------
case 1:
{
if(temp==Response)//尋址成功
{
SendByte(M_S); //發(fā)送M_S命令
state=2; //轉(zhuǎn)換狀態(tài)
break;
}
/*else//尋址不成功,通信結(jié)束,轉(zhuǎn)換為非通信狀態(tài)
{
state=0;
SendByte(STOP);//發(fā)送通信停止命令
break;
}*/
break;
}
case 2:
{
if(temp==M_SOK)//M_S得到回應(yīng)
{
state=3;
SendByte(*Position);//發(fā)送第一字節(jié)
break;
}
break;
}
case 3:
{
if(temp==CONTINUE) //從機(jī)繼續(xù)要求數(shù)據(jù)
{
if(Position-CMD<19)//數(shù)組長(zhǎng)度判斷
{
Position++;
SendByte(*Position);//發(fā)送數(shù)據(jù)
break;

}
else//數(shù)組溢出,停止通信
{
state=0;
SendByte(STOP);
break;
}
}
break;
}
上一頁(yè) 1 2 下一頁(yè)

評(píng)論


技術(shù)專區(qū)

關(guān)閉