c串口一直读到缓存数据_C 串口通信时丢失数据的一种解决方法.doc

您所在位置:网站首页 > 海量文档

&nbsp>&nbsp高等教育&nbsp>&nbsp专业基础教材

C 串口通信时丢失数据的一种解决方法.doc4页

本文档一共被下载:次,您可全文免费在线阅读后下载本文档。

下载提示

1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。

2.该文档所得收入(下载+内容+预览三)归上传者、原创者。

3.登录后可充值,立即自动返金币,充值渠道很便利

C 串口通信时丢失数据的一种解决方法

C#串口通信时丢失数据的一种解决方法

刘凯周云耀

武汉理工大学信息工程学院武汉市(430070)

E-mail:lk.6@163.com

摘要:C#串行类(SerialPort)是.NET Framework version 2.0中一个新增的类,该类将串口操作了封装,从而为串口通信提供了简便方法,而且具有功能强大、通信快速、实时性好等特点。但在实际串口通信的应用中,在串口高波特率大信息量的数据通信时,会出现丢失数据的问题。此时如果只是增加串口类的缓存容量是不能根本解决问题的。本文就是从此实际中遇到的问题出发,分析了问题形成的原因,并结合实际开发的经验,给出了一种解决问题的方法。

关键词:C#串行类丢失数据队列

中图分类号:TP311 1.

前言

C#串行类(SerialPort)是Visual Studio 2005中一个新增的类,它为应用程序提供了通过串口收发数据的简便方法。C#串行类具有功能强大、通信快速、实时性好等特点[1]。该类用于控制串行端口文件资源,提供同步I/O和事件驱动的I/O、对管脚和中断状态的访问以及对串行驱动程序属性的访问。SerialPort类支持:ASCIIEncoding、UTF8Encoding等几乎所有编码格式[2]。

2.

C#串口通信的一般实现方法及潜存的问题

串口有两种读取方式,一种是同步的,另外一种就是基于事件的异步读取方式。因为同步接收会阻塞线程所以在大数据量通信时常采用异步方法读取。

在通信之前要对串口对象做一个初始化,这包括设置PortName(串口号)、BaudRate(波特率)、Parity(奇偶校验)、DataBits(数据位数)等,在此就不赘述了。

由于SerialPort类的封装,屏蔽了很多通信细节。所以异步串口通信的实现逻辑很简单。我们只须要为SerialProt类的DataReceived事件绑定一个处理函数,然后就可以在该函数中实现对串口数据的读取。假设该函数名为GetStrFromPort,其实现示例如下。

Public void GetStrFromPort(object sender,SerialDataReceivedEventArgs e)

{

string str=null;

str=serialprot.ReadTo("\n\r");//读到该帧数据结束处

serialport.DiscardInBuffer();//清除缓存中的内容

DealWithProtStr(str);//处理接收到的数据

}

-1-

大多串口程序都会采用这种思路来实现串口通信。即先接收数据,然后处理数据,并在完成数据处理后,再次等待接收新数据。但这种实现方法在串口高速率大信息量通信时,会出现丢失数据的情况。

数据丢失的原因在于数据接收与数据处理同在一个线程中,如果数据处理时间较长,来不及接收的数据只能暂存于缓存中。一旦缓存满了,新到的数据就会冲刷掉未来的及接收的数据,从而造成数据的丢失。此时如果只单单增加缓存的容量是不能根本解决问题的。这也是我们在实际应用中遇到的问题。

3.

丢失数据问题的解决办法

有鉴于此,我们解决问题的思路就是将数据接收与数据处理分离开来,使数据接收得到最快的时间响应。通过在实际中的反复实验,我们最终采用了多线程加数据池来解决此问题。

设计思路如下:数据接收与数据处理分别在两个线程中进行,数据接收线程负责数据接收并将接收的数据存入数据池中;数据处理线程负责从数据池中读取数据和处理数据。程序设计思路如图1-1所示。

由图1-1可以看出,两个线程有可能会同时访问数据池。因此为使数据接收得到最快的时间响应,最好不要选用像数组这样数据结构。因为此类数据结构在多线程中操作时必须频繁地"加锁"和"解锁",在一定程度上会降低程序的性能。所以我们选用队列Queen作为数据池的数据结构。

队列在顺序存储方面非常有用。数据对象在队列的一端插入,另一端移除。而且当两个线程同时访问队列,如果一个线程只负责数据存入,另一个线程只负责操作数据读取时,不会出现多线程的资源争用的问题,所以不必使用"加锁"和"解锁"操作,从而提高了程序的运行效率。

图1-1多线程加数据池模式的串口通信设计示意图

下面是程序的伪代码。

数据接收线程:

ReceiveThread(){string str=ReceiveFormPort();//从串口读取数据queue.Enqueue(str);//将数据存入队列}

数据处理线程

DealData()

{

while(true)//循环检测队列

{

if(queue.Count=1)//队列中有数据

{

string data=queue.Dequeue();//将数据出队

DealWithReceiveData(d

发表评论

请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。

用户名:

验证码:

匿名?

发表评论

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值