c#串口数据丢失

时间:2010-12-31 07:23:31

标签: c# serial-port data-loss

我编写了一个C#程序来接收COM2端口上的数据。波特率设置为115200.发送方以115200bps的速率发送数据。我的程序偶尔会丢失几个字节。我正在调用ReadByte方法从com端口读取while(true)循环中的数据。

我几乎没有问题:

  • 当波特率设置为高时,我是否应该丢失数据?如果有,为什么?
  • 我将readbuffer大小设置为100 * 1024 * 1024。这是否将串行驱动程序缓冲区大小设置为100 * 1024 * 1024?

有关如何调试此问题的任何想法?

2 个答案:

答案 0 :(得分:4)

接收缓冲区大小为100 * 1024 * 1024是巨大的!我会严重怀疑你需要这个大小,当然不是实际的串口缓冲区。

可能是您正在溢出接收器的物理接收缓冲区,因此您可能需要考虑使用流控制。这将有效地使您的接收器能够向您的发射器“保持开启状态,停止发送一段时间,让我先处理我拥有的内容。”

通过RTS(请求发送)和CTS(清除发送)引脚(通常)使用硬件流控制。

查看this文章,该文章对此进行了更多解释。

我个人建议将串口的ReceivedBytesThreshold属性保留为默认值1,然后处理DataReceived事件。谁知道,也许明天你需要读取一个20字节或者5字节的消息。也许你将来需要阅读可变长度的消息?将阈值保持为1意味着您可以处理将来和将来收到的任何和所有字节。

此阈值表示当缓冲区中 至少 1个字节时,事件将触发。可能会有更多,也可能会更多。请注意, NOT 必然意味着它将针对接收到的每个字节触发。在每个事件上,您需要检查BytesToRead属性并将其读取到您自己的缓冲区中。

值得重复的是,事件 NOT 必须为接收的每个字节触发。

此外,最好在DataReceived事件处理程序中尽可能少地执行此操作。读入接收到缓冲区中的任何字节,并可能将已完成的消息添加到队列中以进行进一步处理,但不做其他事情。

另请注意,RS232 标准 最大规格是19200波特的速度和50英尺的电缆长度。以上任何内容都是未定义的。更高的速度通常需要更好的电缆(更低的电容)和更短的电缆长度。确保它已经过筛选,并且没有在其他“噪音”物品附近运行,如电机,电机逆变器,带电电缆等。

答案 1 :(得分:3)

  

当波特率设置为高时,我是否应该丢失数据?如果有,为什么?

不一定。它可能由于物理连接不良(太长)而发生。

  

我将readbuffer大小设置为100 * 1024 * 1024

这应该是(方式)绰绰有余。

话虽如此,循环和读取单个字节并不是读取端口的最有效方法。

您可以连接到DataReceived事件并设置ReceivedBytesThreshold = 12。这样你就可以随时只读(Buffer,0,12)