【问题标题】:VB.net Serial.write slow on Windows 7VB.net Serial.write 在 Windows 7 上很慢
【发布时间】:2020-05-21 07:49:26
【问题描述】:

我在使用带有 .NET Framework 4.0 的 VB.net 的 Windows 7 上遇到以下问题。 我必须通过串行端口发送一个字节缓冲区。 PC 充当主机,作为从机连接的设备接收缓冲区。每个字节必须与下一个字节间隔一定的时间,以微秒为单位。

这是我的代码 sn-p

                        Dim t1 As New Stopwatch
                        Dim WatchTotal As New Stopwatch

                        WatchTotal.Reset()
                        WatchTotal.Start()

                        t1.Stop()
                        For i As Integer = 0 To _buffer.Length - 1

                            SerialPort1.Write(_buffer, i, 1)

                            t1.Reset()
                            t1.Start()

                            While ((1000000000 * t1.ElapsedTicks / Stopwatch.Frequency) < 50000) ' wait 50us
                            End While
                            t1.Stop()
                        Next

                        WatchTotal.Stop()

                        Debug.Print(WatchTotal.ElapsedMilliseconds)

线程内的一切都在循环。

一切正常,但在装有 Windows 7 的机器上,1 字节的 Serial.write 需要 1 毫秒,所以如果我们必须发送 1024 字节,则需要 1024 毫秒。

这可以通过打印经过的时间来确认

Debug.Print(WatchTotal.ElapsedMilliseconds)

问题似乎出在 SerialPort.Write 方法中。 在装有 Windows 10 的机器上执行相同的代码只需不到 1 毫秒。

当我们必须发送许多字节缓冲区时,问题更加明显,在这种情况下,我们发送了 16 个 1027 字节的缓冲区。在 Win 7 上不到 20 秒,在 Win10 中不到一半(发送 1 个 1027 字节的缓冲区大约需要 120-150 毫秒,发送 16 个数据缓冲区不到 5 秒)。

有谁知道这可能取决于什么?

谢谢


编辑 22/05/2020

如果我删除调试打印和暂停通信的一点延迟,我总是有大约 1027 毫秒来发送 1027 个字节,所以我认为问题仅属于 SerialPort 方法,而不属于计时或秒表对象。这发生在 Windows 7 机器上。 Windows 10 机器上的相同可执行文件运行速度与预期一样快。

                        For i As Integer = 0 To _buffer.Length - 1
                            SerialPort1.Write(_buffer, i, 1)
                        Next

【问题讨论】:

  • 您能改用其中一种标准波特率吗?
  • 什么版本的.Net?
  • .NET Framework 4.0,波特率为 115200 bps。我不能走得更快。
  • 可能异步发生。您希望 TOTAL 中的每个字符都有固定的时间。您在写入后启动计时器。您想先启动计时器,然后发送,然后等待剩下的。因此,无论硬件是否有点慢/快地接受 1 个字符,您总是花费相同的时间来发送 1 个字符。在我看来,应该读取其他一些位/状态以告知该字符已被处理,因此您可以在硬件允许的情况下以最快的速度继续前进。但是,如果您固定时间,那么在完全操作时使其相同 - 而不是在 char 消失之后。

标签: vb.net windows-7 serial-port


【解决方案1】:

有一件事,你的等待代码看起来很麻烦,试试这个。

        'one tick is 100ns, 10 ticks is as microsecond
        Const wait As Long = 50L * 10L ' wait 50us as ticks
        While t1.ElapsedTicks < wait
        End While

繁忙的循环是有问题的,并且因机器而异。我记得在 Win7 上串行端口处理不是很好,但我可能弄错了。

很难相信接收器对时间如此敏感。

【讨论】:

  • 从机是一个微控制器,它接收每个字节并将其存储在闪存中,是的,它真的很敏感。我已经尝试了您的代码并产生了与以前版本相同的输出:1027 1027 1027 1030 1027 1027 问题似乎出在 Serial.write 方法中,因为如果我删除 while 语句,我会在控制台上得到相同的输出
  • 我认为是 SerialPort 问题,请参阅我在原帖中的编辑
【解决方案2】:

如果 Win7 工作站没有或未使用高分辨率计时器,则可能是所描述的差异的原因。

来自StopWatch class的备注部分:

秒表通过计算底层计时器机制中的计时器滴答来测量经过的时间。如果安装的硬件和操作系统支持高分辨率性能计数器,则 Stopwatch 类使用该计数器来测量经过的时间。否则, Stopwatch 类使用系统计时器来测量经过的时间。使用频率和 IsHighResolution 字段来确定秒表计时实现的精度和分辨率。

检查IsHighResolution field 以确定是否正在发生这种情况。

【讨论】:

  • 我不认为是计时器分辨率的问题。请参阅原始帖子中的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 2011-12-27
  • 1970-01-01
  • 2015-09-09
  • 2018-08-11
  • 1970-01-01
  • 2011-04-15
相关资源
最近更新 更多