Pregunta

Escribí una aplicación simple en C# 2.0 usando la clase .Net Framework 2.0 Serialport para comunicarme con una tarjeta controladora a través de COM1.

Recientemente ocurrió un problema donde los bytes devueltos por el método de lectura son incorrectos.Devolvió la cantidad correcta de bytes, sólo los valores eran incorrectos.Sin embargo, una aplicación similar escrita en Delphi aún devolvió los valores correctos.

solía Portmón Para registrar la actividad en el puerto serie de ambas aplicaciones, comparé los dos registros y hubo algunas configuraciones (aparentemente) diferentes menores e intenté imitar la aplicación Delphi lo más fielmente posible, pero fue en vano.

Entonces, ¿qué podría afectar los valores de bytes devueltos por el método de lectura?

La mayoría de las configuraciones entre las dos aplicaciones son idénticas.

Aquí hay una lista de las líneas que diferían en el registro de Portmon:

Aplicación Delphi:

IOCTL_SERIAL_SET_CHAR Serie0 ÉXITO EOF: CCERR:0 BRK:0 EVT:0 XON:11 XOFF:13
Ioctl_serial_set_handflow serial0 éxito batido: 0 reemplazar: 0 Límite de Xon: 256 LímiteXoff:256 IOCTL_SERIAL_SET_TIMEOUTS Serie0 ÉXITO RI:-1 RM: 100 CR:1000 MM: 100 WC:1000 IOCTL_SERIAL_SET_WAIT_MASK Máscara de ÉXITO Serie0:RXCHAR RXFLAG VACÍO CTS DSR RLSD BRK ERR RING RX80COMPLETO

Aplicación C#:

IOCTL_SERIAL_SET_CHAR Serie0 ÉXITO EOF:1aERR:0 BRK:0 TVE:1a Xon: 11 xoff: 13 ioctl_serial_set_handflow serial0 éxito batido: 0 reemplazar: 0 Límite de Xon: 1024 LímiteXoff:1024 IOCTL_SERIAL_SET_TIMEOUTS Serie0 ÉXITO RI:-1 RM:-1 CR:1000 WM:0 WC:1000 IOCTL_SERIAL_SET_WAIT_MASK Máscara de ÉXITO Serie0:Rxchar rxflag cts dsr rlsd brk err ring

ACTUALIZAR:

Los bytes devueltos correctos fueron:91, 1, 1, 3, 48, 48, 50, 69, 66, 51, 70, 55, 52, 93 (14 bytes).El último valor es una simple suma de comprobación.

Los valores incorrectos devueltos fueron:91, 241, 254, 252, 242, 146, 42, 201, 51, 70, 55, 52, 93 (13 bytes).

Como puede ver, el primero y los últimos cinco bytes devueltos corresponden.

El evento ErrorReceived indica que se produjo un error de encuadre, lo que podría explicar los valores incorrectos.Pero la pregunta es ¿por qué SerialPort encontraría un error de encuadre cuando la aplicación Delphi aparentemente no lo hace?

¿Fue útil?

Solución

Bueno, parece que el problema se ha solucionado (al menos de momento).

Aparentemente, un error de encuadre provocó la devolución de valores incorrectos.Escribí una aplicación VB6 usando el control MSComm, que funcionó bien, y comparé los archivos de registro generados por Portmon.

Recogí las siguientes diferencias

Aplicación VB6:

Ioctl_serial_set_handflow serial0 éxito Agitar:1 Reemplazar: 0 xonlimit: 256 xofflimit: 256

Aplicación C#:

Ioctl_serial_set_handflow serial0 éxito Agitar:0 Reemplazar: 0 xonlimit: 1024 xofflimit: 1024

Jugando con la configuración descubrí que si configuro_serialPort.DtrEnable = truela aplicación C# genera la siguiente entrada de registro:

Ioctl_serial_set_handflow serial0 éxito Agitar:1 Reemplazar: 0 xonlimit: 1024 xofflimit: 1024

Eso pareció evitar el error de encuadre y la aplicación parece funcionar bien.

Otros consejos

¿Ha verificado la configuración de número de bits de datos, bits de parada y paridad?

El bit de paridad es una especie de mecanismo de detección de errores.Por ejemplo:Si envía utilizando 7 bits de datos y un bit de paridad, el octavo bit se utilizará para detectar errores de inversión de bits.Si el receptor espera 8 bits de datos y ningún bit de paridad, el resultado será confuso.

Desafortunadamente, no mencionaste exactamente qué tipo de diferencias obtienes.¿Es un carácter ocasional que es diferente o todos los datos entrantes están confusos?Tenga en cuenta que los caracteres leídos a través de la función SerialPort.Read podrían ser cambiados por el sistema debido a la configuración del SerialPort.Codificación propiedad.Esta configuración afecta la interpretación del texto entrante como si fuera texto en ASCII, Unicode, UTF8 o cualquier otro esquema de codificación que Windows use para la conversión de 'byte(s) sin formato' a 'texto legible'.

Si está leyendo en una matriz de bytes (por ejemplo:SerialPort.Read) deberías obtener exactamente los bytes que estás viendo en PortMon.

Si está convirtiendo a caracteres (SerialPort.ReadLine o SerialPort.ReadChar), los datos se codificarán utilizando la codificación actual (propiedad SerialPort.Encoding), lo que explica las diferencias que está viendo.

Si desea ver caracteres con los mismos valores binarios que los bytes en el cable, una buena codificación es Latin-1 como se describe en esta publicación.

Ejemplo:

SerialPort.Encoding = Encoding.GetEncoding("Latin1")
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top