赞
踩
3.4通信功能
串口通信配置:波特率设置为9600bps,8个数据位,1个停止位,无校验。
1)设置目的地坐标
通过串口调试工具向设备发送目的地坐标,第一个数字为目的地的X坐标,第二个数字为目的地的Y坐标,2个数字以英文逗号分隔,并用括号包裹,坐标为整数,X、Y坐标取值范围为0- 999,坐标轴单位为cm。
举例:
发送:
(30,420)
应答:
Got it
说明:通过计算机向设备串口发送一组目的地坐标(30,420),若设备处于“空闲”状态,设备应答Got it,目的地坐标生效,否则应答Busy,目的地坐标不生效。
2)查询设备状态
通过串口调试工具向设备发送字符?,表示查询设备当前的状态。
举例:
发送:
?
应答:
Idle
说明:向设备发送查询设备状态字符?,若设备处于“空闲”状态,设备应答Idle,处于“等待”状态,设备应答Wait,“运行”状态应答Busy。
3)查询设备位置
通过串口调试工具向设备发送查询位置字符#,表示查询设备的当前位置。
举例:
发送:
#
应答:
(30,420)
说明:向设备发送查询设备位置字符#,设备返回当前X坐标为30,Y坐标为420,返回坐标为整数。
**所有串口通信指令和应答内容均为ASCII字符,若设备串口接收到未定义的指令或错误设置,指令不生效,返回 Error。
**严格按照上述格式的约定,设计设备串口通信功能,区分大小写,勿添加回车、换行等其它内容。
1、题目对串口要求:
1)串口通信配置:波特率设置为9600bps,8个数据位,1个停止位,无校验。能收发;
2)所有串口通信指令和应答内容均为ASCII字符,若设备串口接收到未定义的指令或错误设置,指令不生效,返回 Error。
3)严格按照上述格式的约定,设计设备串口通信功能,区分大小写,勿添加回车、换行等其它内容。
4)接收三种指令:设置坐标、查询设备状态、查询设备位置
2、分析串口通信数据传输格式:
接收数据格式:
1)坐标值:”(000,000)”,接收字符数最多9个
2)查询设备状态:”?”,接收字符数最多1个
3)查询设备位置:”#”,接收字符数最多1个
根据接收格式,可以通过判断接收到的第一个字符确定指令:
1)‘(‘ :代表要接收坐标
2)”?”:代表要查询设备状态
3)”#”:代表要查询设备位置
4)其他字符:代表指令不生效
发送数据格式:
发送的都是字符串,根据情况不同发送不同的字符串,因此,字符串的长度不同,要定义统一的结束符,方便程序判断发送完成。这里用’\0’作为结束符,要求所有发送的字符串必须以’\0’结束。
3、程序分析
全局变量
uchar Work_Mode; //=0 空闲 =1 等待 =2 运行 uchar Idle_Receive; //=0 没接收到坐标 =1 接收到坐标 uchar Str_Idle[7]={"Idle\r\n"}; uchar Str_Wait[7]={"Wait\r\n"}; uchar Str_Busy[7]={"Busy\r\n"}; uchar Str_Error[8]={"Error\r\n"}; uchar Str_Got[9]={"Got it\r\n"}; //uchar Str_Axes_S[12]={"(000,000)\r\n"}; //发送格式 uchar Str_Axes_S[12]={0}; //uchar Str_Axes_R[10]={"(000,000)"}; //接收格式 uchar Str_Axes_R[10]={0}; uchar Uart_Receive_Mode; //=0 接收坐标值 =1 查询设备状态 =2 查询设备位置 =3 无效指令 uchar Uart_Receive_First; //接收到第一个字符标志 =1 以接收到 =0 未接收到 int Dest_x=0,Dest_y=0; //目的地坐标值
串口初始化
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率,允许接收
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES=1;
}
发送字符子程序,采用查询法
void uart_byte(uchar B_one) //发送一个字符
{
SBUF=B_one;
while(!TI);//等待
TI=0;
}
void uart_str(uchar *p) //发送带结束符的字符串
{
while(*p != '\0')
{
uart_byte(*p);
p++;
}
}
接收字符串子程序,采用中断方式
void Uart_int() interrupt 4 //串口1中断服务程序 { static uchar receive_i=0; if(RI==1) //接收到字符 { RI=0; if(Uart_Receive_First==0) //接收第一个字符 { Uart_Receive_First=1; //标记已经接收到第一个字符 Str_Axes_R[0]=SBUF; if(Str_Axes_R[0]=='(') {Uart_Receive_Mode=0; receive_i=1; } else if(Str_Axes_R[0]=='?') {Uart_Receive_Mode=1; } else if(Str_Axes_R[0]=='#') {Uart_Receive_Mode=2; } else {Uart_Receive_Mode=3;} } else if(Uart_Receive_First==1 && Uart_Receive_Mode==0)//接收坐标 { Str_Axes_R[receive_i]=SBUF; if(SBUF == ')') {Uart_Receive_First=0; Idle_Receive=1;} receive_i++; } } }
通过全局变量Uart_Receive_First 判断是否接收到第一个字符,
=0还没接收;
=1;已经接收。
通过全局变量Uart_Receive_Mode判断接收指令类型,
=0 接收坐标值
=1 查询设备状态
=2 查询设备位置
=3 无效指令
通过局部静态变量receive_i 记录接收坐标数据的长度。
通过全局变量Idle_Receive 记录接收坐标数据结束,
=1 接收完成
主程序中串口程序:
主框架
if(sj[2]>=450)//串口命令响应 { sj[2]=0; if(Uart_Receive_Mode==1 && Uart_Receive_First==1) //查询设备状态命令 { } else if(Uart_Receive_Mode==2 && Uart_Receive_First==1) //查询设备位置命令 { } else if(Uart_Receive_Mode==3 && Uart_Receive_First==1) //无效命令 { } else if(Uart_Receive_Mode==0 && Idle_Receive==1) //设置目的坐标命令 { } }
1、//查询设备状态命令
if(Uart_Receive_Mode==1 && Uart_Receive_First==1) //查询设备状态命令
{
switch(Work_Mode)
{
case 0: uart_str(Str_Idle); break;
case 1: uart_str(Str_Wait); break;
case 2: uart_str(Str_Busy); break;
}
Uart_Receive_First=0;
}
2、//查询设备位置命令
else if(Uart_Receive_Mode==2 && Uart_Receive_First==1) //查询设备位置命令
{
Dest_axes_ascii(); // 把坐标值转换为ASCII
uart_str(Str_Axes_S);
Uart_Receive_First=0;
}
3、//无效命令
else if(Uart_Receive_Mode==3 && Uart_Receive_First==1) //无效命令
{
uart_str(Str_Error);
Uart_Receive_First=0;
}
4、//设置目的坐标命令
else if(Uart_Receive_Mode==0 && Idle_Receive==1) //设置目的坐标命令
{
uart_str(Str_Axes_R);
uart_str("\r\n");
Idle_Receive=0;
Uart_Receive_First=0;
}
完整程序见顶部
4、调试结果
1)发送坐标,我的测试程序回送坐标值
2)发送?,查询设备状态
这里用S7,可以认为修改设备状态变量 Work_Mode
3)发送#,查询设备位置
这里坐标值,在程序中用变量Dest_x,Dest_y,保存,可以通过S11,S15进行修改
4)发送其他字符,回送错误
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。