|
发表于 2014-11-24 13:59:05
|
显示全部楼层
/*
这段代码是解析单片机从串口获得的来自PC上位机串口(串口调试助手发送)的数据,并向上位机回显相应字符(可在串口助手里看)。相当于下位机对上位机命令的识别。命令的格式是5字节十六进制,如0x FF 00 01 00 FF。
当然,如果你上位机的代码不是一次5字节,这个代码是会出错的。不知道配合坛子的上位机能凑合用不 ?
*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar flag,a[5],i,j;
uchar code msg_left[]="cmd is LEFT ";//code 意思是存储到ROM ?
uchar code msg_right[]="cmd is RIGHT ";
uchar code msg_up[]="cmd is UP ";
uchar code msg_down[]="cmd is DOWN ";
uchar code msg_unknow[]="cmd is UNKNOW ";
/*命令的格式是CMD_TOU+CMD_SEC+CMD_TYPE_XX+CMD_FOU+CMD_WEI
比如左转的命令是0xFF 00 03 00 FF*/
#define CMD_TOU 0xFF //命令头
#define CMD_SEC 0x00 //第二字节
#define CMD_FOU 0x00 //第四字节,第三字节是命令类型,定义如下
#define CMD_WEI 0xFF //命令尾
#define CMD_TYPE_LEFT 0x03 //命令类型 左、右、上、下
#define CMD_TYPE_RIGHT 0x00
#define CMD_TYPE_UP 0x01
#define CMD_TYPE_DOWN 0x02
void init()
{
TMOD=0x20;//T1定时器工作方式2
TH1=0xfd;//定时器初值
TL1=0xfd;
TR1=1;//启动T1定时器
SM0=0;//串口工作方式1
SM1=1;
REN=1;//允许串口接收
EA=1;//总中断
ES=1;//串口中断
j=0;
}
void CommandPro()//对命令进行解析处理
{
if(a[0]==CMD_TOU&&a[1]==CMD_SEC&&a[3]==CMD_FOU&&a[4]==CMD_WEI)
{
switch(a[2])
{
case CMD_TYPE_LEFT:
for(i=0;i<12;i++)//向上位机发送对应信息,可以换成单片机相应动作
{
SBUF=msg_left[i];
while(!TI);//一直循环到TI==1,因为发送完成,发送中断标志位TI会置1
TI=0;//手动清零
}
break;
case CMD_TYPE_RIGHT:
for(i=0;i<13;i++)
{
SBUF=msg_right[i];
while(!TI);
TI=0;
}
break;
case CMD_TYPE_UP:
for(i=0;i<10;i++)
{
SBUF=msg_up[i];
while(!TI);
TI=0;
}
break;
case CMD_TYPE_DOWN:
for(i=0;i<12;i++)
{
SBUF=msg_down[i];
while(!TI);
TI=0;
}
break;
default:
for(i=0;i<14;i++)
{
SBUF=msg_unknow[i];
while(!TI);
TI=0;
}
break;
}
}
}
void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0;//关闭串口中断,防止死循环
CommandPro();//对命令识别、并相应处理
ES=1;
flag=0;
}
}
}
void ser()interrupt 4//串口中断服务
{
RI=0;//接收中断标志位
a[j]=SBUF; //接收数据,一个字节
j++;
if(j==5)
{
flag=1;//接收到5个字节才置位flag
j=0;
}
}
|
|