La mayoría de las implementaciones de RS485 de 2 hilos que he visto usan pines UART RX y TX que, por supuesto, funcionan. Y lo he hecho.
Pero me preguntaba si usar UART en modo semidúplex es una buena alternativa que tal vez (?) tenga el beneficio de un código más limpio y una reducción del número de pines.
La aplicación es Modbus ASCII y el tiempo es tan claro (3,5 caracteres) que el cambio (que hago para DataEnable de todos modos) podría unirse con TransmitEnable.
(Algún contexto: he tenido transmisores RS485 con eco local en la línea UART RX)
Puede ser una buena idea si se encuentra en una situación en la que necesita conservar pines.
Pero también hace que algunas cosas sean más difíciles.
Debe cambiar el pin MCU único entre los modos RX y TX para el cable UART único, además de controlar los pines de habilitación del transmisor/receptor.
También es posible que necesite un pull-up en las líneas de datos para que flote inactivo entre el cambio de dirección del pin MCU; algunos MCU tienen pull-ups internos que pueden permanecer habilitados todo el tiempo en lugar de encenderse solo cuando se ingresa.
También hace que sea imposible volver a leer lo que transmite la MCU, por lo que no es posible detectar fallas, colisiones o errores.
RS485 ya es semidúplex. Entonces, ¿por qué no introducir un poco más a la interfaz PHY?
Es una buena idea si puede encontrar un método confiable para arbitrar RX y TX en los nodos locales y el arbitraje del bus. Al volverse aún más proactivo, puede introducir una forma de detectar la contención en el bus. En el lado del software, la capa de enlace felizmente puede perder una parte importante del código.
Mientras escribo esto, de hecho se siente como una idea muy interesante; algo como Ethernet en RS485 PHY, o debe haber algo ya disponible.
Hmm... Modbus/ASCII estándar no utiliza un tiempo de espera de interrupción de cuadro de 3,5 caracteres. Ese tiempo de espera es característico de Modbus/RTU. Obviamente, si posee la implementación de todos los nodos, esto no significa mucho. Si su rutina de RX de cuadro puede detectar el final del cuadro en función del contenido del cuadro (los cuadros de longitud variable tienen la longitud codificada al principio del cuadro), probablemente ni siquiera necesite respetar los 3,5 caracteres en términos de "tiempo de giro" de RX/TX. ".
Érase una vez que escribí una biblioteca Modbus para la PC, y también sé un poco sobre el 16C550A y los UART compatibles, pero ese conocimiento se está oxidando. Y ciertamente no sé nada sobre los UART que ocurren en los MCU. Siendo mimado por el enfoque derrochador del conteo de pines en el hardware de la PC, y teniendo solo un recuerdo oxidado de la codificación alrededor del hardware UART 16C550A, no veo qué podría ahorrarme "usar el UART en modo semidúplex" en términos de tamaño o complejidad del código.
Dicho esto, si puedo sugerir algo para facilitar la operación RS485 semidúplex, sería usar un UART que pueda dirigir el RX/TX automáticamente , exportando el indicador interno llamado "Transmitter Shift Register Empty" como una señal discreta externa, que se puede conectar directamente al cambiador de nivel RS485 (transceptor).
Nota: no confunda el "registro de desplazamiento del transmisor vacío" deseado con el "registro de retención del transmisor vacío" = un indicador de estado diferente en el UART. Lo primero significa que el byte se está desplazando bit a bit en la línea. Este último se refiere al FIFO, y el indicador THRE se activa tan pronto como el FIFO está vacío, es decir, mientras el registro de desplazamiento todavía está ocupado desplazando el último byte, es decir, demasiado pronto para que el transceptor RS485 se desconecte en alto Z / escucha estado.
Algunas implementaciones de UART pueden enviar esta señal como una función alternativa de los pines RTS o DTR, otras tienen pines de salida dedicados o pueden asignar esto a algún GPIO. El 16C550A estándar solo tiene el TSRE, también conocido como TEMT, como un indicador de estado interno, pero carece de la capacidad de exportarlo en cualquier pin de salida. Es decir, el 16C550A no es una elección estelar para RS485. Como un brillante ejemplo de esta función bien hecha, me gustaría mencionar el último UART OX16C950 de Oxford Semiconductor, que hoy en día ya no se fabrica (el progreso técnico tiene su lado negativo, y hubo una serie de adquisiciones, aproximadamente OX Semi -> PLX - > Avago -> Broadcom). Si la memoria funciona, los UART modernos de EXAR también pueden hacerlo, y algunos chips LPC SuperIO también pueden admitir esto en algunos o todos los canales UART (Fintek, SMSC, tal vez algunos ITE recientes y Nuvoton nee Winbond). Yo no'
Me parece recordar algunos UART donde esta función es defectuosa, es decir, recuerdo una placa PCI adicional para la PC, con puertos RS485 y dirección HW, donde el UART cambiaría el transceptor a alta Z (RX) un poco demasiado pronto, efectivamente cortando la broca de tope. Lo que aparentemente funcionó bien contra otros UART... No recuerdo la marca del chip UART en esa placa.
También he visto un error de diseño a nivel de placa (thinko) en una PC industrial asiática, donde el modo RS485 se implementó al impulsar el pin de dirección RX/TX del transceptor por el TTL Data TX de UART, de modo que el transceptor estaba cambiando entre registro. 1 y alto Z...
Esta característica, es decir, "TSRE=TEMT para dirección RS485 RX/TX" puede ahorrarle algunos dolores de cabeza con la sincronización precisa en el software. Seguro que es un dolor de cabeza en la PC, especialmente en algunos sistemas operativos modernos... ya sea que el tiempo sea un dolor de cabeza o no en su MCU en particular, obviamente es asunto suyo, YMMV.
Marko Bursic
Tony Estuardo EE75
JeromeBu1982