2008-09-22 100 views
4

我寫了一個簡單的應用程序在C#2.0中使用.Net Framework 2.0 Serialport類通過COM1與控制器卡進行通信。什麼可能影響值由Serialport.Read()

最近發生的問題是Read方法返回的字節不正確。它返回了適量的字節,只有值不正確。用Delphi編寫的類似應用程序仍然返回了正確的值。

我用Portmon來記錄兩個應用程序的串行端口上的活動,比較兩個日誌,並在那裏顯示了一些(顯然)小的不同設置,我嘗試儘可能地模仿Delphi應用程序,但是沒有無濟於事。

那麼,什麼會影響Read方法返回的字節值呢?

這兩個應用程序之間的大部分設置都是相同的。

這裏是一個不同的Portmon日誌中的行的列表:

Delphi應用程序:

IOCTL_SERIAL_SET_CHAR的Serial0 SUCCESS EOF:直流 ERR: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#應用程序:

IOCTL_SERIAL_SET_CHAR的Serial0 SUCCESS EOF:1A ERR:0 BRK:0 EVT:1A XON:11 XOFF:13 IOCTL_SERIAL_SET_HANDFLOW的Serial0 SUCCESS搖: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

UPDATE:

正確返回的字節分別爲: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會遇到幀錯誤?

+0

也許你可以給一些錯誤的數據的樣本,旁邊的是正確的。如果我們能看到什麼是不正確的,我們可能會猜到這個問題。 – ravenspoint 2008-09-22 22:30:47

回答

2

嗯,好像問題已經得到解決(至少暫時)。

顯然,一個幀錯誤導致不正確的值返回。我使用MSComm控件編寫了一個VB6應用程序,該程序運行良好,並比較了Portmon生成的日誌文件。

我拿起以下區別

VB6應用程序:

IOCTL_SERIAL_SET_HANDFLOW的Serial0 SUCCESS 搖:1替換:0 XonLimit:256 XoffLimit:256

C#應用:

IOCTL_SERIAL_SET_HANDFLOW的Serial0 成功搖:0替換:0 XonLimit:1024 XoffLimit:1024

與我發現,如果我設置 _serialPort.DtrEnable = true 的C#應用​​程序生成以下日誌條目的設置打圍:

IOCTL_SERIAL_SET_HANDFLOW的Serial0 SUCCESS 搖:1替換:0 XonLimit:1024 XoffLimit:1024

這似乎阻止了框架錯誤和應用程序似乎工作正常。

0

您是否檢查過數據位數,停止位和奇偶校驗的設置?

奇偶校驗位是一種錯誤檢測機制。例如:如果使用7個數據位和一個奇偶校驗位發送,則第8位將用於檢測位反轉錯誤。如果接收器需要8個數據位並且沒有奇偶校驗位,結果將會出現亂碼。

0

不幸的是,你沒有提到你得到的是哪種類型的差異。這是一個偶然的字符,是不同的還是所有傳入的數據都亂碼? 請注意,由於設置了SerialPort.Encoding屬性,系統可能會更改通過SerialPort.Read函數讀取的字符。此設置影響傳入文本的解釋,因爲它是以ASCII,Unicode,UTF8或Windows用於「原始字節」到「可讀文本」轉換的任何其他編碼方案的文本。

+0

我也認爲它可能是編碼,因爲IOCTL_SERIAL_SET_CHAR設置略有不同,我認爲它可能與編碼有關。但是由於返回值是字節,編碼如何影響它呢?你能舉個例子嗎? – jakdep 2008-09-23 08:34:11

+0

啊,對不起,應該檢查一下自己。我看到編碼會影響用於表示單個字符的字節數量。 – jakdep 2008-09-23 08:57:52

0

如果你正在讀入一個字節數組(例如:SerialPort.Read),你應該得到正好在PortMon上看到的字節。

如果要轉換爲字符(SerialPort.ReadLine或SerialPort.ReadChar),那麼將使用當前編碼(SerialPort.Encoding屬性)對數據進行編碼,這將解釋您所看到的差異。

如果您希望看到與導線上的字節具有相同二進制值的字符,那麼使用的編碼是Latin-1,如this post中所述。

例子:

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