Está en la página 1de 7

La UART del ESP32

Visión General:
Las aplicaciones integradas a menudo requieren un método simple de
intercambio de datos entre dispositivos que necesitan un mínimo recursos
del sistema. El receptor/transmisor asincrónico universal (UART) es uno de
esos estándares que pueden realizar un intercambio flexible de datos full-
duplex entre diferentes dispositivos. Los tres controladores UART
disponibles en el chips son compatibles con dispositivos UART de varios
fabricantes. La UART también puede realizar un IrDA (Intercambio de datos
por infrarrojos), o funcionar como un módem RS-485.
Todos los controladores UART integrados en el ESP32 cuentan con un
conjunto idéntico de registros para facilitar la programación y
flexibilidad. Aquí, estos controladores se denominan UARTn, donde n = 0, 1
y 2, en referencia a UART0, UART1 y UART2, respectivamente.

Características:
Los módulos UART tienen las siguientes características principales:
• velocidad de transmisión programable
• 1024 × 8 bits de RAM compartidos por tres FIFO de transmisión UART y
FIFO de recepción
• Admite autocomprobación de velocidad de transmisión de entrada
• Admite 5/6/7/8 bits de longitud de datos
• Soporta 1 / 1.5 / 2/3 bits STOP
• Soporta bit de paridad
• Compatible con el protocolo RS485
• Compatible con el protocolo IrDA
• Admite DMA para comunicar datos a alta velocidad
• Soporta despertar por UART
• Admite control de flujo de software y hardware

La siguiente descripción general describe cómo establecer la comunicación


entre un ESP32 y otros dispositivos UART:

La UART es un enlace de datos orientado a caracteres que se puede utilizar


para lograr la comunicación entre dos dispositivos. Los modo de
transmisión asíncrono significa que no es necesario agregar información de
reloj a los datos enviados. Esto, a su vez, requiere que la velocidad de
datos, los bits de PARADA, la paridad, etc., sean idénticos en la
transmisión y recepción fundamental para que los dispositivos se
comuniquen con éxito.
Una trama UART típica comienza con un bit de INICIO, seguido de un
"carácter" y un bit de paridad opcional para detección de error, y termina
con una condición de PARADA. Los controladores UART disponibles en el
ESP32 proporcionan soporte de hardware para múltiples longitudes de datos
y bits de STOP. Además, los controladores admiten control de flujo de
software y hardware, así como DMA, para una transferencia de datos de alta
velocidad sin interrupciones. Esto permite al desarrollador emplear
múltiples puertos UART en el sistema con una sobrecarga mínima de software.

1
FIGURA 1
La Figura 1 muestra el diagrama de bloques básico del controlador UART. El
bloque UART puede derivar su reloj de dos fuentes: el APB_CLK de 80 MHz, o
el reloj de referencia REF_TICK. Estas dos fuentes de reloj se pueden
seleccionar configurando UART_TICK_REF_ALWAYS_ON.
Luego, un divisor, divide la fuente del reloj seleccionado para generar
señales de reloj que impulsan la UART. UART_CLKDIV_REG contiene el valor
del divisor de reloj en dos partes: UART_CLKDIV (parte integral) y
UART_CLKDIV_FRAG (parte decimal).
El controlador UART se puede dividir en dos bloques funcionales: el bloque
de transmisión y el bloque recetor.
El bloque de transmisión contiene un búfer de transmisión FIFO, que
almacena los datos en espera de ser transmitidos. El software puede
escribir Tx_FIFO a través de APB y transmitir datos a Tx_FIFO a través de
DMA. Tx_FIFO_Ctrl se usa para controlar la lectura y acceso de escritura a
la Tx_FIFO. Cuando Tx_FIFO no es cero, Tx_FSM lee datos a través de
Tx_FIFO_Ctrl y transmite datos de acuerdo con el formato establecido. El
flujo de bits saliente se puede invertir configurando adecuadamente el
regístrate UART_TXD_INV.
El bloque de recepción contiene un búfer de recepción FIFO, que almacena
los datos entrantes en espera de ser procesados.
El flujo de bits de entrada, rxd_in, alimenta al controlador UART. La
negación del flujo de entrada puede controlarse mediante la configuracion
del registro UART_RXD_INV. Baudrate_Detect mide la velocidad en baudios de
la señal de entrada midiendo el ancho de pulso mínimo del flujo de bits de
entrada. Start_Detect se usa para detectar un bit de INICIO en la entrada
de datos. Después de detectar el bit START, RX_FSM almacena los datos
recuperados de la trama recibida en Rx_FIFO a través de Rx_FIFO_Ctrl.
El software puede leer datos en el Rx_FIFO a través del APB. Para liberar
a la CPU de las operaciones de transferencia de datos, el DMA se puede
configurar para enviar o recibir datos.
2
HW_Flow_Ctrl puede controlar el flujo de datos de rxd_in y txd_out através
de RTS y CTS que generan las señales de control (rtsn_out y ctsn_in).
SW_Flow_Ctrl controla el flujo de datos insertando caracteres especiales
en el flujo de datos entrantes y salientes. Cuando UART está en modo sleep
simple (consulte el capítulo Bajo consumo de energía). Wakeup_Ctrl
comenzará a contar pulsos en rxd_in. Cuando el número o los bordes
positivos de la señal RxD sea mayor o igual que (UART_ACTIVE_THRESHOLD +
2), se generará una señal de activación y se enviará al RTC.
RTC luego activará el controlador UART. Tenga en cuenta que solo UART1 y
UART2 admiten el modo sleep simple, y que rxd_in no se puede ingresar a
través de GPIO Matrix sino solo a través de IO_MUX.

