【问题标题】:Does Write send all bytes? (Serial Port)写入是否发送所有字节? (串行端口)
【发布时间】:2014-11-27 06:57:22
【问题描述】:

SerialPort 的Write 方法是否会写入它被告知的所有字节? 我有这段代码可以通过串口发送数据。

            SerialPort port = new SerialPort(
              "COM1", 9600, Parity.None, 8, StopBits.One);

            // Open the port for communications
            port.Open();

            // Write bytes
            byte[] bytes = Encoding.ASCII.GetBytes("Hello world from PC");
            port.Write(bytes, 0, bytes.Length);

            // Close the port
            port.Close();

如果我发送字符串“Hello”,则通过串口连接到我的 PC 的设备会很好地接收它。如果我发送字符串“来自 PC 的 Hello world” 它只接收 前 16 个字节而不是 19 个。 有没有办法可以在代码中验证所有字节都已发送?还是串口连接的硬件问题?

【问题讨论】:

  • 你能发布你如何接收数据的代码吗??
  • OK...但是您确定该设备能够读取所有发送的字节...?通过查看您的代码,字节/数据应该可以毫无问题地发送..
  • 或者在发送前尝试检查 CTS (Clear to send)..
  • @User2012384:我会尝试与硬件制造商核实
  • 如果您指定接收设备的确切含义,这可能会很有用。另见stackoverflow.com/questions/5723627/…

标签: c#


【解决方案1】:

是的,.Write 是同步的,所以所有数据都在返回之前发送。无论如何,你做的 30 秒超时就足够了,如果它不会的话。

【讨论】:

    【解决方案2】:

    通常会发送所有字节。也许问题出在接收方。 要确保关闭握手,请使用此代码,但我相信它已经是默认设置:

    serialPort.Handshake = Handshake.None;
    

    我怀疑接收方。另一端的 UART 可能不够快,无法将字符从缓冲区中取出。也许您可以尝试在消息的各个部分之间添加一些小的延迟,但这当然只是为了进行故障排除。像这样:

            // Write bytes for test purpose
            byte[] bytes = Encoding.ASCII.GetBytes("Hello world from PC");
            port.Write(bytes, 0, 10);
            Thread.Sleep(100); // small delay
            port.Write(bytes, 10, 9); // next block
    

    【讨论】:

    • 我的意思是,它不应该成为您最终解决方案的一部分。嵌入式设备通常具有较小的缓冲区,当它们没有足够快地清空时,您会丢失字符。在上面的代码中,嵌入式设备有大约 100 毫秒的时间来处理传入的字符;这应该足够了。然后下一个字节可以进来。但是您读取了 16 个字节...这可能是嵌入式端缓冲区的大小吗?
    • 可能不需要更改硬件。只有字节以有效的较低速度流动(当然,波特率保持不变)。您甚至可以将其拆分为更多的写入,这些写入具有更小的尺寸和更小的延迟。但回到嵌入式设备制造商可能是最好的办法。
    【解决方案3】:

    我遇到了类似的问题。 我将一个 20 字节的数组写入连接到无线发射器的串行端口。发送完所有字节后,我需要切换回接收模式。 因此,有必要准确知道所有字节何时从串行端口物理写出。 不幸的是,这在 Windows 下是不可能的,因为缓冲区查询不返回物理芯片缓冲区的状态。

    我的解决方案是使用 serialPort.BaseStream.WriteAsync 异步发送数据 然后通过将字节数乘以波特率来计算传输时间:

    serialPort.BaseStream.WriteAsync(buffer,0,buffer.length);
    int waittime = (int)((double)buffer.length * (10/(double)baudrate) + some_reserve);
    Thread.Sleep(waittime);
    

    “10”表示一个字节由 10 位组成

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      相关资源
      最近更新 更多