C#如何将串口接收的带30H偏移的4字节数据转换为1字节HEX值
串口字节序列转换实现方案
核心逻辑说明
当前使用的串口协议本质是将16位整型值的每1位十六进制数(即4位长度的半字节nibble)单独拆分,对每个半字节值加0x30偏移后作为独立字节传输,单帧有效载荷固定为4字节,对应1个16位数值,需要的单字节0x2A是该16位值的低8位结果。
之前转换出错的原因是:减去偏移后直接将每个字节作为8位完整有效值拼接,实际上每个字节仅低4位为有效数据,高4位固定为0,必须按半字节移位规则拼接才能得到正确结果。
具体实现步骤
- 步骤1:偏移去除
对接收的4个原始字节逐个减去0x30,得到4个范围在0x0~0xF的半字节值,对应十六进制数从高位到低位的4个数位。以接收的30 30 32 3A为例,减偏移后得到序列[0x0, 0x0, 0x2, 0xA]。 - 步骤2:半字节拼接为16位整型
按高位到低位的顺序,对4个半字节移位后做按位或运算,拼接为完整16位值,计算公式为:full_val = (n0 << 12) | (n1 << 8) | (n2 << 4) | n3
代入示例值计算:(0<<12) | (0<<8) | (2<<4) | 0xA = 0 + 0 + 32 + 10 = 42,对应十六进制0x002A。 - 步骤3:提取目标单字节
由于当前场景下有效数值范围为0~255,16位值的高8位固定为0,直接和0xFF做按位与取低8位,即可得到目标单字节值0x2A,对应十进制42。
参考代码(Python)
# 串口接收的原始4字节序列 recv_data = bytes([0x30, 0x30, 0x32, 0x3A]) # 去除0x30偏移得到半字节序列 nibbles = [byte - 0x30 for byte in recv_data] # 异常校验:半字节值必须在0~15范围内,否则判定为传输出错 for n in nibbles: if not (0 <= n <= 0xF): raise ValueError("接收数据格式错误") # 拼接为16位数值 full_value = (nibbles[0] << 12) | (nibbles[1] << 8) | (nibbles[2] << 4) | nibbles[3] # 取低8位得到最终结果 result = full_value & 0xFF print(f"十六进制结果: {hex(result)}") # 输出 0x2a print(f"十进制结果: {result}") # 输出 42
补充说明
发送端逻辑可按反向规则实现:将待发送的16位数值拆分为4个半字节,每个半字节加0x30偏移后按顺序通过串口发出即可,和描述的主机发指令逻辑完全匹配。
内容的提问来源于stack exchange,提问作者Vzitiv Igor
相关产品推荐
相关产品推荐