La RAM para UART


Tres controladores UART comparten un espacio RAM de 1024 × 8 bits. Como se
ilustra en la Figura 2, la RAM se asigna en diferentes bloques: Un bloque
contiene datos de 128 × 8 bits. La Figura ilustra la RAM predeterminada
asignada a Tx_FIFO y Rx_FIFO de los tres controladores UART. Tx_FIFO de
UARTn se puede extender configurando UARTn_TX_SIZE, mientras Rx_FIFO de
UARTn se puede extender configurando UARTn_RX_SIZE.

AVISO: extender el espacio FIFO de un controlador UART puede ocupar el


espacio FIFO de otro UART controlador. Si ninguno de los controladores
UART está activo, la configuración de UART_MEM_PD, UART1_MEM_PD y
UART2_MEM_PD puede solicitar a la RAM que ingrese al modo de bajo consumo.
En UART0, el bit UART_TXFIFO_RST y el bit UART_RXFIFO_RST se pueden
configurar para resetear Tx_FIFO o Rx_FIFO, respectivamente. En UART1, el
bit UART1_TXFIFO_RST y el bit UART1_RXFIFO_RST se pueden configurar para
restear Tx_FIFO o Rx_FIFO, respectivamente.
Nota:
UART2 no tiene ningún registro para restablecer Tx_FIFO o Rx_FIFO, y
UART1_TXFIFO_RST y UART1_RXFIFO_RST en UART1 puede afectar el
funcionamiento de UART2. Por lo tanto, estos 2 registros en UART1 solo
deben usarse cuando el Tx_FIFO y Rx_FIFO en UART2 no tienen ningún dato.

FIGURA 2

3
Deteccion de BAUD RATE
Configurar UART_AUTOBAUD_EN para un controlador UART habilitará la función
de detección de velocidad de transmisión. El bloque Baudrate_Detect que se
muestra en la Figura 1 puede filtrar fallas con un ancho de pulso inferior
a UART_GLITCH_FILT.
Para utilizar la función de detección de velocidad de transmisión, se
deben enviar algunos datos aleatorios al receptor antes de comenzar la
comunicación con UART. Esto es necesario para que la velocidad en baudios
se pueda determinar en función del ancho del pulso. UART_LOWPULSE_MIN_CNT
almacena el ancho mínimo de pulso cuando esta en estado lógico bajo,
UART_HIGHPULSE_MIN_CNT almacena el ancho mínimo de pulso en estado lógico
alto. Al leer estos dos registros, el software puede calcular la velocidad
en baudios del transmisor.

Data Frame de la UART


