簡體   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