3

System.IO.Ports.SerialPort クラスを使用して、シリアル ポートを開いて読み取ろうとしています。シリアル ポートをツール ウィンドウ (Visual Studio 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 接続なので、実際には仮想シリアル ポートであることに注意してください。

私の設定は次のとおりです。

BaudRate = 9600
DataBits = 8
DiscardNull = false
DtrEnable = false
Handshake = None
Parity = None
ParityReplace = 63
PortName = COM3
ReadBufferSize = 4096
ReadTimeout = -1
ReceivedBytes = 1
TrsEnable = False
StopBits = One
WriteBufferSize = 2048
WriteTimeout = -1

SysinternalsからPortMonをダウンロードしました。2 つのログをキャプチャしました。1 つ目はHyperTerminalがポートを開いたときに発生するログで、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
4

5 に答える 5

4

HyperTerminal と .NET シリアル ポート オブジェクトの違いについては、HyperTerminal は商用の安定したアプリケーションです。基礎となるシリアル ポート オブジェクトが異常終了したか、例外をスローした場合、ハイパーターミナルはそれをユーザーから隠しました。.NET シリアル ポート オブジェクトは、私が使用した他のどの .NET オブジェクトよりも多くの例外をスローします。

ポイント:

  • 設定を変更するときは常に、最初に閉じてから変更してから、再度開きます。一部のポートは、開いているときに変更すると本当に嫌いです。
  • シリアルポートオブジェクトの周りで、あなたが行うすべてのことについて、多くの「try-catch」を行うことを期待してください。
  • リストされている可能性のある例外ごとに 1 つあることを確認し、それぞれがメッセージをチェックしていることを確認してください (状況によって異なる場合があります)。多くは、閉じて再度開くだけで回復できます。
  • 例外がスローされている場所を正確に追跡してみてください。設定した順序を変更すると問題が解決するかどうかを確認してください...オブジェクトは本当に厄介です。

開く前に DTR を明示的に false に設定しようとした場合は、ニヤニヤしてそのデバイスで我慢する必要があるかもしれません。SerialPort オブジェクトは、.NET で適切に実装されたライブラリの輝かしい例の 1 つではありません。ハイパーターミナルでも同じエラーが発生しますが、無視されます。

可能であれば、通常のシリアル ポートまたは別のブランドの USB デバイスで試してください。それでも同じエラーが発生する場合は、アプリケーション側に問題がある可能性があります。

于 2009-01-30T22:44:28.690 に答える
0

違いはハンドシェイクのようです。

serialport クラスで問題が発生したことはなく、800,000 ビット/秒で実行されるアプリケーションを作成しました。

于 2009-02-17T12:18:34.283 に答える
0

シリアル ポートのリスナーに問題がありました。メイン プロセスがスタックしてしまいました。これは同期であるためです。プロセス、スレッドとタイマーを作成することで解決しました

try
            {
                if (_serialConnection.IsOpen) _serialConnection.Close();
                _serialConnection.Open();
                Thread newThread = new Thread((obj) =>
                {
                    System.Timers.Timer timer = new System.Timers.Timer();
                    timer.Interval = 1000;
                    timer.Elapsed += (sender, e) =>
                    {
                        _slave.Listen();
                    };
                    timer.Enabled = true;
                    timer.Start();
                    
                });
                newThread.IsBackground = true;
                newThread.Start();
            }
            catch (Exception ex)
            {
                throw ex;
            }
于 2021-10-17T18:33:52.143 に答える