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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2720|回復: 1
收起左側

請教51單片機多機通信問題

[復制鏈接]
ID:161562 發表于 2017-1-13 18:51 | 顯示全部樓層 |閱讀模式
本人初學單片機,想知道51單片機多機通信,需要遵守哪些協議,是主機發送一次數據,從機應答,返回一次。以此循環?以下是我參考書上寫的程序;但測試時主機能發送完地址,從機響應后,返回來,主機便無反應。
請大神幫忙知道下。

/*************主機*******************/

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

#define SLAVE 0x02 //定義從機的地址
#define BN 16          
uchar rbuf[16];
uchar code tbuf[16] = {"1234567891234567"};//傳輸

void err()//復位信號
{
        SBUF = 0xff;
        while(TI != 1)
        TI=0;
}

uchar master(uchar addr,uchar command
{
        uchar aa,i,p;
        while(1)
        {
                SBUF = SLAVE ; //主機發送從機地址         (主機發送地址后,從機開始檢驗,并返回給主機自己的地址再次確認)
                while(!TI);
                TI=0;
                while(!RI)         
                RI =0;
/**/        P1 = 0xfe;//            主機收到從機的回信         /*********/
                if(SBUF != addr
                {
                        err();           //主機發送復位信號
                }
                else
                {
                //主機收到從機應答地址后,確認地址是否相符,不符合,則發復位信號(TB8=1);符合則TB8=0,主機開始發送數據
                        TB8=0; //清地址標志
                        SBUF = command
                        while(!TI);
                        TI=0;
        /**/        P1 = 0xfd; // 主機發送命令判斷        /***過不來***/
                        while(!RI);          //主機等待接收
                        RI =0;
                        aa = SBUF;
                        if(aa & 0x80 == 0x80) // 若命令未被接收,發復位信號(TB8 = 1)
                        {
                                TB8 =1;
                                err();
                        }
                        else
                        {
                        //        if(command == 0x01) //主機命令從機接收命令
                                {
                                        if((aa & 0x01)== 0x01)
                                        {
                                /**/        P1 = 0xfc;    //從機返回命令
                                                do
                                                {
                                                        p=0;  //清校驗和
                                                        for(i=0;i<BN;i++)
                                                        {
                                                                SBUF=tbuf[i]
                                                                p += tbuf[i] ;//計算校驗和
                                                                while(!TI);
                                                            TI=0;
                                                        }
                                                        SBUF = p ; //發送校驗和        判斷是否完全接收
                                                        while(!TI);
                                                        TI=0;
                                                        while(!RI)         
                                                        RI =0;
                                                }while(SBUF != 0);          //接收不正確則重新發送
                        /**/                P1 = 0xf7; //         從機接收完成
                                                TB8 = 1;   //發地址幀(置地址標志)
                                                return(0);         //結束函數
                                        }
                                        else
                                        {
                                                if((aa&0x02) == 0x02) //主機接受命令,從機準備好發送
                                                {
                                                        while(1)
                                                        {
                                                                p=0;  //清校驗和
                                                                for(i=0;i<BN;i++)
                                                                {
                                                                        while(!RI)         
                                                                    RI =0;
                                                                        rbuf[i]=SBUF
                                                                        p += rbuf[i] ;//計算校驗和
                                                                }
                                                                while(!RI)
                                                                RI =0;
                                                                if(SBUF == p)  //發送校驗和        判斷是否完全接收
                                                                {
                                                                        SBUF =0X00;  //校驗和相同 發00
                                                                        P1 = 0xfc;
                                                                        while(!TI);
                                                                        TI=0;
                                                                        break;
                                                                }
                                                                else
                                                                {
                                                                        SBUF = 0xff; //校驗和不同發0FF 重新接收
                                                                        while(!TI);
                                                                        TI=0;
                                                                }
                                                        }
                                                        TB8 = 1;   //發地址幀(置地址標志)
                                                    return(0);           //結束函數
                                                }
                                        }
                                }
                        }
                               
                }

        }
}
void main()
{
        TMOD = 0x20;  //定時器 T1 方式2
        TL1 = 0xfd;           //9600
        TH1 = 0xfd;
        PCON = 0x00;   //電源寄存器 波特率正常
        TR1 = 1;  //打開定時器
        SCON =0xf8;           //TB8=1;串口工作方式3         SM2=1
        while(1)
        {
          master(SLAVE,0x01);                //01   從機接收數據
          master(SLAVE,0x02);
        }       
}

/**************從機*****************/
#include <reg52.h>       
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define SLAVE 0x02 //定義從機的地址
#define BN 16            //一次傳輸
uchar rbuf[16]; //接收數組變量
uchar tbuf[6]= {"i konw"}; //接收數組變量
bit tready = 0;                   //從機發送準備位 1為準備好
bit rready = 0;                  //從機接收準備位 1為準備好
void str();        //發送數據函數
void sre();          //接收數據函數
bit TR_flag = 0;
bit RE_flag = 0;

void main()
{
        TMOD =0x20;
        TL1 =0xfd;
        TH1 =0xfd;
        PCON = 0x00;
        TR1 =1;
        SCON = 0xf0 ;          //串口3 SM2 = 1;
        ES = 1;
        EA = 1;
        while(1)
        {
                tready= 1;
                rready = 1; //假定準備好接收和發送
                if(RE_flag == 1)
                {
                        P1 = 0x55;           //1 3 5 7
                }
                if(TR_flag == 1)
                {
                        P1 = 0xaa;         // 2 4 6 8
                }
        }
}
/*從機以中斷方式控制和主機的通信*/
void ser() interrupt 4
{
        uchar a ;
        P1 = 0xfe;//*//           ///從機收到主機指令
        RI=0;
        ES=0;
        if(SBUF != SLAVE)
        {
                ES = 1;
                goto reti;
        }
        SM2 = 0
        SBUF = SLAVE; //再次向主機發送本地址
        while(!TI);
        TI=0;
        P1 = 0xfd; //從機確認
        while(!RI);         
        RI=0;
        if(RB8 == 1)
        {
                SM2 = 1;
                ES=1;
                goto reti;
        }         // /*復位信號,回復監聽*/
        a = SBUF;  //接收主機的命令 command
        if(a == 0x01
        {
                P1        = 0xfc;        //判斷是否收到主機命令
                if(rready == 1)
                        SBUF =0x01;
                else
                        SBUF = 0x00;
                while(!TI);
                TI = 0;
                while(!RI);                 //
                RI=0;
                if(RB8 == 1)           //隨時準備接收新的地址
                {
                        SM2 = 1;
                        ES = 1;
                        goto reti;//* 定義一個標簽, 然后告訴你的

                }        //試著刪除,可加上檢驗
                sre(); //接收數據
        }
        else
        {
                if( a == 0x02)  //從機向主機發送數據
                {
                        if(tready == 1)//從機發送狀態準備好
                                SBUF =0x02;
                        else
                                SBUF = 0x00;
                        while(!TI);
                        TI = 0;
                /*        while(!RI);          
                        RI=0;        */
                        if(RB8 == 1)           //隨時準備接收新的地址
                        {
                                SM2 = 1;
                                ES = 1;
                                goto reti;
                    }         // */          //lingshan  kejiashang jianyan
                        str(); //發送數據
             }
                 else
                 {
                         SBUF = 0x80        ; /*命令非法*/
                           while(!TI);
                        TI = 0;
                        SM2 = 1;   //恢復監聽
                        ES = 1;   
                 }
         }
                       
}
void str() //發送數據
{
        uchar p, i;
        tready =0;
        do
        {
                p=0;
                for(i=0;i<BN;i++)
                {
                        SBUF=tbuf[i]
                        p += tbuf[i] ;//計算校驗和
                        while(!TI);
                        TI=0;
                /*        while(!RI);
                        RI=0;*/
                }
                SBUF = p ; //發送校驗和        判斷是否完全接收
                while(!TI);
                TI=0;
                while(!RI)         
                RI =0;
        }while(SBUF != 0);
        TR_flag = 1;//發送完成
         SM2 = 1;
         ES = 1;
}
void sre()         //接收數據
{
        uchar p , i ;
        rready =0;   //////*////
        while(1)
        {
                p=0;  //清校驗和
                for(i=0;i<BN;i++)
                {
                        while(!RI)          //主機等待接收
                    RI =0;
                        rbuf[i]=SBUF
                        p += rbuf[i] ;//計算校驗和
                }
                while(!RI)          //從機等待接收主機的 返回值 jiaoyanhe
                RI =0;
                if(SBUF == p)  //發送校驗和        判斷是否完全接收
                {
                        SBUF =0X00;  //校驗和相同 發00
                        RE_flag = 1;
                        break;
                }
                else
                {
                        SBUF = 0xff; //校驗和不同發0FF 重新接收
                        while(!TI);
                        TI=0;
                }
        }

        SM2 = 1;
        ES = 1;
}                 







回復

使用道具 舉報

ID:829862 發表于 2022-2-7 15:03 | 顯示全部樓層
:'(:loveliness::lol
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 东京久久 | 国产日韩精品一区 | 国产高清美女一级a毛片久久w | 中文字幕一区二区三区四区五区 | 国产精品成人一区二区 | 久久免费视频观看 | 久久久精品一区 | 久久精品久久久久久 | 久久久久久久久久久久久9999 | 精品一区在线免费观看 | 久久精品国产一区二区电影 | 精品亚洲视频在线 | 亚洲国产精品99久久久久久久久 | 99re免费| 久久久女女女女999久久 | 国产69精品久久99不卡免费版 | 午夜精品网站 | av中文字幕在线 | 成人亚洲| 色香婷婷 | 国产精品免费一区二区三区 | 亚洲欧洲激情 | 日韩手机在线视频 | 亚洲精品日韩精品 | 自拍亚洲| 黄网站在线播放 | 国产一区免费视频 | 伊人狠狠干| 一区二区三区免费观看 | 欧美国产激情二区三区 | 国产精品一区二区不卡 | 一区二区亚洲 | 艹逼网| 午夜成人在线视频 | www.一区二区三区 | www.久久| 日韩视频国产 | 欧美一区二区在线观看视频 | 色婷婷综合久久久中文字幕 | 蜜臀网 | 国产欧美一区二区三区在线看蜜臀 |