La Figura 3 muestra la estructura básica del FRAME de datos. Un FRAME de
datos comienza con una condición de INICIO y termina con una condición de
PARADA. La condición de INICIO requiere 1 bit y la condición de PARADA
puede realizarse utilizando 1 / 1.5 / 2/3-bit de ancho (según lo
establecido por UART_STOP_BIT_NUM, UART_DL1_EN y UAR_DL0_EN). El INICIO es
de bajo nivel, mientras que el STOP es de alto nivel.

FIGURA 3
La longitud de un carácter (BIT0 a BITn) puede comprender de 5 a 8 bits y
puede configurarse mediante UART_BIT_NUM.
Cuando se establece UART_PARITY_EN, el hardware del controlador UART
agregará el bit de paridad apropiado después de los datos.
UART_PARITY se usa para seleccionar paridad impar o paridad par. Si el
receptor detecta un error en el carácter de entrada, se generará una
interrupción UART_PARITY_ERR_INT. Si el receptor detecta un error en el
formato de trama, se generará una interrupción UART_FRM_ERR_INT.
La interrupción UART_TX_DONE_INT se generará cuando se hayan transmitido
todos los datos en Tx_FIFO.
Cuando UART_TXD_BRK está configurado, el transmisor envía varios
caracteres NULL después de que el proceso de envío de datos ha terminado.
UART_TX_BRK_NUM puede configurar el número de caracteres NULL.
Después que el transmisor termina de enviar todos los caracteres NULL, se
generará la interrupción UART_TX_BRK_DONE_INT. El mínimo intervalo entre
los FRAME de datos se puede configurar con UART_TX_IDLE_NUM. Si el tiempo
de inactividad de un FRAME de datos es igual o mayor que el valor
configurado en el registro UART_TX_IDLE_NUM, se generará una interrupción
UART_TX_BRK_IDLE_DONE_INT.
La Figura 4 muestra un formato especial de caracteres AT_CMD. Si el
receptor recibe constantemente caracteres UART_AT_CMD_CHAR y estos

4
caracteres cumplen las siguientes condiciones, es generada una
interrupción UART_AT_CMD_CHAR_DET_INT.
• Entre el primer UART_AT_CMD_CHAR y el último UART_AT_CMD_CHAR, hay al
menos UART_PER_IDLE_NUM APB ciclos de reloj.
• Entre cada carácter UART_AT_CMD_CHAR debe haber menos de
UART_RX_GAP_TOUT APB ciclos de reloj
• El número de caracteres UART_AT_CMD_CHAR recibidos debe ser igual o
mayor que, UART_CHAR_NUM.
• Entre el último carácter UART_AT_CMD_CHAR recibido y el siguiente
UART_AT_CMD_CHAR, hay al menos UART_POST_IDLE_NUM APB ciclos de reloj.

Control de FLUJO de DATOS


El controlador UART admite el control de flujo de datos por hardware y
software. El control de flujo por hardware regula el flujo de datos a
través de la señal de entrada dsrn_in y la señal de salida rtsn_out. El
control de flujo de software regula el flujo de datos insertando
caracteres especiales en el flujo de datos enviados y detectando
caracteres especiales en el flujo de datos recibido.

FIGURA 4
La Figura 4 ilustra cómo funciona el control de flujo de hardware UART. En
el control de flujo por hardware, un estado alto de la señal de salida
rtsn_out significa que se solicita una transmisión de datos, mientras que
un estado bajo de la misma señal notifica la contraparte para detener la
transmisión de datos hasta que rtsn_out sea levantado nuevamente. Hay dos
formas para que un transmisor pueda realizar el control de flujo por
hardware:

5
• UART_RX_FLOW_EN es 0: el nivel de rtsn_out se puede cambiar configurando
UART_SW_RTS.
• UART_RX_FLOW_EN es 1: si los datos en Rx_FIFO son mayores que
UART_RXFIFO_FULL_THRHD, el nivel de rtsn_out se reducirá.
Si el controlador UART detecta un flanco en ctsn_in, generará una
interrupción UART_CTS_CHG_INT y se detendrá la transmisión de datos, una
vez que se completa la transmisión de datos actual.
El alto nivel de la señal de salida dtrn_out significa que el transmisor
ha terminado la preparación de datos.
El controlador generará la interrupción UART_DSR_CHG_INT, después de
detectar un flanco en la señal de entrada dsrn_in. Después que el software
detecta la interrupción mencionada anteriormente, el nivel de señal de
entrada de dsrn_in se puede determinar leyendo UART_DSRN. El software
luego decide si puede recibir datos en ese momento o no.
La configuración de UART_LOOPBACK habilitará la función de detección de
bucle invertido de la UART. En este modo, la señal de salida
txd_out de la UART está conectado a su señal de entrada rxd_in, rtsn_out
está conectado a ctsn_in y dtrn_out es conectado a dsrn_out. Si los datos
transmitidos corresponden a los datos recibidos, UART puede transmitir y
recibir datos normalmente.

