串行端口上的十六进制转换错误

Posted

技术标签:

【中文标题】串行端口上的十六进制转换错误【英文标题】:Hex translation error over a serial port 【发布时间】:2014-02-23 12:35:59 【问题描述】:

这是一个我无法弄清楚的奇怪现象。我非常感谢任何人的任何意见。

我正在尝试从通过 XBEE 无线卡连接到我的 PC 的 arduino 接收温度数据。接收 XBEE 直接连接到我 PC 上的 COM8 串行端口。我有一个非常简单的 C# 程序,它使用串行端口类接收数据。首先它从串口读取一个字符

    *private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    
        //RxString = serialPort1.ReadExisting();
        RxRead = serialPort1.ReadChar();
        //RxRead = 0x13;
        this.Invoke(new EventHandler(DisplayText));
    *

(忽略注释掉的位。它们是其他实验!)。然后,使用 RxRead int 将我写入的数据传输到一个简单的 Web 表单上。

    private void DisplayText(object sender, EventArgs e)
    

            RxString = RxRead.ToString();
            textBox1.AppendText(RxString);
            textBox1.AppendText(", ");
    

它在 Web 表单上打印得很好。

126, 0, 125, 51, 63, 0, 125, 51, 63, 0, 64, 63, 63, 82, 63, 63, 1, 49, 57, 46, 48, 48, 13, 10 , 63,

除了,上面的 125、51 流中的两个实例不正确。它们应该是十进制 19,十六进制 13。我知道是这种情况,因为协议定义明确,我可以使用 XCTU 程序看到来自 XBEE 的十六进制数据,(见下文)

接收数据包

7E 00 13 90 00 13 A2 00 40 A6 90 52 90 9A 01 31 39 2E 31 32 0D 0A B5

- Start delimiter: 7E
- Length: 00 13 (19)
- Frame type: 90 (Receive Packet)
- 64-bit source address: 00 13 A2 00 40 A6 90 52
- 16-bit source address: 90 9A
- Receive options: 01
- Received data: 31 39 2E 31 32 0D 0A
- Checksum: B5

谁能想到为什么这个程序应该非常愉快地接收每个字节,但每次遇到十六进制 13 时都会发出嘶嘶声? (哦,我试过用 readbyte 代替 readchar,它给了我同样的东西。

非常感谢您的任何想法)。

【问题讨论】:

是同一个数据,只是显示方式不同而已。一个以 16 为底(十六进制),另一个以 10 为底(十进制)。只是值如何打印的问题,字节值是相同的。你得到的 63 个值是 '?' 的 ASCII 码。你得到它是因为你不能使用 ReadExisting() 来读取二进制数据。您必须使用 Read()。 注意字节顺序(big-endian 或 little-endian)对于 c#,请参见此处:msdn.microsoft.com/en-us/library/… 【参考方案1】:

确保在初始化串行端口时关闭 XOn/Xoff 流控制。 0x13 对应 XOFF,即“暂停传输”,它将从您收到的流中剥离。之后会发生什么我没有确切的解释,但是如果 XOn/Xoff 被启用,那么你要做的第一件事就是禁用它。

【讨论】:

太棒了。我相信就是这样。很抱歉发布后续,但是您如何关闭 XON/XOFF 流控制? 在本机代码中,它将使用 SetCommState 函数 MSDN 和 DCB 结构 MSDN。在 C# 中,尝试 PInvoke 和 PInvoke 或查看 ***。 使用 .NET Port 类,设置在 Handshake 属性中 ([MSDN]msdn.microsoft.com/en-us/library/…)。【参考方案2】:

我认为您应该使用ReadByte() 而不是ReadChar(),因为您正在读取二进制数据。如果切换到该方法,它会开始打印正确的值吗?

附加信息:

设置第 8 位的任何字节都表示为 63(0x3F,'?')。 由于某种原因,0x13 字节被打印为两个字节:0x7D、0x33 ("3")。

你是在8位模式下打开串口吗?

【讨论】:

奇怪的是,这两种方法都完全相同。不过谢谢你的想法。 这很有趣,因为所有打印的值都是 7 位的。我对 C# 不熟悉——RxRead 是什么数据类型?你是怎么打开串口的?您是否缺少将其设置为 8N1 的代码?

以上是关于串行端口上的十六进制转换错误的主要内容,如果未能解决你的问题,请参考以下文章

从端口C#二进制数据转换为十六进制字符串

Flutter 将十六进制转换为 Uint8list

二进制怎样转换成8421BCD码?

串口二进制传输改回车

从串行端口发送十六进制数据的问题

C语言中的Modbus ASCII LRC生成