第十五届蓝桥杯单片机设计与开发项目国赛赛题分析(串口通信部分)

第十五届蓝桥杯单片机设计与开发项目国赛赛题分析(串口通信部分)

题目对串口通信部分说明

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)发送其他字符,回送错误
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值