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

时间:2008-09-22 22:12:26

标签: .net serial-port

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

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

我使用Portmon来记录两个应用程序的串行端口上的活动,比较两个日志,其中有一些(显然)次要的不同设置,我试图尽可能地模仿Delphi应用程序,但无济于事。

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

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

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

Delphi App:

  

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF:dc   错误:0 BRK:0 EVT:0 XON:11 XOFF:13
  IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: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#App:

  

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF:1a   错误:0 BRK:0 EVT:1a XON:11 XOFF:13   IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake:0   替换:0 XonLimit:1024    XoffLimit:1024 IOCTL_SERIAL_SET_TIMEOUTS Serial0 SUCCESS RI:-1    RM:-1 RC:1000 WM:0 WC:1000 IOCTL_SERIAL_SET_WAIT_MASK Serial0 SUCCESS面具:   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会遇到帧错误?

4 个答案:

答案 0 :(得分:2)

好吧,好像问题已经解决了(至少目前是这样)。

显然,帧错误导致返回错误值。我编写了一个VB6应用程序,使用MSComm控件,工作正常,并比较了Portmon生成的日志文件。

我发现了以下差异

VB6 App:

  

IOCTL_SERIAL_SET_HANDFLOW Serial0   成功摇:1 替换:0   XonLimit:256 XoffLimit:256

C#App:

  

IOCTL_SERIAL_SET_HANDFLOW Serial0   成功震动:0 替换:0   XonLimit:1024 XoffLimit:1024

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

  

IOCTL_SERIAL_SET_HANDFLOW Serial0   成功摇:1 替换:0   XonLimit:1024 XoffLimit:1024

这似乎可以防止框架错误,应用程序似乎工作正常。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

不幸的是,您没有提到您获得的差异。是偶然的角色是不同的还是所有传入的数据都是乱码? 请注意,由于SerialPort.Encoding属性的设置,系统可能会更改通过SerialPort.Read函数读取的字符。此设置会影响传入文本的解释,因为它是ASCII,Unicode,UTF8中的文本或Windows用于“原始字节”到“可读文本”转换的任何其他编码方案。

答案 3 :(得分:0)

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

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

如果要查看与线路上的字节具有相同二进制值的字符,则使用的良好编码是Latin {1,如this post中所述。

示例:

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