|
本人初學(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;
}
|
|