C# SerialPort串口通信返回值与Pascal synaser测试程序不一致问题
问题原因分析
- 异常返回的
0x3F是C#SerialPort类的默认校验错误替换值,而非总线上实际存在的数据:SerialPort类默认开启校验错误替换逻辑,当收到的字节出现奇偶校验错误时,会自动将错误字节替换为0x3F(对应ASCII字符?)。而Pascal的synaser库默认关闭了该替换逻辑,所以运行正常。 - 当前代码混用了
BaseStream写和SerialPort实例读:SerialPort.ReadByte()会经过内置的校验、编码转换逻辑,总线抓包确认写入数据正常,说明错误是C#串口类内部处理时生成的。 - 代码中未显式设置停止位、流控等参数,默认值可能和硬件要求不匹配,也会触发校验错误生成替换值。
解决方案
按以下步骤修改代码即可解决问题:
- 禁用校验错误替换逻辑,显式配置所有串口参数
// 确保StopBits参数和硬件要求一致,常用取值为One/Two/OnePointFive var port = new SerialPort(Port, 19200, Parity.Mark, 8, StopBits.One); port.ParityReplace = 0; // 禁用校验错误字节替换 // 部分硬件需要DTR/RTS信号才会正常返回数据,根据硬件要求选加 port.DtrEnable = true; port.RtsEnable = true;
- 写入完成后主动刷出缓冲区,避免数据滞留在串口缓存
port.BaseStream.WriteByte(0x00); port.BaseStream.WriteByte(0x01); port.BaseStream.Flush(); // 新增该行,确保数据立刻发出
- 改用
BaseStream读取原始字节,避开SerialPort内置的转换逻辑
将confirmation = port.ReadByte();替换为:
confirmation = port.BaseStream.ReadByte();
- 优化串口实例生命周期:不要每次发送都新建、开闭串口,频繁开闭串口会导致总线电平波动产生误码,建议全局复用同一个串口实例,程序初始化时打开,退出时关闭即可。
验证方式
修改完成后测试,如果不再返回0x3F仅返回0xAA,说明问题已解决。如果仍有异常,可通过总线抓包确认收到的原始数据是否仅包含0xAA,排除硬件本身返回异常数据的可能。
内容的提问来源于stack exchange,提问作者Adam Čuba
相关产品推荐
相关产品推荐

