使用SerialPort的ReadExisting()无法保留>127的字节值问题咨询
解决SerialPort读取二进制数据时高字节被替换的问题
这个问题的核心原因很明确:你用的ReadExisting()方法是按字符串读取串口数据,而SerialPort默认使用的是ASCII编码——ASCII编码只覆盖0x00到0x7F的范围,任何超过0x7F的字节都会被自动替换成0x3F(也就是问号字符),这就是你看到数据丢失的原因。
想要获取原始的二进制字节数组,你需要改用SerialPort.Read()方法,它直接读取字节流,不会做编码转换。下面是修改后的代码示例:
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) { // 先获取串口当前可用的字节数 int bytesAvailable = serialPort1->BytesToRead; // 创建对应大小的字节数组来存储原始数据 array<System::Byte>^ rawBytes = gcnew array<System::Byte>(bytesAvailable); // 将串口数据读取到字节数组中 int bytesRead = serialPort1->Read(rawBytes, 0, bytesAvailable); // 现在rawBytes里就是完整的原始二进制数据了,你说的0x80会被完整保留 // 如果需要转为字符(即使是不可打印的),可以用单字节编码直接映射,比如Latin1 System::String^ rawStr = System::Text::Encoding::Latin1->GetString(rawBytes, 0, bytesRead); }
补充说明:
- 如果单片机发送的是纯二进制数据,优先用字节数组来处理,完全避免编码转换带来的干扰。
- 如果确实需要转成字符串,别用默认的ASCII编码,选择单字节编码(比如Latin1/ISO-8859-1),这种编码会把每个字节直接映射为对应的Unicode字符,不会替换任何字节。
内容的提问来源于stack exchange,提问作者Diego Colombo
相关产品推荐
相关产品推荐

