//利用串口傳輸控制信號不是簡單的發送一幀數據,而是需要多功能的數據串,也不要把控制程序放在中斷里。
//以下是依你的程序和要求改為串口信號多功能控制,供參考。自定義協議:以此為例 "AA 55 AA 5A 59"共五位數據
//AA是數據頭,55 AA 5A 是三位有效數據,59是數據尾,是三位有效數據和的余數,依此驗證數據傳輸是否正確
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar table0[] ="OK "; //用于串口助手返回驗證
uchar table1[]="ERROR ";//用于串口助手返回驗證
uchar rec_buf[5]; //數據緩存
bit flag=0; //接收完成標志
bit sign=0; //數據驗證標志
sbit beep=P2^3;
/**********串口發送函數*************/
void SendOneByte(uchar k)
{
SBUF = k; //發送數據
while(!TI); //等待發送完成
TI = 0; //發送中斷請求標志位清0
}
void main(void)
{
uchar i,j; //臨時變量
SCON=0x50; //設定串口工作方式
PCON=0x00; //波特率不倍增
TMOD=0x20; //定時器1工作于8位自動重載模式, 用于產生波特率
TL1=0xfd;
TH1=0xfd; //波特率9600
TR1=1;
EA=1;
ES = 1; //允許串口中斷
while(1)
{/************數據解析*************/
if(flag==1) //5位數據串接收完成
{
ES=0; //關串口中斷
flag=0; //接收完成標志清0
j=rec_buf[1]+rec_buf[2]+rec_buf[3];//三位有效數據的和,溢出部分舍棄
if(rec_buf[4]==j)//驗證數據和
{
for(i=0;i<3;i++)
SendOneByte(table0[i]);//返回串口助手字符"OK"
sign=1; //數據傳輸正確
}
else
{
for(i=0;i<6;i++)
SendOneByte(table1[i]);//返回串口助手字符"ERROR"
sign=0; //數據傳輸錯誤
}
ES=1; //開串口中斷
/******控制任務*******/
if(sign==1)
{
P0=rec_buf[1];
P1=rec_buf[2];
P2=rec_buf[3];
beep=1;
}
else
{
P0=0xff;
P1=0xff;
P2=0xff;
beep=0;
}
}
}
}
/*********************************************************
串口中斷服務函數
*********************************************************/
void serial() interrupt 4
{
static uchar num=0; //靜態計數變量
RI=0; //接收中斷請求標志位清0
rec_buf[num]=SBUF; //接收到的數據串保存在緩存數組
if(rec_buf[0]==0xAA) //驗證數據頭(起始位)
{
num++;
if(num>=5)
{
flag=1; //接收完成標志置1
num=0; //計數變量清0
}
}
} |