【问题标题】:Extra bytes 3F received serialport c#额外字节 3F 收到串口 c#
【发布时间】:2018-11-04 13:23:56
【问题描述】:

我正在制作一个项目,该项目意味着 PIC18F4610 通过 Zigbee 无线 UART 与带有无线 Zigbee 模块的 USB 串行端口进行通信。当我按下 PIC 上的按钮时,它会向 USB 端口上的另一个 Zigbee 模块无线发送一个 10 字节的数据包(字节)。 它发送的数据包是 0A 01 80 90 A0 B0 C0 D0 E0 F0。 如果我在 PC 上使用任何像 RealTerm 这样的终端程序,我会收到发送的确切字节包。 但是,在我的程序中,我(通常)得到以下数据包: 3F 3F 0A 01 80 90 A0 B0 C0 D0 E0 F0 包括发送的良好数据包,但开头有两个 3F(即,发送的是 12 个字节而不是 10 个字节)。我可以通过程序来克服这个问题,但有时它只在开头放置一个 3F,而其他的它在数据包项目之间滑动一个 3F。没有丢包项,只是到处加3F(只有一两个),一般在开头。 我已经检查了编码,因为 3F 是当找不到一个字符进行编码时,但它似乎没问题,因为它确实收到了 F0。 串行端口在接收到发送的数据包时是打开的。它的配置:

ST.puertoserie.PortName = "COM1";
ST.puertoserie.BaudRate = 9600;
ST.puertoserie.Parity = (Parity) 1;
ST.puertoserie.DataBits = 8;
ST.puertoserie.StopBits = (StopBits) 1;
ST.puertoserie.Encoding = System.Text.Encoding.GetEncoding(28591);

已定义 DataReceived 事件处理程序,并在串行端口接收字节时触发。

    ST.puertoserie.DataReceived += new SerialDataReceivedEventHandler(RecepcionBytePuertoSerie);

事件处理程序(ST 是我拥有的一个全局类,包括一些变量和串行端口):

private void RecepcionBytePuertoSerie(object sender, SerialDataReceivedEventArgs e)
 {
     while(ST.puertoserie.BytesToRead > 0) {
     ST.rxcadena[ST.rxindex] = (byte) ST.puertoserie.ReadByte(); 
     ST.rxindex++; 
  }

   byte[] kprueba = new byte[ST.rxindex];
   for (int t = 0; t < ST.rxindex; t++) { kprueba[t] = ST.rxcadena[t]; }
   MessageBox.Show(BitConverter.ToString(kprueba).Replace("-", " "));   // Display bytes in message box
   ST.rxindex = 0; 
   ST.puertoserie.DiscardInBuffer(); 
 }

关于为什么会发生这种情况的任何线索?我已经尝试了各种各样的东西,但没有办法。终端仿真器正确接收。程序中必须有一些潜在的原因,等等。现在程序只用一个简单的形式来做这件事,直到我可以让串行通信工作。无线似乎不是问题(隐藏代码或任何东西),因为终端仿真器准确接收 PIC 发送的内容。由于终端仿真器正确接收,Windows 似乎也不是问题。 任何线索/帮助? 保罗

【问题讨论】:

  • 它确实像编码问题一样大声嘎嘎,但 sn-p 无法解释。通过修复此代码中的可见错误来取得成功。您必须删除 DiscardInBuffer() 调用,它会随机丢弃数据。并且 ST.rxindex = 0 分配需要正确完成,现在它完全是偶然的。通过计算字节数或采用允许您始终检测消息的开始和结束的协议来做到这一点。
  • .NET SerialPort 类是我曾经使用过的 buggiest pieces of bad code 之一。有时它工作,有时它不 - 它与一些设备合作,而另一些则没有。不止一次,我不得不放弃它并转向不同的解决方案。可能是您的实现有问题,但我个人已经达到了 SerialPort 类的目的,我已经停止给予它怀疑的好处。
  • 至少,根据上面的链接,尝试重写以避免使用DataReceived 事件和BytesToRead 属性。如果您必须使用SerialPort 类,最好将所有处理放入其自己的线程并运行循环以在该线程上同步服务端口。这可以让您绕过 .NET 类中最严重的问题。

标签: c#


【解决方案1】:

在使用串行 RS232 协议与设备通信时,我也遇到了非常类似的问题。我的软件(使用 System.IO.Ports 用 C# 编写)还在收到的消息中引入了 3F(ASCII = "?")。我通过根据设备需要进行相同的端口配置(奇偶校验、停止位、...)来解决它。我的问题是我使用的是 serialPort.Parity = Parity.Even,而不是 Parity.None(正如设备要求的那样)。

在其他论坛上(似乎是一个经常遇到的问题)它说问题是 c# SerialPort 类正在使用的编码。 对我没有帮助,但看看这个链接,也许它对你有帮助:https://social.msdn.microsoft.com/Forums/en-US/efe127eb-b84b-4ae5-bd7c-a0283132f585/serial-port-sending-8-bit-problem?forum=Vsexpressvb

【讨论】:

    【解决方案2】:

    感谢您的回答。

    现在我已经物理地桥接了串行端口的 Tx 和 Rx 引脚。 该程序运行正常。完美的。对 USB 转串口设备执行相同操作时,我会进行更新。应该可以正常工作。如果是这样,我将传递给无线 UART 设备,这些设备对于 Realterm 工作非常完美,但对于 C# 奇怪的字节 (3F) 开始出现。会更新,因为我除了周末没有太多时间。现在我已经实现了对工作正常的数据包的 CRC16 检查。 为什么没有正确编程串行端口类的人?还是之后改正? 另一方面,如果我写出一个不使用DataReceivedBytesToRead 的协议,我将不得不创建固定长度的数据包,因为我不知道何时完成接收数据,因为我无法确定代码可能代表数据包结束的数据可能已损坏和/或永远不会到达。必须考虑到我正在接收尚未真正发送的“幽灵”字节。此外,数据包可能会被截断,并且不会接收到所有数据包,并且线程会无休止地等待。现在必须考虑一下。 我会继续更新更多(很可能是问题而不是解决方案)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      相关资源
      最近更新 更多