新聞中心

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

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

        作者: 時間:2016-11-30 來源:網絡 收藏
        //-----------------------------------------------------------------------
        //----------------接收部分---------------------------------------------
        case 4:
        {
        if(temp==Response)//呼叫從機得到回應
        {
        state=5;//轉換狀態(tài)
        SendByte(S_M);//發(fā)送從機到主機命令
        break;
        }
        /*else//無回應,停止此次傳輸
        {
        state=0;
        SendByte(STOP);
        break;
        } */
        else
        break;
        }
        case 5:
        {
        if(temp==OK)//發(fā)送S_M得到回應
        {
        state=6;//轉換狀態(tài)
        SendByte(S_MOK);//準備完成
        break;
        }
        /*else //無回應,停止通信
        {
        state=0;
        SendByte(STOP); //發(fā)送停止命令
        break;
        }*/
        else
        break;
        }
        case 6:
        {
        if(Position-CMD<20) //數組溢出判斷
        {
        *Position=temp;//接收數據
        Position++;
        SendByte(CONTINUE); //要求從機繼續(xù)發(fā)送數據
        break;
        }
        else//超出數組,停止通信
        {
        state=0;
        SendByte(STOP);
        break;
        }
        }
        default:
        break;
        }
        }
        }


        //-----------------------------------------------
        //從機程序,從機接收信息,所以用中斷法會更便于反饋和執(zhí)行命令
        //-------------------------------
        #include "basic.h"

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

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

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

        #define ERROR 0xf5//錯誤
        #define Response 0xf6//應答信號
        #define CONTINUE 0xf7//接受數據之后給對方發(fā)送的反饋,請求繼續(xù)
        #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,};//從機返回的狀態(tài)值
        uchar CMD[20]={0};//主機給從機發(fā)送的命令
        uchar state=0;//狀態(tài)值,進行中斷判斷
        uchar ADDR;//呼叫從機地址
        uchar temp=0;//SBUF緩存
        uchar *Position=0;//數據指針,指定數據更新的位置

        //------------------------------------------
        //STC12具有7字節(jié)全球唯一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為波特率發(fā)生器
        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;//打開串口中斷
        }
        //------------------------------------------
        //查詢法發(fā)送一個字
        void SendByte (uchar date)
        {
        ES=0;//關斷串口中斷
        EN_DATASEND;
        SBUF=date;
        while(!TI);
        TI=0;
        ES=1; //打開串口中斷
        }

        //主函數,可以用大循環(huán)只執(zhí)行全局數組命令,而中斷接收并修改全局命令命令
        void main()
        {
        All_Init();
        Position=DATA;
        //SendCmd(DATA);
        while(1);
        {
        }
        }

        //串口1中斷服務程序,用state進行狀態(tài)判斷處理
        void UART1() interrupt 4
        {
        RI=0;
        temp=SBUF;//讀取數據
        if (state)
        {
        switch (state)
        {
        case 1:
        if(temp==M_S)//主機發(fā)送到從機,從機準備好接收數據
        {
        SendByte(M_SOK);//發(fā)送應答
        state=2;//更換狀態(tài)
        break;
        }
        else if(temp==S_M)//主機要求從機發(fā)數據
        {
        SendByte(OK);//回應主機
        state=3;//轉換狀態(tài)
        Position=DATA;
        break;
        }
        else if(temp==STOP)
        {
        SM2=1;
        state=0;
        break;
        }
        break;
        case 2:
        {
        if(temp==STOP)//停止符判定,回到待機狀態(tài)
        {
        state=0;
        SM2=1;
        break;
        }
        DATA[1]=temp;//接收數據
        SendByte(CONTINUE);//接收數據后回應
        //SendByte(DATA[1]);//串口測試用的
        break;
        }
        case 3:
        {
        switch(temp)
        {
        case S_MOK://主機準備完成
        {
        SendByte(*Position);//發(fā)送數據
        break;
        }
        case CONTINUE:
        {
        Position++;
        SendByte(*Position);//發(fā)送數據
        break;
        }
        case STOP:// 停止命令,返回待機狀態(tài)
        {
        state=0;
        SM2=1;
        break;
        }
        }
        }
        }
        }
        if(RB8==1)//判斷尋址
        {
        if(temp==ADDR)//進行地址判斷
        {
        SM2=0;//從機響應,清除SM2
        SendByte(Response);//發(fā)送應答
        state=1;//更換狀態(tài)
        }
        else//用于主機呼叫從機之后,錯誤的呼叫其他從機,則使該機處于待機狀態(tài)
        {
        SM2=1;
        state=0;
        }
        }
        }

        上一頁 1 2 下一頁

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 大连市| 钟祥市| 南靖县| 凌云县| 上思县| 娱乐| 长兴县| 丰顺县| 改则县| 德惠市| 监利县| 东平县| 巨野县| 六安市| 永新县| 建阳市| 平泉县| 陕西省| 尼木县| 察雅县| 治县。| 金溪县| 河北区| 叙永县| 中超| 竹溪县| 阳曲县| 资源县| 左云县| 井冈山市| 深水埗区| 湘潭县| 仲巴县| 隆尧县| 扎兰屯市| 濮阳市| 三台县| 大理市| 山阳县| 芷江| 定州市|