【问题标题】:Error opening serial port using the System.IO.Ports.SerialPort class使用 System.IO.Ports.SerialPort 类打开串行端口时出错
【发布时间】:2010-10-04 12:42:04
【问题描述】:

我正在尝试使用 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连接,所以它实际上是一个虚拟串口。

我的设置如下:

波特率 = 9600
数据位 = 8
DiscardNull = 假
DtrEnable = 假
握手 = 无
奇偶校验 = 无
奇偶校验替换 = 63
端口名称 = COM3
读取缓冲区大小 = 4096
读取超时 = -1
接收字节数 = 1
TrsEnable = 假
StopBits = 一
WriteBufferSize = 2048
写入超时 = -1

我从Sysinternals 下载了PortMon。我已经捕获了两个日志。第一个是日志HyperTerminal打开端口时发生了什么,第二个是.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

【问题讨论】:

  • IOException 的InnerException 有更多细节吗?另外,您可以在超级终端(或其他终端)中打开它吗?
  • @Jon B,此错误中没有内部异常,并且在超级终端中确实有效。
  • 在 Win32 API 中,DTR 由DCB 结构中的标志之一控制:msdn.microsoft.com/en-us/library/aa363436(VS.85).aspx
  • @Jeremy 你解决过这个问题吗?我知道这是不久前的事了,但我面临着 the same problem 的细微差别。
  • 我使用了一个名为 OpenNETCF.IO.Serial.dll 的第三方组件。效果很好。

标签: .net serial-port


【解决方案1】:

我的串口监听器有问题,主进程卡住了 - 因为它是同步的。进程,通过创建线程和计时器解决

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;
            }

【讨论】:

    【解决方案2】:

    看起来不同之处在于握手。

    我没有遇到串行端口类的问题,并且编写了以 800,000 位/秒运行的应用程序。

    【讨论】:

      【解决方案3】:

      看到这个forum post。我怀疑这与硬件或驱动程序故障有关。这并不能解释为什么它可以与超级终端一起使用。听从 Joseph M. Newcomer 的建议,看看 HyperTerminal 的不同之处。

      【讨论】:

      • 超级终端不一定使用 .NET 类:它使用的是 Win32 API ...并且它可能使用较少的 Win32 API,和/或具有不同的错误处理,即 .NET 类。网课'。特别是,使用 Win32 API,您可以打开一个端口并且随后无法设置其某些设置。
      • 我从 sysinternals 运行了 PortMon 软件,并将日志添加到我的问题中,我只是不知道现在哪个 win32 命令导致错误,如何解决它。有没有更好的串口类可用?
      • 我认为该论坛帖子的扩展摘要是有序的(所以这个答案是独立的 - 而不是仅链接)。
      【解决方案4】:

      在真正的UART 中,DTREnable 将断言您的 UART 的 DTR 引脚以表明您已准备好接收数据。

      根据您的驱动程序的实现,您可能需要将 DTREnable 设置为 true 以打开端口。

      【讨论】:

      • 是的,我忘了说,它是USB连接,所以它是一个虚拟串口。如果您建议的是问题,我该如何解决?串口st to DtrEnable = false
      • 这解决了我使用端口的问题,简单的 _Port.DtrEnable=true;
      【解决方案5】:

      关于超级终端和.NET串口对象的区别,超级终端是一个商业的、稳定的应用程序。如果底层串行端口对象死亡或抛出异常,超级终端会将其隐藏起来。 .NET 串行端口对象引发的异常比我使用过的任何其他 .NET 对象都多。

      要点:

      • 每当您更改设置时,请先将其关闭、更改,然后再重新打开。当您在打开时更改它时,有些端口真的很讨厌它。
      • 期望围绕您的串行端口对象,围绕您所做的每一件事进行大量“try-catch”。
      • 确保列出的每个可能的异常都有一个,并确保每个都检查消息(在不同的情况下可能会有所不同)。许多都可以通过关闭和重新打开来恢复。
      • 尝试准确跟踪异常发生的位置。看看修改你设置的顺序是否能解决问题……这个对象真的很挑剔。

      如果您在打开之前尝试将 DTR 明确设置为 false,那么您可能只需要咧嘴一笑并忍受该设备。 SerialPort 对象不是 .NET 中实现良好的库的发光示例之一。如果您注意到,超级终端会收到同样的错误,但它只是忽略它。

      如果可以,请尝试使用普通串行端口或不同品牌的 USB 设备。如果您仍然遇到相同的错误,则可能是您的应用程序方面的问题。

      【讨论】:

      • 我正在调用 Open 方法。异常被抛出在那里的某个地方。我使用了 sysinternals 的 PortMonitor,发现在后台,正在发出 IOCTL_SERIAL_CLR_DTR,它返回错误 0xC0000001 并导致 SerialPort 类关闭端口并引发异常。
      • 超级终端不会导致发出 IOCTL_SERIAL_CLR_DTR。不知道如何在 .net 框架中抑制它。
      • 很遗憾,您可能无法对此无能为力。 ://
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多