利用串口进行通信,当发送方(A)将数据写入串口后,通过无线或有线方式将数据传送给接收方(B),B通过调用串口读方法comm.read(参数)即可将数据读出。原理十分简单,但最近在利用串口处理SM-42无线传输时,数据总是一段一段的传到B,并不能在comm_DataReceived方法中单纯使用read方法将数据接收完全。我知道用缓存机制,但由于经验少(正在实习),到网上找了找大牛们的方法,并结合自己的理解,发现有两种方法可以处理。

方法一:comm_DataReceived(Comm控件的数据接收方法,当有数据来临时会触发)会创建一个线程(悲哀,因为之前不知道它另辟线程,所以自己编写了一个线程处理函数),因此当串口在等待数据时,不影响主窗体或主线程的操作。所以当数据到来时,可以通过Thread.Sleep(100)让接收函数休息100毫秒,这100毫秒做什么用呢?就是让所有的数据都到达B时再读取,这样就逃避了分批到达的问题。很明显,这是在糊弄。因为万一100毫秒都不够呢?所以,方法二更合适。

private void comm_DataReceived(objectsender, EventArgs e)
{
Thread.Sleep(100); //等待100毫秒
int nReviceBytesNum =comm.BytesToRead; ///收到的字节数。
byte[] ReadBuf = new byte[nReviceBytesNum]; ///定义接收字节数组
comm.Read(ReadBuf, 0, nReviceBytesNum);  ///接收数据
}

方法二:使用缓存机制完成。首先通过定义一个成员变量List<byte> buffer = new List<byte>(4096);用来存放所有的数据,在接收函数里,通过buffer.AddRange()方法不断地将接收到的数据加入到buffer中,并同时对buffer中的数据进行检验,如果达到一定的长度并且校验结果正确(校验方法在发送方和接收方一致),再进行处理。具体代码如下:

代码

private List<byte> buffer = new List<byte>(4096);
private void sp_DataReceived(objectsender, EventArgs e) //sp是串口控件
        {
            int n = sp.BytesToRead;
            byte[] buf = new byte[n];
            sp.Read(buf, 0, n);

//1.缓存数据
            buffer.AddRange(buf);
            //2.完整性判断
            while (buffer.Count >= 4) //至少包含帧头(2字节)、长度(1字节)、校验位(1字节);根据设计不同而不同
            {
                //2.1 查找数据头
                if (buffer[0] == 0x01) //传输数据有帧头,用于判断
                {
                    int len = buffer[2];
                    if (buffer.Count < len + 4) //数据区尚未接收完整
                    {
                        break;
                    }
                    //得到完整的数据,复制到ReceiveBytes中进行校验
                    buffer.CopyTo(0, ReceiveBytes, 0, len + 4);
                    byte jiaoyan; //开始校验
                    jiaoyan = this.JY(ReceiveBytes);
                    if (jiaoyan != ReceiveBytes[len+3])                   //校验失败,最后一个字节是校验位
                    {
                        buffer.RemoveRange(0, len + 4);
                        MessageBox.Show("数据包不正确!");
                        continue;
                    }
                    buffer.RemoveRange(0, len + 4);
                    /执行其他代码,对数据进行处理。
                }
                else //帧头不正确时,记得清除
                {
                    buffer.RemoveAt(0);
                }
            }
        }

