?? 485.c
字號(hào):
#ifndef __485_C__
#define __485_C__
#include <AT89X51.H>
#include <string.h>
#define unsigned char uchar
#define unsigned int uint
/* 通信命令 */
#define __ACTIVE_ 0x01 // 主機(jī)詢問(wèn)從機(jī)是否存在
#define __GETDATA_ 0x02 // 主機(jī)發(fā)送讀設(shè)備請(qǐng)求
#define __OK_ 0x03 // 從機(jī)應(yīng)答
#define __STATUS_ 0x04 // 從機(jī)發(fā)送設(shè)備狀態(tài)信息
#define __MAXSIZE 0x08 // 緩沖區(qū)長(zhǎng)度
#define __ERRLEN 12 // 任何通信幀長(zhǎng)度超過(guò)12則表示出錯(cuò)
uchar dbuf[__MAXSIZE]; // 該緩沖區(qū)用于保存設(shè)備狀態(tài)信息
uchar dev; // 該字節(jié)用于保存本機(jī)設(shè)備號(hào)
sbit M_DE = P1^0; // 驅(qū)動(dòng)器使能,1有效
sbit M_RE = P1^1; // 接收器使能,0有效
void get_status(); // 調(diào)用該函數(shù)獲得設(shè)備狀態(tài)信息,函數(shù)代碼未給出
void send_data(uchar type, uchar len, uchar *buf); // 發(fā)送數(shù)據(jù)幀
bit recv_cmd(uchar *type); // 接收主機(jī)命令,主機(jī)請(qǐng)求僅包含命令信息
void send_byte(uchar da); // 該函數(shù)發(fā)送一幀數(shù)據(jù)中的一個(gè)字節(jié),由send_data()函數(shù)調(diào)用
void main()
{
uchar type;
uchar len;
/* 系統(tǒng)初始化 */
P1 = 0xff; // 讀取本機(jī)設(shè)備號(hào)
dev = (P1>>2);
TMOD = 0x20; // 定時(shí)器T1使用工作方式2
TH1 = 250; // 設(shè)置初值
TL1 = 250;
TR1 = 1; // 開(kāi)始計(jì)時(shí)
PCON = 0x80; // SMOD = 1
SCON = 0x50; // 工作方式1,波特率9600bps,允許接收
ES = 0; // 關(guān)閉串口中斷
IT0 = 0; // 外部中斷0使用電平觸發(fā)模式
EX0 = 1; // 開(kāi)啟外部中斷0
EA = 1; // 開(kāi)啟中斷
/* 主程序流程 */
while(1) // 主循環(huán)
{
if(recv_cmd(&type) == 0) // 發(fā)生幀錯(cuò)誤或幀地址與本機(jī)地址不符,丟棄當(dāng)前幀后返回
continue;
switch(type)
{
case __ACTIVE_: // 主機(jī)詢問(wèn)從機(jī)是否存在
send_data(__OK_, 0, dbuf); // 發(fā)送應(yīng)答信息,這里buf的內(nèi)容并未用到
break;
case __GETDATA_:
len = strlen(dbuf);
send_data(__STATUS_, len, dbuf); // 發(fā)送設(shè)備狀態(tài)信息
break;
default:
break; // 命令類型錯(cuò)誤,丟棄當(dāng)前幀后返回
}
}
}
void READSTATUS() interrupt 0 using 1 // 產(chǎn)生外部中斷0時(shí)表示設(shè)備狀態(tài)發(fā)生改變,該函數(shù)使用寄存器組1
{
get_status(); // 獲得設(shè)備狀態(tài)信息,并將其存入dbuf指向的存儲(chǔ)區(qū),數(shù)據(jù)最后一字節(jié)置0表示數(shù)據(jù)結(jié)束
}
/* 該函數(shù)接收一幀數(shù)據(jù)并進(jìn)行檢測(cè),無(wú)論該幀是否錯(cuò)誤,函數(shù)均會(huì)返回
* 函數(shù)參數(shù)type保存接收到的命令字
* 當(dāng)接收到數(shù)據(jù)幀錯(cuò)誤或其地址位不為0時(shí)(非主機(jī)發(fā)送幀),函數(shù)返回0,反之返回1
*/
bit recv_cmd(uchar *type)
{
bit db = 0; // 當(dāng)接收到的上一個(gè)字節(jié)為0xdb時(shí),該位置位
bit c0 = 0; // 當(dāng)接收到的上一個(gè)字節(jié)為0xc0時(shí),該位置位
uchar data_buf[__ERRLEN]; // 保存接收到的幀
uchar tmp;
uchar ecc = 0;
uchar i;
M_DE = 0; // 置發(fā)送禁止,接收允許
M_RE = 0;
/* 接收一幀數(shù)據(jù) */
i = 0;
while(!c0) // 循環(huán)直至幀接收完畢
{
RI = 0;
while(!RI);
tmp = SBUF;
RI = 0;
if(db == 1) // 接收到的上一個(gè)字節(jié)為0xdb
{
switch(tmp)
{
case 0xdd:
data_buf[i] = 0xdb; // 0xdbdd表示0xdb
ecc = ecc^0xdb;
db = 0;
break;
case 0xdc
data_buf[i] = 0xc0; // 0xdbdc表示0xc0
ecc = ecc^0xc0;
db = 0;
break;
default
return 0; // 幀錯(cuò)誤,返回
}
i++;
}
switch(tmp) // 正常情況
{
case 0xc0: // 幀結(jié)束
c0 = 1;
break;
case 0xdb: // 檢測(cè)到轉(zhuǎn)義字符
db = 1;
break;
default: // 普通數(shù)據(jù)
data_buf[i] = tmp; // 保存數(shù)據(jù)
ecc = ecc^tmp; // 計(jì)算校驗(yàn)字節(jié)
i++;
}
if(i == __ERRLEN) // 幀超長(zhǎng),錯(cuò)誤,返回
return 0;
}
/* 判斷幀是否錯(cuò)誤 */
if(i<4) // 幀過(guò)短,錯(cuò)誤,返回
return 0;
if(ecc != 0) // 校驗(yàn)錯(cuò)誤,返回
return 0;
if(data_buf[0] != dev) // 非訪問(wèn)本機(jī)命令,錯(cuò)誤,返回
return 0;
*type = data_buf[1]; // 獲得命令字
return 1; // 函數(shù)成功返回
}
/* 該函數(shù)發(fā)送一幀數(shù)據(jù)幀,參數(shù)type為命令字、len為數(shù)據(jù)長(zhǎng)度、buf為要發(fā)送的數(shù)據(jù)內(nèi)容 */
void send_data(uchar type, uchar len, uchar *buf)
{
uchar i;
uchar ecc = 0; // 該字節(jié)用于保存校驗(yàn)字節(jié)
M_DE = 1; // 置發(fā)送允許,接收禁止
M_RE = 1;
send_byte(dev); // 發(fā)送本機(jī)地址
ecc = dev;
send_byte(type); // 發(fā)送命令字
ecc = ecc^type;
send_byte(len); // 發(fā)送長(zhǎng)度
ecc = ecc^len;
for(i=0; i<len; i++) // 發(fā)送數(shù)據(jù)
{
send_byte(*buf);
ecc = ecc^(*buf);
buf++;
}
send_byte(ecc); // 發(fā)送校驗(yàn)字節(jié)
TI = 0; // 發(fā)送幀結(jié)束標(biāo)志
SBUF = 0xc0;
while(!TI);
TI = 0;
}
/* 該函數(shù)發(fā)送一個(gè)數(shù)據(jù)字節(jié),若該字節(jié)為0xdb,則發(fā)送0xdbdd,若該字節(jié)為0xc0則,發(fā)送0xdbdc */
void send_byte(uchar da)
{
switch(da)
{
case 0xdb: // 字節(jié)為0xdb,發(fā)送0xdbdd
TI = 0;
SBUF = 0xdb;
while(!TI);
TI = 0;
SBUF = 0xdd;
while(!TI)
TI = 0;
break;
case 0xc0: // 字節(jié)為0xc0,發(fā)送0xdbdc
TI = 0;
SBUF = 0xdb;
while(!TI);
TI = 0;
SBUF = 0xdc;
while(!TI)
TI = 0;
break;
default: // 普通數(shù)據(jù)則直接發(fā)送
TI = 0;
SBUF = da;
while(!TI);
TI = 0;
}
}
#endif
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -