C#串口读取十六进制数据异常问题求助
解决SerialPort读取单片机十六进制数据时高位字节被替换为0x3F的问题
问题根源
你遇到的0x7F以上字节被替换为0x3F(问号)的问题,核心是SerialPort的Encoding设置错误。你设置的Windows-1252编码会将无法映射的字节强制替换为0x3F,而你需要读取的是原始十六进制字节流,不是文本字符,这个编码设置完全多余,反而会干扰原始字节的读取。
解决方案
1. 修正SerialPort的编码设置
直接移除serialPort1.Encoding = Encoding.GetEncoding("Windows-1252");这行代码,或者替换为不会修改原始字节的编码(比如iso-8859-1,它会将每个字节一对一映射为对应字符,不会产生替换):
// 推荐:直接移除编码设置,或者使用iso-8859-1 serialPort1.Encoding = Encoding.GetEncoding("iso-8859-1");
2. 优化字节读取逻辑
当前代码每次只读1个字节,效率低且容易出现读取不完整的情况。建议先获取可用字节数,一次性读取所有到达的字节,再逐个处理:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { SerialPort sp = (SerialPort)sender; int bytesAvailable = sp.BytesToRead; byte[] tempBuffer = new byte[bytesAvailable]; int bytesRead = sp.Read(tempBuffer, 0, bytesAvailable); foreach (byte b in tempBuffer.Take(bytesRead)) { byte_input[count - 1] = b; count--; string hexValue = b.ToString("X2"); this.BeginInvoke(new Action(() => textBox1.AppendText(hexValue + " "))); if (count == 0) { value = BitConverter.ToSingle(byte_input, 0); Array.Clear(byte_input, 0, byte_input.Length); this.BeginInvoke(new EventHandler(ShowData)); count = 4; } } } catch (Exception ex) { this.BeginInvoke(new Action(() => textBox1.AppendText($"读取错误: {ex.Message}\n"))); } }
3. 校验串口参数
务必确保SerialPort的波特率、数据位、停止位、奇偶校验位和单片机的配置完全一致,参数不匹配也会导致读取到错误的字节。
补充说明
- 基于字符的读取方法(比如
ReadChar、ReadExisting)会受Encoding设置影响,读取原始字节时,优先使用Read(byte[])这类直接操作字节的方法。 - 调试时可以直接输出读取到的字节值,确认是否在读取阶段就已经出现错误,而不是后续显示环节的问题。
内容的提问来源于stack exchange,提问作者user24354609
相关产品推荐
相关产品推荐