CONTROL de FLUJO de Datos por SOFTWARE


El software puede forzar al transmisor a dejar de transmitir datos
configurando UART_FORCE_XOFF, así como forzar el transmisor para continuar
enviando datos configurando UART_FORCE_XON.
La UART también puede controlar el flujo del software transmitiendo
caracteres especiales. Configurando UART_SW_FLOW_CON_EN habilitará la
función de control de flujo de software. Si el número de bytes de datos
que UART ha recibido excede el del umbral UART_XOFF, el controlador UART
puede enviar UART_XOFF_CHAR para indicar a su contraparte que detenga la
transmisión de datos.
Cuando UART_SW_FLOW_CON_EN es 1, el software puede enviar caracteres de
control de flujo en cualquier momento. Cuando UART_SEND_XOFF está
configurado, el transmisor insertará un UART_XOFF_CHAR y lo enviará
después de los datos actuales de la transmisión se ha completado. Cuando
UART_SEND_XON está configurado, el transmisor insertará un UART_XON_CHAR y
lo enviará después de que se complete la transmisión de datos actual.

INTERRUPCIONES DE LA UART
• UART_AT_CMD_CHAR_DET_INT: se activa cuando el receptor detecta el
carácter at_cmd configurado.
• UART_RS485_CLASH_INT: se activa cuando se detecta una colisión entre el
transmisor y el receptor en Modo RS-485.
• UART_RS485_FRM_ERR_INT: se activa cuando se detecta un error de trama de
datos en RS-485.
• UART_RS485_PARITY_ERR_INT: se activa cuando se detecta un error de
paridad en el modo RS-485.
• UART_TX_DONE_INT: se activa cuando el transmisor ha enviado todos los
datos FIFO.
• UART_TX_BRK_IDLE_DONE_INT: se activa cuando el estado inactivo del
transmisor se ha mantenido al mínimo después de enviar los últimos datos.
• UART_TX_BRK_DONE_INT: se activa cuando el transmisor completa el envío
de caracteres NULL, después que se envían datos a la FIFO de transmisión.
• UART_GLITCH_DET_INT: se activa cuando el receptor detecta un bit de
INICIO.
6
• UART_SW_XOFF_INT: se activa si el receptor obtiene un Xon char cuando se
pone UART_SW_FLOW_CON_EN a 1.

SOPORTE ESP-IDF y ARDUINO


El ESPressif Iot Development Framework tiene toda una serie de funciones
que permiten la configuración de la UART, las mismas se encuentran en el
manual del ESP-IDF v4.1 en la página 876 muy completas y que pueden correr
en ARDUINO simplemente agregando en la cabecera del programa la inclusión
del archivo de cabecera:

#include <driver/uart.h>

#include <stdio.h>// lo incluimos si queremos usar printf

Es posible consultar como se construye la conversión de ARDUINO a ESP-IDF,


por debajo de Arduino existe toda una estructura de archivos denominada
HAL que es una capa de rutinas que permiten transformar ARDUINO a ESP-IDF.
Todos estos constructores los pueden ver en:

Documentos\Arduino\hardware\espressif\esp32\cores\esp32

También se puede consultar los archivos de librerias de espressif IDF que


se pueden incorporar a nuestro código arduino, las cuales están en:

Documentos\Arduino\hardware\espressif\esp32\tools\sdk\include

Las funciones que manejan los periféricos internos del ESP32 se encuentran
en:

Documentos\Arduino\hardware\espressif\esp32\tools\sdk\include\driver\driver

También podría gustarte