//利用串口传输控制信号不是简单的发送一帧数据,而是需要多功能的数据串,也不要把控制程序放在中断里。
//以下是依你的程序和要求改为串口信号多功能控制,供参考。自定义协议:以此为例 "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
}
}
} |