Ошибка открытия последовательного порта
-
20-08-2019 - |
Вопрос
Я пытаюсь открыть последовательный порт и прочитать его, используя класс System.IO.Ports.SerialPort.Я перетащил последовательный порт с панели инструментов (VS 2008) в форму Windows.У меня настроена сетка свойств, поэтому я могу легко изменять свойства последовательного порта во время выполнения.Когда я пытаюсь открыть порт, я получаю ошибку, показанную ниже.Я не понимаю, почему, потому что я могу открывать и читать порт с помощью Hyperterminal.Есть идеи?
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 = ложь
Дтренабле = ложь
Рукопожатие = Нет
Паритет = Нет
ЧетностьЗаменить = 63
Имя порта = COM3
Чтениебуферсизе = 4096
Время чтения = -1
Полученные байты = 1
Трсенабле = ложь
Стопбиты = Один
WriteBufferSize = 2048
WriteTimeout = -1
Я скачал PortMon с sysinternals.Я записал 2 журнала: первый — это журнал того, что происходит, когда 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
Решение
Что касается различий между Hyperterminal и объектом последовательного порта .NET, Hyperterminal — это коммерческое стабильное приложение.Если базовый объект последовательного порта умер или выдал исключение, Hyperterminal скрыл его от вас.Объект последовательного порта .NET выдает больше исключений, чем любой другой объект .NET, который я использовал.
Что следует отметить:
- Всякий раз, когда вы меняете настройку, сначала закройте ее, измените, а затем снова откройте.Некоторые порты действительно ненавидят, когда вы меняете их, пока они открыты.
- Ожидайте, что вам придется делать много попыток вокруг вашего объекта последовательного порта, вокруг всего, что вы делаете.
- Убедитесь, что у вас есть по одному для каждого из перечисленных исключений, и убедитесь, что каждое из них проверяет сообщение (оно может быть разным в разных обстоятельствах).Многие из них можно восстановить, просто закрыв и снова открыв.
- Попробуйте точно проследить, где возникают исключения.Посмотрите, исправит ли это изменение порядка, который вы установили...объект действительно привередливый.
Если вы попытались явно установить для DTR значение false перед открытием, вам, возможно, придется просто ухмыльнуться и обнажить его с помощью этого устройства.Объект SerialPort не является одним из ярких примеров хорошо реализованной библиотеки в .NET.Если вы заметили, гипертерминал получает ту же ошибку, но просто игнорирует ее.
Если можете, попробуйте использовать обычный последовательный порт или USB-устройство другой марки.Если вы по-прежнему получаете ту же ошибку, возможно, проблема в вашем приложении.
Другие советы
В действительности UART
, DTREnable
будет утверждать DTR
булавка твоего UART
чтобы указать, что вы готовы получать данные.
В зависимости от реализации вашего драйвера вам может потребоваться установить DTREnable
к true
чтобы открыть порт.
Видеть это сообщение на форуме.Я подозреваю, что это связано с неисправностью оборудования или драйвера.Однако это не объясняет, почему это работает с Hyperterminal.Следуйте советам Джозефа М.Новичок, который увидит, что Hyperterminal делает по-другому.
похоже, что разница в рукопожатии.
у меня не было проблем с классом последовательного порта, и я написал приложения, работающие со скоростью 800 000 бит/с.