4 votos

Software Arduino serie - full duplex

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

Las librerías Arduino incluidas proporcionan una librería SoftwareSerial que he descubierto que es sólo medio dúplex - durante la rutina de envío, las interrupciones están deshabilitadas, lo que por supuesto significa que la rutina de recepción impulsada por las interrupciones está apagada.

Antes de implementar mi propia biblioteca full-duplex, quería saber si otros han encontrado una solución sencilla para esto, o si hay bibliotecas por ahí que lo implementen correctamente.

3voto

Alex Andronov Puntos 178

No he utilizado el Arduino, pero he escrito UARTs suaves y eficientes en un buen número de plataformas. El mejor enfoque en una plataforma determinada dependerá de los tipos de operaciones de manipulación de bits que pueda realizar de forma más eficiente. Sin embargo, yo ofrecería algunas sugerencias:

  1. Asigne la máxima prioridad al ISR de sondeo en serie y ejecútelo preferentemente al triple de la velocidad de datos deseada. Muestrea todas las entradas y escribe todas las salidas al comienzo de esta rutina de interrupción, y luego calcula cuáles deben ser las salidas para la siguiente pasada. Esto ayudará a minimizar cualquier desviación de tiempo que podría ser causada por el tiempo de procesamiento de interrupción variable.
  2. Para el receptor, en lugar de utilizar una máquina de estado como tal, puede ser útil desplazar efectivamente los datos entrantes en un gran registro de desplazamiento. Si el patrón de bits indica que se ha recibido un byte, coge los datos y borra los bytes correspondientes. ... 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 aunque 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 a otra palabra de memoria y hacer la migración de bits en una interrupción posterior. Dado que la transmisión en serie sólo necesitará hacer algo cada tres interrupciones, la eliminación de bits podría hacerse en las interrupciones en las que la rutina de transmisión en serie no se ejecuta.

3voto

Mark Biek Puntos 41769

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

1voto

tenfour Puntos 118

Dice que no se puede cambiar el hardware existente, ¿se puede añadir? Si ambas líneas seriales no necesitan estar activas al mismo tiempo, entonces podrías usar un multiplexor o un conmutador analógico en las líneas UART y conmutar hacia adelante y hacia atrás entre los dos dispositivos que necesitan ser atendidos. Sólo tendrás que asegurarte de que cuando conmutes el nivel de tu pin TX permanezca alto cuando se aleje de la UART (para evitar una falsa condición START).

0voto

JW. Puntos 145

No uses SoftSerial, al menos usa NewSoftSerial... Creo que es un verdadero desafío (tal vez incluso imposible) lograr una comunicación UART multicanal full-duplex sin dos UARTs de hardware... con NewSoftSerial, creo que el sacrificio que haces es que sólo puedes "usar" un canal a la vez. Creo que si se pudiera hacer con Arduino ya se habría hecho.

Ver debate aquí sobre el uso de múltiples instancias de NewSoftSerial.

0voto

Craig Hyatt Puntos 158

¿Permitirá el cliente utilizar un Arduino Mega que tiene 4 puertos serie de hardware?

http://www.arduino.cc/en/Main/ArduinoBoardMega

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X