繁体   English   中英

什么会影响Serialport.Read()返回的值

[英]What Could Affect Values Returned By Serialport.Read()

我已经使用.Net Framework 2.0 Serialport类在C#2.0中编写了一个简单的应用程序,以通过COM1与控制器卡进行通信。

最近发生的问题是Read方法返回的字节不正确。 它返回正确的字节数,只有值不正确。 但是,用Delphi编写的类似应用程序仍返回正确的值。

我使用Portmon在两个应用程序的串行端口上记录了活动,比较了两个日志,并在那里找到了一些(显然)次要的不同设置,并且我尝试尽可能地模仿Delphi应用程序,但无济于事。

那么,什么会影响Read方法返回的字节值呢?

两个应用之间的大多数设置都是相同的。

以下是Portmon日志中不同的行的列表:

Delphi应用程序:

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF:dc ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW的Serial0成功摇:0替换:0 XonLimit:256 XoffLimit:256 IOCTL_SERIAL_SET_TIMEOUTS的Serial0 SUCCESS RI:-1 RM:100 RC:1000 WM:100 WC:1000 IOCTL_SERIAL_SET_WAIT_MASK的Serial0 SUCCESS面膜:RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR RING RX80FULL

C#应用程序:

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13 IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake:0 Replace:0 XonLimit:1024 XoffLimit:1024 IOCTL_SERIAL_SET_TIMEOUTS Serial0 SUCCESS RI:-1 RM: WM:0 WC:1000 IOCTL_SERIAL_SET_WAIT_MASK串行0成功掩码:RXCHAR RXFLAG CTS DSR RLSD BRK ERR RING

更新:

正确的返回字节为:91、1、1、3、48、48、50、69、66、51、70、55、52、93(14个字节)。 最后一个值是简单的校验和。

返回的错误值是:91、241、254、252、242、146、42、201、51、70、55、52、93(13个字节)。

如您所见,返回的前五个字节对应。

ErrorReceived事件表明发生了帧错误,这可能解释了错误的值。 但是问题是,为什么Delphi应用程序显然没有,SerialPort为什么会遇到成帧错误?

好吧,看来问题已经解决了(至少暂时没有解决)。

显然,成帧错误导致返回不正确的值。 我使用MSComm控件编写了一个VB6应用程序,该应用程序运行良好,并比较了Portmon生成的日志文件。

我总结了以下差异

VB6应用程序:

IOCTL_SERIAL_SET_HANDFLOW串行0成功摇动:1替换:0 XonLimit:256 XoffLimit:256

C#应用程序:

IOCTL_SERIAL_SET_HANDFLOW串行0成功摇动:0替换:0 XonLimit:1024 XoffLimit:1024

进行设置,我发现如果我设置_serialPort.DtrEnable = true则C#App会生成以下日志条目:

IOCTL_SERIAL_SET_HANDFLOW串行0成功摇动:1替换:0 XonLimit:1024 XoffLimit:1024

这似乎可以防止框架错误,并且该应用程序似乎运行正常。

您是否检查过数据位数,停止位和奇偶校验的设置?

奇偶校验位是一种错误检测机制。 例如:如果使用7个数据位和一个奇偶校验位进行发送,则第八个位将用于检测位反转错误。 如果接收器需要8个数据位而没有奇偶校验位,则结果将出现乱码。

不幸的是,您没有确切提及得到的区别类型。 是偶尔出现的字符不同还是您输入的所有数据乱码? 请注意,由于设置了SerialPort.Encoding属性,系统可能会更改通过SerialPort.Read函数读取的字符。 此设置会影响传入文本的解释,因为传入文本是ASCII,Unicode,UTF8或Windows用于“原始字节”到“可读文本”转换的任何其他编码方案的文本。

如果您正在读取一个字节数组(例如:SerialPort.Read),则应该确切获得在PortMon上看到的字节。

如果要转换为字符(SerialPort.ReadLine或SerialPort.ReadChar),则将使用当前编码(SerialPort.Encoding属性)对数据进行编码,这将说明您所看到的差异。

如果你想看到相同的二进制值电线上的字节字符,一个良好的编码使用的是拉丁语-1中描述的这个帖子

例:

SerialPort.Encoding = Encoding.GetEncoding("Latin1")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM