1

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

我有几个问题:

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

关于如何调试这个问题的任何想法?

4

2 回答 2

4

100*1024*1024 的接收缓冲区大小是巨大的!我会严重怀疑您是否需要这个大小,当然对于实际的串行端口缓冲区来说也不是。

可能是您溢出了接收器的物理接收缓冲区,因此您可能需要考虑使用流控制。这将有效地使您的 Receiver 对您的 Transmitter 说“等一下,停止发送,让我先处理我有的东西。”

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

看看这篇文章,它解释了更多关于它的内容。

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

此阈值意味着当缓冲区中至少有1 个字节时将触发事件。可能还有更多,而且可能会有。请注意,这并不一定意味着它会为接收到的每个字节触发。在每个事件中,您需要检查 BytesToRead 属性并将这些属性读入您自己的缓冲区。

值得重复的是,事件不一定会接收到的每个字节触发。

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

另请注意,RS232的标准最大规格是 19200 波特的速度和 50 英尺的电缆长度。高于此的任何内容都是未定义的。更高的速度通常需要更好的电缆(更低的电容)和更短的电缆长度。确保它被屏蔽并且没有在其他“嘈杂”物品附近运行,例如电机、电机逆变器、带电电缆等。

于 2010-12-31T12:22:35.327 回答
3

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

不必要。这可能是由于物理连接不良(太长)而发生的。

我将读取缓冲区大小设置为 100*1024*1024

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

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

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

于 2010-12-31T10:38:39.780 回答