質問
System.IO.Ports.SerialPort クラスを使用してシリアル ポートを開いて読み取ろうとしています。シリアル ポートをツール ペイン (VS 2008) から Windows フォームにドラッグしました。プロパティ グリッドをセットアップしたので、実行時にシリアル ポートのプロパティを簡単に変更できます。ポートを開こうとすると、次のようなエラーが表示されます。ハイパーターミナルを使用してポートを開いて読み取ることができるため、理由がわかりません。何か案は?
System.IO.IOException Error connection: A device attached to the system is not functioning
at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.InternalResources.WinIOError()
at System.IO.Ports.SerialStream.set_DtrEnable(Boolean value)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at Test.CardReader.frmMain.Connect() in D:\Develop\2.0\Projects\Kiosk\EmbeddedBrowser\Windows Forms\Test.CardReader\Form1.cs:line 166
注意してください、これはUSB接続であるため、それは私の設定が次のとおりである仮想シリアルポートです。
ボーレート = 9600
データビット = 8
DiscardNull = false
DtrEnable = false
ハンドシェイク = なし
パリティ = なし
パリティ置換 = 63
ポート名 = COM3
読み取りバッファサイズ = 4096
読み取りタイムアウト = -1
受信バイト = 1
TrsEnable = False
ストップビット = 1
書き込みバッファサイズ = 2048
書き込みタイムアウト = -1
PortMon を sysinternals からダウンロードしました。2 つのログをキャプチャしました。1 つ目は、ハイパーターミナルがポートを開いたときに何が起こるかというログです。2 つ目は、.net SerialPort クラスがポートを開こうとしたときに何が起こるかです。
ハイパーターミナル:
IRP_MJ_CREATE USBSER000 SUCCESS Options: Open
IOCTL_SERIAL_SET_QUEUE_SIZE USBSER000 SUCCESS InSize: 8192 OutSize: 8192
IOCTL_SERIAL_CONFIG_SIZE USBSER000 SUCCESS Size: 0
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_SET_RTS USBSER000 SUCCESS
IOCTL_SERIAL_SET_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:f6 XOFF:6
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:80000001 Replace:80000040 XonLimit:80 XoffLimit:200
IOCTL_SERIAL_SET_TIMEOUTS USBSER000 SUCCESS RI:10 RM:0 RC:0 WM:0 WC:5000
IOCTL_SERIAL_SET_WAIT_MASK USBSER000 SUCCESS Mask: RLSD ERR
IOCTL_SERIAL_GET_MODEMSTATUS USBSER000 SUCCESS
IOCTL_SERIAL_WAIT_ON_MASK USBSER000
IRP_MJ_READ USBSER000 Length 80
.Netシリアルポート:
IRP_MJ_CREATE USBSER000 SUCCESS Options: Open
IOCTL_SERIAL_GET_PROPERTIES USBSER000 SUCCESS
IOCTL_SERIAL_GET_MODEMSTATUS USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_CLR_RTS USBSER000 SUCCESS
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:0 Replace:0 XonLimit:4096 XoffLimit:4096
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_CLR_RTS USBSER000 SUCCESS
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:0 Replace:0 XonLimit:4096 XoffLimit:4096
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IRP_MJ_CLEANUP USBSER000 SUCCESS
IRP_MJ_CLOSE USBSER000 SUCCESS
解決
ハイパーターミナルと .NET シリアル ポート オブジェクトの違いについては、ハイパーターミナルは商用の安定したアプリです。基礎となるシリアル ポート オブジェクトが停止するか例外をスローした場合、ハイパーターミナルはそれを隠しました。.NET シリアル ポート オブジェクトは、私が使用した他の .NET オブジェクトよりも多くの例外をスローします。
ポイント:
- 設定を変更するときは、まず設定を閉じ、変更してから再度開きます。一部のポートは、開いたまま変更すると非常に嫌がります。
- シリアル ポート オブジェクトや実行するあらゆる動作について、多くの「try-catch」を実行することが予想されます。
- リストされている可能性のある例外ごとに 1 つずつ用意し、それぞれがメッセージを確認するようにしてください (状況によっては異なる可能性があります)。多くは閉じて再度開くだけで回復可能です。
- 例外がスローされている場所を正確に追跡してみてください。設定した順序を変更すると問題が解決するかどうかを確認してください...オブジェクトは本当に気難しいです。
開く前に DTR を明示的に false に設定しようとした場合は、そのデバイスをニヤニヤしながら裸にするだけで済むかもしれません。SerialPort オブジェクトは、.NET で適切に実装されたライブラリの輝かしい例の 1 つではありません。気が付けば、ハイパーターミナルでも同じエラーが発生しますが、無視されます。
可能であれば、通常のシリアル ポートまたは別のブランドの USB デバイスで試してください。それでも同じエラーが発生する場合は、アプリ側に問題がある可能性があります。
他のヒント
実際のUART
では、DTREnable
は、あなたがデータを受信する準備ができているを示すために、あなたのDTR
のUART
ピンをアサートします。
あなたのドライバの実装に応じて、ポートを開くためにDTREnable
するtrue
を設定する必要があります。
このフォーラム投稿を参照してください。私はそれがハードウェアやドライバの誤動作に関係している疑いがあります。それはしかし、ハイパーターミナルで動作する理由を説明しません。ハイパーターミナルが異なりやっているかを確認するジョセフM.新人からのアドバイスに従ってください。
それが見えます。
私はSERIALPORTクラスに問題がなかった800,000 bpsで走ったのアプリを書いています。