/* 雙機(jī)點(diǎn)對(duì)點(diǎn)通信的從機(jī)部分 */
#ifndef __P2P_S_C__
#define __P2P_S_C__
#include <AT89X51.H>
#include <STRING.H>
#define __MAX_LEN_ 64 // 數(shù)據(jù)最大長(zhǎng)度
#define _MHZ_ 11 // 設(shè)置單片機(jī)使用的晶振頻率(11.0592MHz)
/* 以下為程序協(xié)議中使用的握手信號(hào) */
#define __RDY_ 0x06 // 主機(jī)開(kāi)始通信時(shí)發(fā)送的呼叫信號(hào)
#define __BUSY_ 0x15 // 從機(jī)忙應(yīng)答
#define __OK_ 0x00 // 從機(jī)準(zhǔn)備好
#define __SUCC_ 0x0f // 數(shù)據(jù)傳送成功
#define __ERR_ 0xf0 // 數(shù)據(jù)傳送錯(cuò)誤
void init_serial(); // 串口初始化
unsigned char recv_data(unsigned char *buf); // 接收數(shù)據(jù)
void Beep_ok(); // 蜂鳴表示數(shù)據(jù)接收ok,該函數(shù)代碼未給出
void main()
{
char buf[__MAX_LEN_];
unsigned char i = 0;
unsigned char tmp = 0xff;
/* 串口初始化 */
init_serial(); // 初始化串口
EA = 0; // 關(guān)閉所有中斷
/* 進(jìn)入設(shè)備應(yīng)答階段 */
while(1)
{
/* 如果接收到的數(shù)據(jù)不是握手信號(hào)__RDY_,則繼續(xù)等待 */
while(tmp != __RDY_)
{
RI = 0;
while(!RI);
tmp = SBUF;
RI = 0;
}
/* 程序通過(guò)檢測(cè)P0口數(shù)據(jù)判斷當(dāng)前設(shè)備狀態(tài),若P0=0xab,表示當(dāng)前設(shè)備忙 */
P0 = 0xff;
tmp = P0;
if(tmp == 0xab) // 如果P0口數(shù)據(jù)為0x,則當(dāng)前設(shè)備忙,發(fā)送__BUSY_信號(hào)
{
TI = 0;
SBUF = __BUSY_;
while(!TI);
TI = 0;
continue;
}
TI = 0; // 否則發(fā)送__OK_信號(hào)表示可以接收數(shù)據(jù)
SBUF = __OK_;
while(!TI);
TI = 0;
/* 數(shù)據(jù)接收 */
tmp = 0xff;
while(tmp == 0xff)
{
tmp = recv_data(buf); // 校驗(yàn)失敗返回0xff,接收成功則返回0
}
Beep_ok(); // 蜂鳴表示數(shù)據(jù)接收成功
}
}
/* 初始化串口 */
void init_serial()
{
TMOD = 0x20; //定時(shí)器T1使用工作方式2
TH1 = 250; // 設(shè)置初值
TL1 = 250;
TR1 = 1; // 開(kāi)始計(jì)時(shí)
PCON = 0x80; // SMOD = 1
SCON = 0x50; //工作方式1,波特率9600bps,允許接收
}
/* 接收數(shù)據(jù),注意該函數(shù)使用buf指向的緩沖區(qū)保存數(shù)據(jù),在數(shù)據(jù)末尾使用’\0’表示數(shù)據(jù)結(jié)束
* 返回值為0,數(shù)據(jù)校驗(yàn)成功,返回值為0xff,數(shù)據(jù)校驗(yàn)失敗
*/
unsigned char recv_data(unsigned char *buf)
{
unsigned char len; // 該字節(jié)用于保存數(shù)據(jù)長(zhǎng)度
unsigned char ecc; // 該字節(jié)用于保存校驗(yàn)字節(jié)
unsigned char i,tmp;
/* 接收數(shù)據(jù)長(zhǎng)度 */
RI = 0;
while(!RI);
len = SBUF;
RI = 0;
/* 使用len的值為校驗(yàn)字節(jié)ecc賦初值 */
ecc = len;
/* 接收數(shù)據(jù) */
for(i=0; i<len; i++)
{
while(!RI);
*buf = SBUF; // 接收數(shù)據(jù)
ecc = ecc^(*buf); // 進(jìn)行字節(jié)校驗(yàn)
RI = 0;
buf++;
}
*buf = 0; // 表示數(shù)據(jù)結(jié)束
/* 接收校驗(yàn)字節(jié) */
while(!RI);
tmp = SBUF;
RI = 0;
/* 進(jìn)行數(shù)據(jù)校驗(yàn) */
ecc = tmp^ecc;
if(ecc != 0) // 校驗(yàn)失敗
{
*(buf-len) = 0; // 清空數(shù)據(jù)緩沖區(qū)
TI = 0; // 發(fā)送校驗(yàn)失敗信號(hào)
SBUF = __ERR_;
while(!TI);
TI = 0;
return 0xff; // 返回0xff表示校驗(yàn)錯(cuò)誤
}
TI = 0; // 校驗(yàn)成功
SBUF = __SUCC_;
while(!TI);
TI = 0;
return 0; // 校驗(yàn)成功,返回0
}
#endif