problema de sincronización AVR UART

0

Estoy aprendiendo programación integrada (no soy ingeniero eléctrico). Lo siento si este no es el lugar correcto o estoy haciendo esta pregunta incorrectamente, pero me fue muy difícil tratar de encontrar una solución. Estoy usando un ATMega32 con un módulo GPS y un LCD de 16x2. Solo quiero leer una oración NMEA sobre UART y enviar los datos analizados a la pantalla LCD. Leí la oración en un búfer y luego la escupí en la pantalla. Pero a veces obtengo datos inconsistentes ... El GPS está siempre encendido y el AVR se enciende en el medio y espera el inicio de una oración y luego continúa recibiendo.

Mi pregunta es: ¿cómo se pueden sincronizar dos dispositivos si uno está siempre enviando (el GPS envía datos a una velocidad de 1 Hz) y el otro recibe en forma aleatoria? ¿Cómo se logra la sincronización UART? Sé de los bits de inicio y detención, pero una vez que UART recibe un paquete defectuoso (por ejemplo, genera un error de trama), ¿cómo puede recuperarse y sincronizarse?

explique también qué sucede a nivel de hardware o, si puede, indíqueme un recurso en línea, no puedo encontrar lo que estoy buscando.

¡Muchas gracias!

Luca

    
pregunta Luca

4 respuestas

6

Su intuición es correcta: el hardware de UART no tiene ninguna sincronización más allá del nivel de byte. (Se sincroniza en el nivel de byte para usted, a través de un bit de inicio especial como se explica aquí )

Para sincronizar "paquetes" más largos que un byte, la mayoría de los protocolos de comunicación serie de alto nivel tienen un "preámbulo" especial de bytes que se garantiza que no aparecerá en el mensaje. Luego hay varias estrategias para señalar el final de un paquete: algunos protocolos indican el final del mensaje con una secuencia especial de "parada" de bytes que no puede aparecer en el mensaje. Otros utilizan un encabezado de mensaje de longitud fija que indica la longitud precisa del mensaje.

No he usado el protocolo NMEA personalmente, pero basado en esta guía parece al igual que usan '$' como un carácter especial que señala el inicio de un paquete. No está permitido aparecer dentro del paquete.

Entonces, para recibir estos datos en su programa, creo que necesita hacer algo como esto:

  1. Ignora todos los bytes hasta que veas un '$'
  2. Luego, registre cada byte en una matriz, comenzando desde la posición 0. (Asegúrese de que su matriz sea lo suficientemente larga como para contener el mensaje válido más largo posible. Si los datos exceden la longitud de su matriz, vuelva al paso 1).
  3. Deténgase cuando vea 'CR' seguido de 'LF' (esto parece indicar el final del paquete NMEA)
  4. Calcule la suma de comprobación y verifique que coincida con la suma de comprobación transmitida. Si no, vuelve al paso 1.
  5. Usa los datos de tu matriz
  6. Vuelve al paso 1.

Esta discusión tiene muchos buenos enlaces: enlace

    
respondido por el Luke
1

Si observa el formato de un mensaje NMEA, tiene un carácter de inicio definido ($) y uno o más caracteres de finalización CR + LF. Me gusta esto de Wikipedia:

  

$ GPAAM, A, A, 0.10, N, WPTNME * 32

Su software necesita buscar el carácter $ y guardar todos los siguientes caracteres en un búfer hasta que reciba CR + LF. Luego puede verificar si el mensaje es válido calculando la suma de comprobación y comparándolo con la suma de comprobación en el mensaje (el * 32 es la suma de comprobación en el ejemplo). Solo si las sumas de comprobación coinciden, el mensaje debe enviarse a la pantalla LCD.

    
respondido por el Steve G
0

En realidad, hay dos preguntas involucradas en tu publicación:

1) ¿Cómo se logra la sincronización? No lo es. El único factor común que los dos dispositivos tienen en común es el tiempo. Esto es lo que especifica el Baudrate; Especifique una velocidad en baudios diferente para los dos dispositivos y recibirá basura. La mayoría de los UART de hardware (y espero que esté utilizando el hardware dedicado en su controlador) proporciona decodificación de los bits de Inicio / Parada, así como los datos reales. Así que aquí estamos hablando de un solo byte (una sola letra ASCII en este caso). El GPS enviará un bit de inicio, los datos y un bit de parada. Esta es una verificación de datos muy simple y poco confiable, pero es la única que realmente tendrá para una transmisión UART. Para ser honesto, si ha definido correctamente la configuración, esto funcionará en todo momento. Me han transferido Megabytes para realizar pruebas sin siquiera un solo error de bit en 115200.

2) Usted declara que a veces recibe basura. Para mí, esto puede tener dos razones: o bien sus bytes ya están dañados (debería ver algunos errores en los registros de errores UART de los microcontroladores en ese caso) o comienza a perder caracteres porque su programa principal no puede recibirlos tan rápidamente. Necesitaríamos una descripción más detallada de lo que realmente obtienes. Dado que normalmente esos módulos GPS están bastante bien probados, supongo que el problema está de su lado. Después de cada carácter recibido, asegúrese de verificar el registro de errores de los controladores para detectar posibles problemas. Otro método para verificar su velocidad en baudios sería conectar un alcance a su línea de transmisión y verificar si los tiempos de bits coinciden con lo que ha configurado. ¿Puedes describir tu escenario un poco mejor? ¿Qué controlador usa? ¿Utiliza un cristal externo? ¿A qué velocidad ejecuta el controlador? ¿Cuál es su configuración para los registros UART? ¿Ve algún error durante las transferencias?

    
respondido por el Tom L.
0
  

¿Cómo se logra la sincronización UART? Sé de los bits de inicio y detención, pero una vez que UART recibe un paquete incorrecto (por ejemplo, genera un error de trama), ¿cómo puede recuperarse y sincronizarse?

Se puede lograr una sincronización confiable dejando un "tiempo muerto" de al menos un período de caracteres entre las transmisiones. Si un UART receptor comienza (o se vuelve) desincronizado del transmisor, volverá a sincronizarse cuando la transmisión se detenga y comience nuevamente.

(En el contexto de NMEA, esto debería suceder naturalmente, ya que la velocidad de la línea serie debería ser lo suficientemente alta para que el enlace serie no esté siempre activo. Si no lo está, su enlace serie está completamente saturado, y algunos mensajes probablemente sean estar perdido!)

Un método menos confiable, pero aún efectivo, de obtener una sincronización confiable es usar 1.5 o 2 bits de parada para el enlace serial. Es probable que una UART receptora que se desincronice comience a leer espacios dentro de la transmisión como bits de parada individuales, y eventualmente debería "desviarse" nuevamente a la sincronización adecuada con los bits de parada extendidos.

    
respondido por el duskwuff

Lea otras preguntas en las etiquetas