串口通信中接收数据时延迟处理与缓存处理的解决方案(C#)相关推荐

  1. C#解决串口通信中接收数据时延迟处理与缓存处理的方法

    转载连接: http://blog.csdn.net/yaoliang11/article/details/6885768 C#解决串口通信中接收数据时延迟处理与缓存处理的方法 时间:2011-1-2 ...

  2. 环形缓冲区-----适合在通信中接收数据(例如uart)

    为什么要用环形缓冲区 当有大量数据的时候,我们不能存储所有的数据,那么计算机处理数据的时候,只能先处理先来的,处理之后就会把数据释放掉,再处理下一个.那么已经处理的数据的内存就会被浪费掉.因为后来的数 ...

  3. mima接收数据时粘包和大小端问题解决方案具体实现

    使用java的mina框架接收数据总是会把数据拼接在一起然后再发送给上层的,所以在自定义网络传输协议的时候一定就在数据开始的固定位置处存放主体内容的数据长度,要不就是固定每个数据包的固定长度,其实两种 ...

  4. FPGA学习笔记(四)——串口通信之接收数据(调试过程)

    本学习笔记主要参考小梅哥B站教学视频,网址如下: https://www.bilibili.com/video/BV1va411c7Dz?p=1 使用的编译器为Vivado,HDL语言为verilog ...

  5. 求android 中串口的发送接收数据代码

    RT,求高手帮忙! 就是 /dev/ttyS0 和/dev/ttyS1 两个设备的通信问题.. 同求~ 这个是不是需要串口驱动啊?最近正在搞这个串口通信的案子,头疼 同样也没有搞出来,老是报:不能扫描 ...

  6. STM32串口通信中使用printf发送数据配置方法 开发环境 Keil

    STM32串口通信中使用printf发送数据配置方法(开发环境 Keil RVMDK) 已有 12456 次阅读2011-6-29 23:29 | 在STM32串口通信程序中使用printf发送数据, ...

  7. js 串口通信mscomm接收undefined_串口通信帧的同步方法(识别一帧数据的起始结束)42...

    串口通信是单片机和DSP等嵌入式系统之间,以及嵌入式系统与PC机或无线模块之间的一种非常重要且普遍使用的通信方式.在嵌入式系统的硬件结构中,通常只有一个8位或16位的CPU,不仅要完成主流程的工作,同 ...

  8. 串口通信,接收并解析数据的方式

    串口通信,接收并解析数据的方式 (点击链接阅读原文)

  9. 串口通信中ReadFile和WriteFile的超时详解!

    源:串口通信中ReadFile和WriteFile的超时详解! 在用ReadFile和WriteFile读写串行口时,需要考虑超时问题.如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFi ...

最新文章

  1. C++ Primer 学习笔记_75_模板与泛型编程 --模板定义
  2. 百行代码带你入门 vue-router!
  3. 数组 最大值,课堂测试
  4. 自食其力!ASP.NET 4打造HTML5视频控件
  5. 让程序员爱不释手的两个导航网站
  6. python线程池管理两个队列_Python 线程池使用有限大小的工作队列
  7. 回文字符串判断python实现
  8. IIS站点无法启动,万维网发布服务无法开机启动解决办法
  9. 我的阴阳两界:革命时期的爱情--王小波
  10. 分析评估和定位声音质量
  11. Pytorch:VGG16
  12. 字节跳动后台开发实习面试回顾
  13. 联想笔记本电脑主板分析与维修(型号G50-70M版号NM-A273) 问题:按电源开关不开机无反应,充电指示灯不亮
  14. 编程新手表示很想知道JAVA中Bean是什么?
  15. AI 人工智能学习之假设检验
  16. 2021年全球烤面包机收入大约1363.7百万美元,预计2028年达到1536.8百万美元
  17. POST,PUT和PATCH的区别
  18. 安全团队不可错过的 7 个开源工具
  19. kingscada3.52 工程文件说明
  20. Vysor 最新安装使用教程

热门文章

  1. 蔬菜名称大全500种_市场上常见47种室外健身器材型号及名称大全
  2. 在php中array函数的作用是什么意思,php中的array函数有什么用
  3. 2010计算机知识点总结,2010年全国职称计算机考试:知识点笔记第一章
  4. 怎么真正入行Web前端行业?JavaScript五大新特性是什么?
  5. 计算机应用基础0035形考答案,计算机应用基础0035形考答案
  6. docker切换到linux容器模式,linux – 将虚拟主机转换到Docker容器
  7. html页面图片翻转特效代码,如何使用css实现翻转图片的效果(附代码)
  8. mapreduce分组统计_如何优雅的理解MapReduce
  9. LUNA16数据集肺结节显示亲测
  10. 使用multiprocessing时的DictProxy object, typeid 'dict' at ; '__str__()' failed