找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1770|回复: 10
收起左侧

关于单片机串口接收转发程序的问题分析

[复制链接]
ID:230975 发表于 2019-9-27 17:04 | 显示全部楼层 |阅读模式
各们老师请帮我看一下,我在做串口接收,再转发实验。把从上位机接收到的七个字符到数组里。然后再把这个数组里面的数据发送回去给上位机。?
现在能过上位机如果发送长度正好是七个字符,是没问题的。如果发送的长度不到七个字符,那么返回到上位的数据,就会被打乱。如何做出判断,只接收长度够七的字符串呢?(比如,我发送 10 20 30 40 50 60 70 那么可以正解的返回给上位机,但是如果我只发送10 20 30 40 那么返回给上位的就是10 20 30 40 10 20 30 。如何让单片机只返回正解的字符串)谢谢。

单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar flag,a,i,j;
  6. uchar buf[7];
  7. void init()
  8.     {
  9.     SCON=0X50;
  10.    TMOD =0X20;
  11.    TH1=0XFD;
  12.    TL1=0XFD;
  13.    TR1=1;
  14.    EA=1;
  15.    ES=1;
  16.     }
  17. void main()
  18.     {
  19.    init();
  20.    while(1)
  21.       {
  22.      if(flag==1)
  23.         {
  24.       j=0;
  25.       ES=0;
  26.       for(i=0;i<7;i++)
  27.          {
  28.        SBUF=buf[i];
  29.      while(!TI);
  30.      TI=0;
  31.       }
  32.       ES=1;
  33.       flag=0;
  34.       
  35.      }
  36.    }

  37. }
  38. void ser() interrupt 4
  39.      {
  40.       uchar temp;
  41.            RI=0;   
  42.            temp=SBUF;
  43.            buf[j++]=temp;
  44.                  if(j==7)
  45.                    {
  46.                      flag=1;
  47.                      ES=0;
  48.                     }
  49.      else
  50.         {
  51.       flag=0;
  52.      }
  53.       }
复制代码

回复

使用道具 举报

ID:213173 发表于 2019-9-27 20:55 | 显示全部楼层
简单的方法是收到一个字节立即发还上位机,复杂一点的方法是相隔一定时间没有收到数据判断为结束,计算字节长度后发还上位机。
回复

使用道具 举报

ID:351097 发表于 2019-9-27 22:50 | 显示全部楼层
你上位机大概多久发送一轮数据?如果可以确定每轮发送数据的时间,那可以开一个定时器监控每轮接收数据的字节数,如果数据不足7个字节,则把接收的数据丢掉,不发送给上位机。只有数据达到7个字节,才发送给上位机
回复

使用道具 举报

ID:111517 发表于 2019-9-28 09:56 | 显示全部楼层
我提供给你另外要给思路,你可以自己定义一个首字母标识,当你接收端识别出来你接收这个字母的时候就一定是第一个
回复

使用道具 举报

ID:230975 发表于 2019-9-28 15:26 | 显示全部楼层
wulin 发表于 2019-9-27 20:55
简单的方法是收到一个字节立即发还上位机,复杂一点的方法是相隔一定时间没有收到数据判断为结束,计算字节 ...

收发时间不固定
回复

使用道具 举报

ID:230975 发表于 2019-9-28 15:27 | 显示全部楼层
沧浪 发表于 2019-9-28 09:56
我提供给你另外要给思路,你可以自己定义一个首字母标识,当你接收端识别出来你接收这个字母的时候就一定是 ...

接收的首字节是固定的。
回复

使用道具 举报

ID:230975 发表于 2019-9-28 15:27 | 显示全部楼层
没有你 发表于 2019-9-27 22:50
你上位机大概多久发送一轮数据?如果可以确定每轮发送数据的时间,那可以开一个定时器监控每轮接收数据的字 ...

时间不固定。很随机的
回复

使用道具 举报

ID:230975 发表于 2019-9-28 15:29 | 显示全部楼层
wulin 发表于 2019-9-27 20:55
简单的方法是收到一个字节立即发还上位机,复杂一点的方法是相隔一定时间没有收到数据判断为结束,计算字节 ...

您看我这个思路可以吗?能过REN这位来控制,接收还是不接收。发送不想接收返回信息的命令的时候,把REN=0,要接收的返回信息时,REN=1.这样可吗
回复

使用道具 举报

ID:230975 发表于 2019-9-28 15:37 | 显示全部楼层
沧浪 发表于 2019-9-28 09:56
我提供给你另外要给思路,你可以自己定义一个首字母标识,当你接收端识别出来你接收这个字母的时候就一定是 ...

命令是固定的,返回的信息也是固定的。
只是有的命令返回的是七个字节的信息,有的命令返回的是4个字节的信息。
不知道如何只接收七个字节的信息,而不接收4个字节的信息。如果这样可行吗。在发送反回4个字节命令之前,把串口接收关了,等到发送七个字节信息的时候再把串口接打开。
回复

使用道具 举报

ID:123289 发表于 2019-9-28 16:25 | 显示全部楼层
用串行通讯协议解决。
回复

使用道具 举报

ID:213173 发表于 2019-9-28 22:53 | 显示全部楼层

在你的程序基础上改写成利用定时器T0判断串口1帧数据(1~7字节)收发程序,供参考。

  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar i,j=0;
  6. bit Lock=0;
  7. uchar buf[7];
  8. void init()
  9. {
  10.         SCON=0X50;
  11.         TMOD =0X21;
  12.         TH0=0xfe;
  13.         TL0=0x0b;
  14.         TH1=0XFD;
  15.         TL1=0XFD;
  16. //        TR0=1;
  17.         TR1=1;
  18.         EA=1;
  19.         ET0=1;
  20.         ES=1;
  21. }
  22. void main()
  23. {
  24.         init();
  25.         while(1)
  26.         {
  27.                 if(Lock==1)
  28.                 {
  29.                         Lock=0;
  30.                         EA=0;
  31.                         for(i=0;i<j;i++)
  32.                         {
  33.                                 SBUF=buf[i];
  34.                                 while(!TI);
  35.                                 TI=0;
  36.                         }
  37.                         j=0;                               
  38.                         EA=1;
  39.                 }
  40.         }
  41. }
  42. void T0_time() interrupt 1 //0.5ms定时中断
  43. {
  44.         TH0=0xfe;
  45.         TL0=0x0b;
  46.         TR0=0;//关闭定时器
  47.         Lock=1; //开自锁标志
  48. }
  49. void ser() interrupt 4
  50. {
  51.         RI=0;   
  52.         if(j<7)
  53.         j++;
  54.         buf[j-1]=SBUF;
  55.         TR0=1;       
  56. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表