Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 82|回复: 0

C# 解决上位机串口接收数据丢失问题

[复制链接]
  • TA的每日心情
    奋斗
    昨天 16:33
  • 签到天数: 146 天

    [LV.7]常住居民III

    1422

    主题

    1479

    帖子

    7万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    71008
    发表于 2021-4-15 14:11:42 | 显示全部楼层 |阅读模式

    项目需要实现下位机和上位机的数据传输,看了网上的很多上位机的处理方法主要有两种。方法一是:port_DataReceived(SerialPort控件的数据接收方法,当有数据来临时会触发)会创建一个线程,因此当串口在等待数据时,不影响主窗体或主线程的操作。方法二是:使用缓存机制(参考:http://blog.csdn.net/jiqiang_paul/article/details/6914619)。首先通过定义一个成员变量List ReceBuf  new List(4096);用来存放所有的数据,在接收函数里,通过RecBuf.AddRange()方法不断地将接收到的数据加入到ReceBuf中,并同时对Recebuf中的数据进行检验,如果达到一定的长度并且校验结果正确(校验方法在发送方和接收方一致),再进行处理。

    经过测试发现这两种方法在数据包发送间隔小于200ms时,会出现数据丢包的问题,现在将这两种方法结合起来,同时将方法二改进为双缓存机制,经过测试发现可以解决数据的丢包的问题。
    一、在 public MainForm()中定义串口数据接收事件
      public MainForm()
            {
                InitializeComponent();
                serialPort_port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);//串口接收事件
                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//关闭夸线程检查
            }
    二、MainForm类下定义接收事件的委托并编写接收程序
     
      public delegate void PortDelegate();
            private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                PortDelegate proc_PORTGETDATA = new PortDelegate(getComData);
                IAsyncResult async_PORTGETDATA = proc_PORTGETDATA.BeginInvoke(null, null);
            }
    private List ReceBuffer = new List(4096);//串口接收一级缓存,默认分配一页内存并始终不超过 
     private byte[] DataTemp = new byte[10];//从一级缓存拷贝到二级缓存 
     private List DataBuf = new List(1000);//串口接收二级缓存,默认分配1000并始终不超过
     private byte[] DataTemp2 = new byte[10];//从二级缓存拷贝出来分析
     private byte[] DataAnalyBuf = new byte[8]; 
     public void getComData()
     { 
     try
     { 
     int n = serialPort_port.BytesToRead; 
     byte[] Receive = new byte[n]; 
     serialPort_port.Read(Receive, 0, Receive.Length); 
     bool DataCatched = false;//数据可以分析的标志
     //缓存数据 
     ReceBuffer.AddRange(Receive); 
     //完整性判断 
     while(ReceBuffer.Count >= 10)
     { 
     ////查看帧首和尾数据,判断准确性 
    //这里可以写成对数据的校验如CRC
    if (ReceBuffer[0] == 0x50 && ReceBuffer[9] == 0x42) 
     { 
     ReceBuffer.CopyTo(0, DataTemp, 0, 10); 
     DataBuf.AddRange(DataTemp); 
    DataCatched = true; 
     ReceBuffer.RemoveRange(0, 10);//获得一条正确的数据,删除缓存
     }
     else
     { 
     ReceBuffer.RemoveAt(0);//不是数据头,删除数据
     }
     }
     //分析数据 
     if (DataCatched == true) 
     { 
     while (DataBuf.Count > 0)
     {
     DataBuf.CopyTo(0,DataTemp2,0,10); 
    在这里写自己的数据分析
    DataBuf.RemoveRange(0, 10);
     } 
     }
     } catch { } 
     }
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

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

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2021-10-19 17:19 , Processed in 0.056386 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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