久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

51單片機多機通信協議

作者:胡力拼   來源:本站原創   點擊數:  更新時間:2013年11月17日   【字體:

  做自己以前沒做過的東西,總會有各種躊躇,害怕做不出來,其實要是真的開始去做了,問題就解決大半了。  在家沒網,就開始寫了,  熬了兩夜,加一個半天,總算是完成了通信協議,經調試,可以正常工作。  如果有孩子也要做這個,可以參考一下哈!  別的不多說,貼代碼。 

 

//-------------------------------------------------
//主機程序,主機座控制,用中斷法
//-----------------------------------------------

 
#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)//呼叫從機得到回應
{
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;
}
}
 
}
關閉窗口

相關文章

主站蜘蛛池模板: japan25hdxxxx日本 做a的各种视频 | av在线伊人 | 亚洲视频中文字幕 | 成年人免费看 | 久久久久久久综合 | 伊人狠狠干 | 久久久999免费视频 999久久久久久久久6666 | 成人小视频在线 | 午夜电影福利 | 91精品入口蜜桃 | 欧美一区二区在线播放 | 九九久久这里只有精品 | 精品伦精品一区二区三区视频 | 国产精品美女www | 亚洲一区二区三区四区五区午夜 | 欧美一区二区在线免费观看 | 亚洲欧美成人影院 | 久久免费视频在线 | 99久久精品免费看国产四区 | 日本三级网站在线观看 | 日韩毛片| 国产精品久久久久一区二区三区 | 欧美区在线 | 一区二区三区国产 | a欧美| 这里有精品 | 国产区第一页 | 狠狠干av | 91视视频在线观看入口直接观看 | 日韩av在线不卡 | 九色综合网 | 国产欧美精品一区二区 | 91麻豆精品国产91久久久久久久久 | 三级黄视频在线观看 | 国产高清一区二区 | 国产精品久久久久久久久久久久久 | 亚洲一区在线日韩在线深爱 | 日韩视频在线播放 | 亚洲一区二区三区在线 | 日本三级网址 | 中文字幕日韩一区 |