LSP: UART SW COMUNICACIÓN SERIE ENTRE MICROCONTROLADORES MEDIANTE UART SW En esta práctica se describe la forma de realizar una comunicación serie half-duplex entre dos microcontroladores utilizando UARTs software. En el apartado 1 se describe el hardware empleado para la conexión con el circuito real (que en principio no se utilizará). En el apartado 2 se indica el formato de trama y el modo de funcionamiento de la UART software tanto para la transmisión como la recepción. En el apartado 3 se indican las pruebas a realizar, que se limitan al empleo del simulador. 1. Descripción del hardware (circuito real). La figura representa el conexionado realizado. El aislamiento galvánico se garantiza mediante 2 optoacopladores (PC817), lo que obliga a utilizar 4 líneas de conexión (Figura 1). micro 0 micro 1 2K2 GND P3.4 P3.2 +5V 4K7 Líneas de conexión 4K7 +5V P3.2 P3.4 GND 2K2 Figura 1 Hardware para el enlace serie entre dos microcontroladores. Se supone que el puerto serie incorporado en el micro ya está siendo utilizado para otra tarea (p. ej. el enlace con un PC), por lo que debe programarse una UART software. Por simplicidad, se emplea una UART half-duplex. Se elige el terminal P3.2 (RxD) como receptor para utilizar el bit de inicio de la trama (START) como fuente de interrupción (INT 0). La señal se transmite por el terminal P3.4 (TxD). 1 LSP: UART SW 2. Descripción de la UART SW Para realizar la UART SW se utilizan los siguientes recursos: 1) Interrupción externa 0. La línea de recepción de datos (RxD) se conecta en la entrada P3.2 (INT0). De esta forma, es posible detectar la llegada de una trama mediante la interrupción generada por INT0. 2) Temporizador 1. Este temporizador se emplea para obtener los intervalos de tiempo necesarios en la generación de la señal transmitida y en el muestreo de la recibida. 2.1. Recepción de una trama La recepción de una trama se debe realizar de la siguiente forma (ver Figura 2): 1) La llegada del bit de START genera la interrupción externa 0. En la rutina de atención a la interrupción (ISR) correspondiente se inicializa un contador de bits recibidos (rx_nbit = 0). A continuación se carga en el temporizador 0 el valor adecuado para que se desborde después de que transcurra un tiempo t mediobit . De esta forma, la ISR del temporizador se ejecutará coincidiendo con el centro del bit de START. Además, las interrupciones externas 0 se dejan inhibidas. De esta forma se evita que otros flancos internos de la trama puedan generar una interrupción similar a la del bit de START. 2) El resto del proceso de recepción lo realiza la ISR del temporizador 1. La primera vez que entra la ISR (rx_nbit=0) se verifica que RxD se mantiene a 0. En caso contrario se considera que se trata de una trama no válida, provocada probablemente por una interferencia. Si el START es correcto, se prepara el temporizador para generar la próxima ISR después de un tiempo t bit y se incrementa rx_nbit. En sucesivas entradas de la ISR se muestrean los 8 bits de datos y se verifica el bit de parada (STOP). La variable rx_nbit permite a la ISR determinar qué bit de la trama se recibe en cada momento. Cuando finaliza la trama (llegada de un bit de STOP válido), se activa un indicador UART_RI, se deja parado el temporizador y se vuelven a habilitar las interrupciones externas. De esta forma se hace posible la recepción de una nueva trama. 2 LSP: UART SW start stop DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 tmediobit Comprobación del nivel tbit Lectura de bit de datos Figura 2 Formato de trama y proceso de recepción. Para saber si ha llegado una trama, se debe consultar el bit UART_RI. Si está a '1', se puede leer el byte recibido de la variable uart_rxbuf. Es importante dejar borrado el indicador UART_RI para que una posterior consulta contenga la información esperada. 2.2. Transmisión de una trama Antes de transmitir un byte, se debe esperar a que el indicador UART_TI se encuentre a '1'. Entonces, se carga el byte en la variable uart_txbuf y se llama a a subrutina txbyte. La transmisión se lleva a cabo de la siguiente forma. 1) La subrutina txbyte inicializa un contador de bits transmitidos (tx_nbit=0), carga el byte a transmitir en la variable tx_shift, activa el indicador txing y provoca la entrada de la ISR del temporizador 1 activando TF1. 2) La ISR del temporizador 1 verifica siempre txing para saber si debe gestionar una transmisión (txing=1) o una recepción (txing=0). La primera vez que entra la ISR del temporizador, el contador tx_nbit está a cero y la ISR pone la salida de datos TxD a '0' (bit de START). En entradas posteriores actualiza TxD con los bits de datos y finalmente con el bit de STOP (TxD='1'). Además, incrementa tx_nbit y prepara el temporizador para que genere la siguiente interrupción. Cuando tx_nbit es 10, la ISR da por concluida la transmisión (ya ha finalizado el bit de STOP), por lo que activa UART_TI, pone a '0' el indicador txing y habilita la interrupción externa 0 (habilita recepción). 3 LSP: UART SW start stop DB0 DB1 DB2 DB3 tbit DB4 DB5 DB6 DB7 Salida de nivel fijo Salida de bit de datos Figura 3 Formato de trama y proceso de transmisión. 2.3. Diagramas de flujo De acuerdo con el funcionamiento descrito en el apartado anterior, en las figuras siguientes se indican los diagramas de flujo correspondientes a la ISR de la interrupción externa INT0, la subrutina de transmisión de datos y la ISR del temporizador 1. intext0 rx_nbit = 0 inhibe interr. externa 0 prepara temp.0 prepara temp. 0 para tmediobit reti Figura 4 Diagrama de flujo de la ISR de INT0. 4 LSP: UART SW txbyte tx_nbit = 0 tx_shift = uart_txbuf inhibe interr. externa 0 txing = 1 TF0= 1 (genera int. temp0) (genera int. temp.1) ret reti Figura 5 Diagrama de flujo de la subrutina de transmisión. inttim0 inttim1 parartemp.1 tim0 parar si TxD = 0 si txing=1 ? tx_nbit=0 ? no rx_nbit=0 ? no TxD = DB(tx_nbit) si TxD = 1 si rx_nbit es 9 tx_nbit=9 ? si DB(rx_nbit) = RxD no RxD = 1 ? si txing = 0 UART_TI= 1 borra IE0 habilita EXT0 no si rx_nbit entre 1 y 8 ? no tx_nbit ++ RxD = 0 ? no tx_nbit entre 1 y 8 ? no si error de trama no UART_RI= 1 rx_nbit ++ error de trama borra IE0 habilita EXT0 reti preparar temp. 0 prepara temp.1 para tbit Figura 6 Diagrama de flujo de la ISR de TEMP1. 5 LSP: UART SW 3 Trabajo propuesto La forma más cómoda de depurar el SW de la UART consiste en realizar una simulación. Para ello se crean en el archivo CNX dos microcontroladores (con el mismo programa) y un botón conectado al primero de ellos (micro1). El pin del micro 1 que actúa como salida serie se conecta al pin de entrada serie del micro2, asignándoles el mismo número de nodo. Cada vez que se pulse el botón, el micro1 debe enviar un byte (o varios) al micro2. Para verificar el funcionamiento se pueden visualizar las tramas generadas, empleando el analizador lógico de UVI51win. 6