Pregunta

Estoy intentando abrir y leer desde un puerto serie usando la clase System.IO.Ports.SerialPort. Arrastré el puerto serie desde el panel de herramientas (VS 2008) a mi formulario de Windows. Tengo una red de propiedades configurada para poder cambiar fácilmente las propiedades del puerto serie en tiempo de ejecución. Cuando intento abrir el puerto, aparece el error que se muestra a continuación. No entiendo por qué porque puedo abrir y leer desde el puerto usando Hyperterminal. ¿Alguna idea?

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

Nota, esta es una conexión USB, por lo que en realidad es un puerto serie virtual Mi configuración es la siguiente:
BaudRate = 9600
DataBits = 8
DiscardNull = false
DtrEnable = false
Apretón de manos = Ninguno
Paridad = Ninguna
ParityReplace = 63
PortName = COM3
ReadBufferSize = 4096
ReadTimeout = -1
ReceivedBytes = 1
TrsEnable = Falso
StopBits = Uno
WriteBufferSize = 2048
WriteTimeout = -1

Descargué PortMon de sysinternals. Capturé 2 registros, el primero es el registro de cómo sucede cuando Hyperterminal abre el puerto, el segundo es lo que sucede cuando la clase .net SerialPort intenta abrir el puerto:

Hiperterminal:

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 SerialPort:

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 
¿Fue útil?

Solución

Con respecto a las diferencias entre hyperterminal y el objeto de puerto serie .NET, Hyperterminal es una aplicación comercial y estable. Si el objeto del puerto serie subyacente murió o arrojó una excepción, Hyperterminal se lo ocultó. El objeto de puerto serie .NET arroja más excepciones que cualquier otro objeto .NET que haya usado.

Puntos para hacer:

  • Siempre que cambie una configuración, ciérrela primero, cámbiela y luego vuelva a abrirla. Algunos puertos realmente lo odian cuando lo cambias mientras estás abierto.
  • Espere hacer muchos 'try-catch' alrededor de su objeto de puerto serie, alrededor de cada cosa que haga.
  • Asegúrese de tener uno para cada posible excepción enumerada, y asegúrese de que cada uno verifique el mensaje (puede ser diferente en diferentes circunstancias). Muchos son recuperables simplemente cerrando y volviendo a abrir.
  • Intenta seguir exactamente dónde se lanzan las excepciones. Vea si modifica el orden en que establece las cosas, lo arregla ... el objeto es realmente delicado.

Si ha intentado establecer explícitamente DTR en falso antes de abrir, entonces es posible que solo tenga que sonreír y mostrarlo con ese dispositivo. El objeto SerialPort no es uno de los ejemplos brillantes de una biblioteca bien implementada en .NET. Si observa, el hiperterminal obtiene el mismo error, pero simplemente lo ignora.

Si puede, pruébelo con un puerto serie normal o con un dispositivo USB de otra marca. Si aún recibe el mismo error, podría ser algo en el lado de su aplicación.

Otros consejos

En UART real, DTREnable afirmará el DTR pin de su true para indicar que está listo para recibir datos.

Dependiendo de la implementación de su controlador, es posible que necesite configurar <=> en <=> para abrir el puerto.

Consulte esta publicación en el foro . Sospecho que tiene que ver con el hardware o el mal funcionamiento del controlador. Sin embargo, esto no explica por qué funciona con Hyperterminal. Siga los consejos de Joseph M. Newcomer para ver qué hace Hyperterminal de manera diferente.

parece que la diferencia es el apretón de manos.

No he tenido problemas con la clase de puerto serie y he escrito aplicaciones que se ejecutan a 800,000 bps.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top