Domanda

Sto provando ad aprire e leggere da una porta seriale usando la classe System.IO.Ports.SerialPort. Ho trascinato la porta seriale dal riquadro degli strumenti (VS 2008) sul mio modulo di Windows. Ho impostato una griglia di proprietà in modo da poter facilmente modificare le proprietà della porta seriale in fase di esecuzione. Quando provo ad aprire la porta, viene visualizzato l'errore mostrato di seguito. Non capisco perché, perché posso aprire e leggere dalla porta usando Hyperterminal. Qualche 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, questa è una connessione USB, quindi è una porta seriale virtuale Le mie impostazioni sono le seguenti:
BaudRate = 9600
DataBits = 8
DiscardNull = false
DtrEnable = false
Stretta di mano = Nessuno
Parità = Nessuna
ParityReplace = 63
PortName = COM3
ReadBufferSize = 4096
ReadTimeout = -1
ReceivedBytes = 1
TrsEnable = False
StopBits = One
WriteBufferSize = 2048
WriteTimeout = -1

Ho scaricato PortMon da sysinternals. Ho acquisito 2 registri, il primo è il registro di ciò che accade quando Hyperterminal apre la porta, il secondo è ciò che accade quando la classe .net SerialPort tenta di aprire la porta:

Hyperterminal:

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 
È stato utile?

Soluzione

Per quanto riguarda le differenze tra hyperterminal e l'oggetto della porta seriale .NET, Hyperterminal è un'app commerciale stabile. Se l'oggetto della porta seriale sottostante è morto o ha generato un'eccezione, Hyperterminal lo ha nascosto. L'oggetto porta seriale .NET genera più eccezioni rispetto a qualsiasi altro oggetto .NET che ho usato.

Punti da sottolineare:

  • Ogni volta che modifichi un'impostazione, chiudila prima, modificala, quindi riaprila. Alcune porte lo odiano davvero quando lo cambi mentre è aperto.
  • Aspettatevi di fare un sacco di 'try-catch' attorno al vostro oggetto porta seriale, in ogni cosa che fate.
  • Assicurati di averne uno per ogni possibile eccezione elencata e assicurati che ognuno controlli il messaggio (può essere diverso in circostanze diverse). Molti sono recuperabili semplicemente chiudendo e riaprendo.
  • Prova a seguire esattamente dove vengono generate le eccezioni. Vedi se la modifica dell'ordine che imposti le cose lo risolve ... l'oggetto è davvero schizzinoso.

Se hai provato a impostare esplicitamente il DTR su false prima dell'apertura, potresti semplicemente sorridere e scoprirlo con quel dispositivo. L'oggetto SerialPort non è uno dei brillanti esempi di una libreria ben implementata in .NET. Se noti, l'iperterminale ottiene lo stesso errore, ma lo ignora.

Se puoi, provalo con una normale porta seriale o un dispositivo USB di marca diversa. Se ricevi ancora lo stesso errore, potrebbe trattarsi di qualcosa sul lato della tua app.

Altri suggerimenti

In realtà UART, DTREnable affermerà il DTR pin del tuo true per indicare che sei pronto a ricevere dati.

A seconda dell'implementazione del driver, potrebbe essere necessario impostare <=> su <=> per aprire la porta.

Vedi questo post sul forum . Ho il sospetto che abbia a che fare con l'hardware o il malfunzionamento del driver. Questo non spiega perché funzioni con Hyperterminal. Segui i consigli di Joseph M. Newcomer per vedere cosa sta facendo Hyperterminal in modo diverso.

sembra che la differenza sia la stretta di mano.

Non ho avuto problemi con la classe serialport e ho scritto app che funzionavano a 800.000 bps.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top