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。我已经捕获了两个日志。第一个是超级终端打开端口时发生的情况的日志,第二个是 .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

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

要点:

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

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

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

于 2009-01-30T22:44:28.690 回答
1

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

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

于 2009-01-30T17:41:43.230 回答
0

请参阅此论坛帖子。我怀疑这与硬件或驱动程序故障有关。这并不能解释为什么它可以与超级终端一起使用。遵循 Joseph M. Newcomer 的建议,了解 HyperTerminal 的不同之处。

于 2009-01-30T19:36:10.630 回答
0

看起来不同的是握手。

我没有遇到串行端口类的问题,并且编写了以 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 回答