MICROPROCESADORES EJERCICIO DE EVALUACIÓN POR CURSO Microcontrolador ATMEL AT90S2313 Apellidos, Nombre Problema.- Descripción general: Se desea utilizar un microcontrolador AT90S2313 para registrar el número de personas que existen en el interior de un edificio determinado. Dicho edificio posee un acceso de entrada y otro distinto para la salida y, en cada uno de ellos, se ha situado un dispositivo que genera un pulso por cada persona que lo atraviesa. El número de individuos que caben en el edificio es inferior a 10000, como parece obvio, pero puede ser mayor a 255. El propietario del edificio quiere conocer, de forma remota, el número de personas que se encuentran en su interior, utilizando un enlace serie asíncrono a 2400bps. Descripción detallada: • Contaje. Los pulsos que generan los dispositivos situados en las entradas, se conectan en los pines PD2(INT0) y PD3(INT1), accesos de entrada y salida respectivamente. El microcontrolador debe configurar la generación de interrupciones externas mediante flanco de bajada. Las rutinas de interrupción correspondientes deberán incrementar o decrementar la variable NUM_PERSONAS. • Enlace Remoto. La UART debe habilitar la generación de interrupciones por recepción. La recepción del byte $F, provocará que el microcontrolador envíe (mediante polling e independiente de la rutina de interrupción de recepción) una secuencia de tres bytes que contiene, primero, el propio dato recibido, a continuación el byte MSB de la variable NUM_PERSONAS y, finalmente, el byte LSB de dicha variable. La señal de reloj del microcontrolador es de 1Mhz. Solución propuesta: En primer lugar, se procederá a construir las rutinas de configuración necesarias para los puertos, interrupciones externas y UART. • Interrupciones externas: Requiere que los bits INT1,INT0 del registro GIMSK estén activos. A su vez, los bits ISCX1,ISCX0 (donde X=1 o 0) del registro MCUCR deben ser 1 y 0 respectivamente (configuración del flanco de bajada). Además los pines PD3 y PD2 se deben configurar como entradas (aunque por defecto, esta es la configuración con la que arranca el microcontrolador). Config_int_externas: LDI TEMP, $C0 OUT GIMSK, TEMP LDI TEMP,$0A OUT MCUCR,TEMP ;Configura flanco de bajada en entradas externas CBI DDRD,2 ;Configura el pin PD2 como entrada CBI DDRD,3 ;Configura el pin PD3 como entrada ;Habilita generación de interrupciones externas. RET 1 • Configuración de la UART. Velocidad a 9600bps, teniendo en cuenta el reloj de 1Mhz, esto nos da un valor de UBRR = 25. Por otro lado, se deben habilitar, tanto el receptor como el transmisor y la generación de interrupciones de recepción, por lo que los bits RxEN, TxEN y RXCIE del registro UCR deben estar a 1. No hay que configurar los pines de los puertos, porque, automáticamente, cuando se activa la UART, los pines se configuran en el sentido adecuado. Config_UART: LDI TEMP, 24 OUT UBRR, TEMP LDI TEMP,$98 OUT UCR,TEMP ;2400bps RET • Rutina de interrupción externa 0 (acceso de entrada). Su función es incrementar la variable NUM_PERSONAS INT_EXTERNA0: IN TEMP, SREG PUSH TEMP LDI TEMP,1 ADD NUM_PER_LOW,TEMP ;Incrementa el byte menos significativo CLR TEMP ;borra temp, pero no afecta al bit C ADC NUM_PER_HIGH,TEMP ;Incrementa C a la parte más significativa. POP TEMP OUT SREG,TEMP RETI • Rutina de interrupción externa 1 (acceso de salida). Su función es decrementar la variable NUM_PERSONAS INT_EXTERNA1: IN TEMP, SREG PUSH TEMP LDI TEMP,1 SUB NUM_PER_LOW,TEMP ;Decrementa el byte menos significativo CLR TEMP ;borra temp, pero no afecta al bit C SBC NUM_PER_HIGH,TEMP ;Decrementa C a la parte más significativa. POP TEMP OUT SREG,TEMP RETI • Rutina de interrupción de UART. Recibe el byte del enlace remoto, lo almacena en alguna posición determinada y activa la variable global RECEP. INT_UART: IN TEMP, SREG PUSH TEMP IN TEMP,UDR CPI TEMP,$F BRNE salto_int MOV SECUENCIA0,TEMP LDI RECEP,1 ;Lee el byte recibido. ;Pone a 1 la variable global RECEP. 2 salto_int: POP TEMP OUT SREG,TEMP RETI • Programa principal. Inicializa pila y registros. RESET: .INCLUDE “2313DEF.INC” .DEF TEMP=R16 .DEF SECUENCIA0=R1 .DEF SECUENCIA1=R2 .DEF SECUENCIA2=R3 .DEF CONT=R17 .DEF NUM_PER_HIGH=R18 .DEF NUM_PER_LOW=R19 .DEF RECEP=R20 .ORG 0x0 RJMP RESET RJMP INT_EXTERNA0 RJMP INT_EXTERNA1 .ORG 0x7 RJMP INT_UART LDI TEMP,$DF OUT SPL,TEMP RCALL Config_int_externas RCALL Config_UART CLR NUM_PER_HIGH CLR NUM_PER_LOW SEI BUCLE: Transmision: SBRS RECEP,0 RJMP BUCLE ;Si RECEP es 1, hay que transmitir el número de personas CLI ;Anula interrupciones MOV SECUENCIA1, NUM_PER_HIGH MOV SECUENCIA2,NUM_PER_LOW SEI BUCLE_TX: ;Activa interrupciones CLR RECEP LDI CONT,3 CLR ZHIGH LDI ZLOW,1 ;El registro Z apunta al registro R1, donde comienza la secuencia a transmitir. SBIS USR,UDRE ;Espera que el buffer de transmisión quede vacío. RJMP BUCLE_TX LD R0,Z+ OUT UDR,R0 DEC CONT BRNE BUCLE_TX RJMP BUCLE ;Transmite el primer byte de la secuencia 3