serie del software Arduino - dúplex completo

4

Necesito dos puertos seriales para este proyecto Atmega328 Arduino, pero este procesador solo tiene un UART de hardware. El procesador, el diseño de hardware y el entorno de programación ya están configurados, y no puedo cambiar el hardware o el procesador, por lo que se requiere una solución de software.

Las bibliotecas de Arduino incluidas proporcionan una biblioteca de SoftwareSerial que descubrí que es solo semidúplex: durante la rutina de envío, las interrupciones están desactivadas, lo que por supuesto significa que la rutina de recepción dirigida por interrupciones se apaga.

Antes de implementar mi propia biblioteca de dúplex completo, quería saber si otros han encontrado una solución simple para esto, o si hay bibliotecas que lo implementan correctamente.

    
pregunta Adam Davis

5 respuestas

1

No he usado el Arduino, pero he escrito UARTs eficientes en varias plataformas. El mejor enfoque en una plataforma dada dependerá de los tipos de operaciones de intercambio de bits que pueda realizar de manera más eficiente. Sin embargo, ofrecería algunas sugerencias:

  1. Asigne la máxima prioridad al ISR de sondeo en serie y ejecútelo preferiblemente a 3 veces la velocidad de datos deseada. Pruebe todas sus entradas y escriba todas sus salidas al comienzo de esta rutina de interrupción, y luego averigüe cuáles deberían ser las salidas para la próxima pasada. Esto ayudará a minimizar cualquier sesgo de tiempo que de otra manera podría ser causado por el tiempo variable de procesamiento de interrupción.
  2. Para el receptor, en lugar de usar una máquina de estados como tal, puede ser útil cambiar efectivamente los datos entrantes a un gran registro de cambios. Si el patrón de bits indica que se recibió un byte, tome los datos y borre los bytes apropiados.
      ... near start of interrupt (for consistent timing)
      shiftreg >>= 1;
      if (IN_PORT)
        shiftreg |= 0x20000000;
      ... other interrupt logic, then...
      if ((shiftreg & 0x20000007) == 0x20000001)
      {
        int result = 0;
        if (shiftreg & 0000000040) result |= 1;  // Note: constants are OCTAL!
        if (shiftreg & 0000000400) result |= 2;
        if (shiftreg & 0000004000) result |= 4;
        if (shiftreg & 0000040000) result |= 8;
        if (shiftreg & 0000400000) result |= 16;
        if (shiftreg & 0004000000) result |= 32;
        if (shiftreg & 0040000000) result |= 64;
        if (shiftreg & 0400000000) result |= 128;
        // Do something appropriate with result, then...
        shiftreg |= 0x3FFFFFFFF;
      }
      else if (shiftreg = 1)
      {
        ... Do something with long-break (will be detected exactly once)
      }
    

Tenga en cuenta que si bien el tiempo en el peor de los casos puede ser significativo, el tiempo en el caso normal será bastante rápido. Además, cuando se detecta un byte entrante, uno podría copiarlo en otra palabra de la memoria y hacer el munging de bits en una interrupción posterior. Dado que la transmisión en serie solo tendrá que hacer algo cada tres interrupciones, la combinación de bits se puede realizar en interrupciones donde no se ejecuta la rutina de transmisión en serie.

    
respondido por el supercat
1

Usted dice que no puede cambiar el hardware existente, ¿puede agregar? Si ambas líneas seriales no necesitan estar activas al mismo tiempo, entonces puede usar un multiplexor o un interruptor analógico en las líneas UART y alternar entre los dos dispositivos que necesitan ser atendidos. Solo tendrás que asegurarte de que cuando cambies el nivel de tu pin de TX se mantenga alto cuando se aleje del UART (para evitar una condición de START falso).

    
respondido por el AngryEE
0

Cuando necesitaba un segundo UART de hardware en un AVR, usé un dispositivo MAX3100. Tiene una interfaz SPI y es muy fácil de usar. Son bastante caros, pero ahorran mucho trabajo.

    
respondido por el Leon Heller
0

¿El cliente le permitirá usar un Arduino Mega que tiene 4 puertos seriales de hardware?

enlace

    
respondido por el JonnyBoats
0

No use SoftSerial, al menos use NewSoftSerial ... Creo que es una tarea realmente difícil (tal vez incluso imposible) el llevar a cabo la comunicación UART de dúplex completo de canales múltiples sin dos UART de hardware ... con NewSoftSerial, I piensa que el sacrificio que haces es que solo puedes "usar" un canal a la vez. Creo que si se pudiera hacer con Arduino, ya se habría hecho.

Consulte la discusión aquí sobre el uso de varias instancias de NewSoftSerial.

    
respondido por el vicatcu

Lea otras preguntas en las etiquetas