找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2745|回復(fù): 1
收起左側(cè)

請(qǐng)教51單片機(jī)多機(jī)通信問(wèn)題

[復(fù)制鏈接]
ID:161562 發(fā)表于 2017-1-13 18:51 | 顯示全部樓層 |閱讀模式
本人初學(xué)單片機(jī),想知道51單片機(jī)多機(jī)通信,需要遵守哪些協(xié)議,是主機(jī)發(fā)送一次數(shù)據(jù),從機(jī)應(yīng)答,返回一次。以此循環(huán)?以下是我參考書上寫的程序;但測(cè)試時(shí)主機(jī)能發(fā)送完地址,從機(jī)響應(yīng)后,返回來(lái),主機(jī)便無(wú)反應(yīng)。
請(qǐng)大神幫忙知道下。

/*************主機(jī)*******************/

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

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

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

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

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

/**************從機(jī)*****************/
#include <reg52.h>       
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define SLAVE 0x02 //定義從機(jī)的地址
#define BN 16            //一次傳輸
uchar rbuf[16]; //接收數(shù)組變量
uchar tbuf[6]= {"i konw"}; //接收數(shù)組變量
bit tready = 0;                   //從機(jī)發(fā)送準(zhǔn)備位 1為準(zhǔn)備好
bit rready = 0;                  //從機(jī)接收準(zhǔn)備位 1為準(zhǔn)備好
void str();        //發(fā)送數(shù)據(jù)函數(shù)
void sre();          //接收數(shù)據(jù)函數(shù)
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; //假定準(zhǔn)備好接收和發(fā)送
                if(RE_flag == 1)
                {
                        P1 = 0x55;           //1 3 5 7
                }
                if(TR_flag == 1)
                {
                        P1 = 0xaa;         // 2 4 6 8
                }
        }
}
/*從機(jī)以中斷方式控制和主機(jī)的通信*/
void ser() interrupt 4
{
        uchar a ;
        P1 = 0xfe;//*//           ///從機(jī)收到主機(jī)指令
        RI=0;
        ES=0;
        if(SBUF != SLAVE)
        {
                ES = 1;
                goto reti;
        }
        SM2 = 0
        SBUF = SLAVE; //再次向主機(jī)發(fā)送本地址
        while(!TI);
        TI=0;
        P1 = 0xfd; //從機(jī)確認(rèn)
        while(!RI);         
        RI=0;
        if(RB8 == 1)
        {
                SM2 = 1;
                ES=1;
                goto reti;
        }         // /*復(fù)位信號(hào),回復(fù)監(jiān)聽(tīng)*/
        a = SBUF;  //接收主機(jī)的命令 command
        if(a == 0x01
        {
                P1        = 0xfc;        //判斷是否收到主機(jī)命令
                if(rready == 1)
                        SBUF =0x01;
                else
                        SBUF = 0x00;
                while(!TI);
                TI = 0;
                while(!RI);                 //
                RI=0;
                if(RB8 == 1)           //隨時(shí)準(zhǔn)備接收新的地址
                {
                        SM2 = 1;
                        ES = 1;
                        goto reti;//* 定義一個(gè)標(biāo)簽, 然后告訴你的

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

        SM2 = 1;
        ES = 1;
}                 







回復(fù)

使用道具 舉報(bào)

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

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表