UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Interrupciones. Temporizadores y Contadores de eventos en microcontroladores. Objetivos. • Conocer y poder usar interrupciones externas. • Programar rutinas de servicio de interrupciones. • Entender las diferencias entre evento de interrupción generado por nivel o por canto. • Conocer y poder usar temporizadores. • Programar rutinas de servicio de timer. • Emplear timer para generar señales de determinada duración. • Simular programas que usen interrupciones y temporizadores. Preparación previa. Interrupciones en microcontrolador 8051. Fuentes. Existen cinco fuentes externas que pueden causar interrupciones. Dos señales externas(INT0’, INT1’ de lógica negativa, ubicadas en P3.2 y P3.3. Son los pines 12 y 13 del microcontrolador) que setean dos flip-flops IE0 y IE1, cuando ocurre un canto de bajada o un cambio de nivel de la señal externa. Int0’ Pin 12 P3.2 Int1’ Pin 13 P3.3 Los bits de control IT0 e IT1 programan si el evento se registra cuando ocurre un canto o un cambio de nivel. Los estados registrados en IE0 e IE1 se limpian cuando se sirve la interrupción, en caso de ser activadas por cantos; si la generación de las interrupciones es por cambio de nivel, el hardware externo debe desactivar el nivel. Dos interrupciones ocasionadas por los rebalses de los timer se almacenan en TF0 y TF1. Estos valores se limpian automáticamente cuando se sirve la interrupción. Una interrupción generada por la puerta serial cuando se llena el buffer de recepción(RI) o cuando se vacía el de trasmisión(TI). Esta condición no es puesta a cero cuando se sirve la interrupción. Debe ser limpiada dentro de la rutina de servicio, cuando se haya determinado la causa de la interrupción. Todos los bits que registran interrupciones pueden ser puestos en cero, mediante instrucciones. Esto permite no servir interrupciones pendientes(que aún no han sido servidas), para esto deben limpiarse los bits dentro del rutina de servicio. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 41 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Habilitamiento. Cada una de las cinco fuentes puede ser habilitada o deshabilitada individualmente mediante el registro IE. Se dispone de un habilitamiento global de las interrupciones. El registro IE se encuentra en la dirección 0xA8, y puede manipularse al bit. Símbolo Ubicación En uno habilita interrupción generada por: ES IE.4 Puerta serial ET1 IE.3 Timer 1 ET0 IE.1 Timer 0 EX1 IE.2 Externa 1 EX0 IE.0 Externa 0 EA IE.7 todas las fuentes habilitadas en IE. Por lo tanto es posible, que una rutina de servicio, deshabilite a otras, cambiando los bits de IE. También es posible diseñar una rutina de servicio que no pueda ser interrumpida; para esto basta limpiar EA al entrar a la rutina, y dejar EA en uno, antes de salir. Prioridad. Las cinco fuentes de interrupciones tienen asignada una prioridad. Una interrupción de baja prioridad puede ser interrumpida por otra de mayor prioridad; pero no por una de más baja prioridad. El registro IP se encuentra en la dirección 0xB8, y puede manipularse al bit. Símbolo Ubicación En uno asigna alta prioridad a: PS IP.4 Puerta serial PT1 IP.3 Timer 1 PT0 IP.1 Timer 0 PX1 IP.2 Externa 1 PX0 IP.0 Externa 0 Si se registran dos solicitaciones de interrupción de diferente prioridad, se sirve la de mayor prioridad. Si son de igual prioridad(o sea ambas altas o ambas bajas) se define un orden entre ellas. De mayor a menor el orden es: IE0, TF0, IE1, TF1, (RI or TI). Forma de procesar la interrupción. En los últimos ciclos de reloj de un ciclo de máquina(éste tiene 12 ciclos de reloj), se toman las muestras y se graban los flip-flops que registran los requerimientos de interrupción. En el siguiente ciclo de máquina se determina el requerimiento que debe ser servido, si existe un requerimiento que cumpla las condiciones(prioridad, habilitamiento) en el próximo ciclo de máquina se efectúa un llamado de hardware a la rutina de servicio de la interrupción correspondiente(la unidad de control inserta una instrucción de llamado a subrutina, la cual demora dos ciclos de máquina).. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 42 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Este llamado no se efectúa en tres casos: En caso que se esté efectuando el servicio de una interrupción de igual o mayor prioridad(en este caso el requerimiento queda pendiente); si el ciclo de determinación de la interrupción no es el último de la instrucción que se está ejecutando(esto asegura que la instrucción en ejecución se termine correctamente); si la instrucción en ejecución escribe en los registros IP o IE, o es la instrucción RETI(esto asegura que se efectuará dichas instrucciones y una adicional antes de saltar a la rutina de servicio. El llamado a una subrutina por hardware consiste en que el procesador empuja en el stack el valor de PC y carga en PC la dirección del vector de la interrupción que debe servirse. Las direcciones de los vectores se encuentran en la siguiente tabla: Símbolo IE0 TF0 IE1 TF1 RI+TI Dirección 0x0003 0x000B 0x0013 0x001B 0x0023 Causada por interrupción: Externa 0 Timer 0 Externa 1 Timer 1 Puerta serial Sentencia C para fijar el vector interrupt 0 interrupt 1 interrupt 2 interrupt 3 interrupt 4 Se tienen 8 bytes para la rutina de servicio. En caso de requerir ésta más espacio se suele instalar una instrucción de salto a la rutina(por esto se suele denominar vector a las celdas de inicio de los servicios). La instrucción de salto ocupa tres bytes. Retorno de interrupción. La última instrucción de una rutina de servicio debe ser reti. Las rutinas del programa terminan en la instrucción ret. La instrucción reti, informa a la unidad de control del procesador que la rutina de servicio terminó y que puede aceptar requerimientos del mismo nivel de prioridad de la que acaba de terminar; o bien si es de menor prioridad ejecuta una instrucción antes de servir la interrupción pendiente. Además reti, saca del stack la dirección de la próxima instrucción a ejecutar y la graba en el registro PC. Requerimientos de interrupciones externas. Si una interrupción externa se activa por canto, el controlador visualiza que en un ciclo de máquina se tenga un nivel y el complemento en el siguiente; es decir la fuente que genera la interrupción debe hacerlo con un pulso de por lo menos 12 ciclos de reloj en alto y de por lo menos 12 ciclos de reloj en bajo, para que pueda ser detectado el canto. Los bits IE0 y EI1 son puestos en cero al servir la interrupción. Si la interrupción externa es activada por nivel, la fuente que la produce debe mantenerla activa hasta que se produzca el servicio; y debe desactivarla antes de que termine la rutina de servicio, en caso contrario se producirá otra interrupción. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 43 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Velocidad de respuesta. Se requieren un mínimo de tres ciclos de máquina antes de que comience la primera instrucción de una rutina de servicio(el ciclo actual y los dos del llamado por hardware). Este tiempo puede aumentar si una interrupción de igual o mayor prioridad está en ejecución(en este caso pueden pasar varios ciclos); o si la instrucción en ejecución aún no termina(en este caso puede alargarse en 3 ciclos ya que la instrucción más larga MUL o DIV ocupan cuatro ciclos de máquina); o si la instrucción modifica IP o IE o es un RETI lo más que se puede alargar es 5 ciclos(uno para completar la instrucción corriente y 4 adicionales, en peor caso(MUL o DIV), para ejecutar la próxima instrucción). Entonces la velocidad de respuesta a un requerimiento, que pueda servirse, es mayor que 3 ciclos y puede durar hasta 8 ciclos antes de iniciar la primera instrucción de la rutina de servicio. Salvar recursos. Cuando se está ejecutando una subrutina, ésta tiene almacenadas las variables más usadas en registros(esto por velocidad de ejecución), al ingresar a la rutina de servicio de la interrupción, se requiere almacenar el estado de los registros que estén siendo usados y antes de salir debe restaurárselos. Para lograr el cambio de ambiente(de contexto) en el microcontrolador se dispone de cuatro bancos de registros. Cada banco está formado por 8 registros, denominados R0..R7, cada registro es de 8 bits. El cambio de banco puede efectuarse en menor tiempo que múltiples escrituras y lecturas a la memoria para salvar los registros en forma individual, logrando rutinas que pueden tener menores tiempos de ejecución(esto es indispensable en aplicaciones de tiempo real, en las cuales el microcontrolador debe reaccionar rápidamente a los cambios). Entonces al entrar a la rutina de servicio se almacena el banco actual, luego se cambia de banco. Al salir de la rutina se restaura el banco que se estaba usando al ingresar. Se emplean los bits 3 y 4 del registro PSW para almacenar el número de banco en uso. Los bancos de registros están ubicados en las direcciones inferiores de la RAM interna. Banco 00 01 10 11 Desde dirección 0x00 0x08 0x10 0x18 Hasta Dirección 0x07 0x0F 0x17 0x1F Sentencia C para definir banco using 0 using 1 using 2 using 3 Entonces los nombres R0 hasta R7 pueden significar direcciones diferentes de memoria, de acuerdo al número de banco activo. Por ejemplo R0 en el banco cero es la dirección 0x00, y R0 en el banco 2 es equivalente a la dirección del byte 0x10. En este microcontrolador los registros son los primeros bytes de la memoria ram interna. Debe notarse que al efectuar un reset del microcontrolador, éste inicializa el stack pointer en 0x07. Si se emplean otros bancos debe modificarse el stack al inicio. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 44 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores El registro SP(stack pointer) apunta al último ocupado, cuando se empuja algo en el stack, primero se incrementa SP y luego se almacena el byte en la dirección que éste apunta. Es decir, se van apilando datos hacia arriba. El siguiente ejemplo ilustra una rutina de servicio que salva el acumulador y se cambia al banco 2. No se emplea el banco tres, y la zona se usará para el stack. En la iniciación, antes de llamar a main, debe establecerse el stack, para ello basta ejecutar: mov SP, #17 ; no puede usarse el banco 3 para registros, es la zona de stack. rutina de servicio: push acc push psw mov psw,#10 .... .... pop psw pop acc reti ;salva acumulador ;salva banco actual ;setea banco 2(en binario coloca banco en bits 3 y 4: 00010000) ;restaura banco Instalación de las rutinas de servicio. La sentencia en C: void timer0(void) interrupt 1 using 2 Intercala el código de inicio y término de la rutina de servicio para fijar el banco que se empleará. Además la especificación de interrupt 1, escribe en la dirección 0x000B la instrucción: ljmp timer0 ; el nombre simbólico de la rutina. Código de arranque. El compilador C genera automáticamente una serie de instrucciones para setear el stack y limpiar los primeros 128 bytes de la RAM interna(banco de registros y zona de bits(0x20 hasta 0x2F)); y para llamar a la rutina principal. En el siguiente código, se han colocado todos los vectores. Sólo es necesario colocar las instrucciones de salto en las interrupciones que se programen, quedando disponibles los bytes que no se empleen. La fijación del stack depende de la forma en que se use. Por un lado si debe soportar que una rutina llame a otras subrutinas, debe calcularse un tamaño que permita almacenar los espacios y direcciones de retorno, para el mayor número de rutinas que puedan estar simultáneamente activadas. Si se emplea además para soportar recursividad, debe calcularse para permitir todas las encarnaciones de las variables locales. En el compilador puede programarse que el stack esté en memoria externa. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 45 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores 0x0000 0x0003 0x0006 ..... 0x000B .…. 0x000E ..... 0x0013 0x0016 ..... 0x001B 0x001E ….. 0x0023 0x0026 inicio : lazo: ljmp ljmp … inicio externa0 ljmp ... ... timer0 ljmp ... externa1 ljmp … timer1 ljmp … mov clr mov mov djnz mov ljmp serial SP,#17 a R0, #7F @R0,a R0, lazo P2,#FF main ;cuando se activa reset, PC se coloca en 0x0000. ;zona de vectores. ;setea stack (en la zona del banco 3) ;inicia R0 con 127 decimal ;limpia lo apuntado por R0 ;R0- - y salta si no es cero a lazo. ;inicia puerta P2 de entrada(Manual pág. 3-6 y 3-7) ;vincula con el principal. Cuando se emplea un compilador gran parte de los detalles de assembler que se han explicado no son necesarios, ya que éste genera automáticamente los vectores y el código de arranque. Normalmente el código de arranque debe estar en assembler, ya que es dependiente del procesador. Temporizadores. El 8051 tiene dos contadores internos, denominados timer 0 y timer 1. Cada timer puede funcionar como contador o como temporizador. Se habilita el reloj del contador con la ecuación: TRi & (Gatei’ # INTi’) , con i =0 para timer 0; y con i = 1 para timer 1. El reloj del contador está dado por: (C/Ti & Ti) # (C/Ti’ & (clk/12)) Timer. Si C/Ti = 0 funciona como timer, en este caso el contador incrementa su cuenta una vez, cada 12 ciclos del reloj del procesador(desde una cuenta inicial que puede presetearse). Cuando el contador pasa a la cuenta cero, se pone en uno TFi (se setea en el overflow del contador). Para habilitar el temporizador se emplea el bit TRi, que recuerda Timer Run. Además se requiere que Gatei = 0. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 46 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Cuando TFi se pone en uno , se genera condición para interrupción. En caso de estar habilitada la interrupción del timer, este bit se coloca en cero al servirse la interrupción. Se lleva la cuenta en dos registros THi y TLi de 8 bits cada uno. Escribiendo en estos registros se puede colocar un valor inicial en el contador. Mediante dos bits M1i y M0i se programa el modo de contar. El modo 00: El contador opera con 13 bits(de los 16) permitiendo cuentas desde 0 hasta 213 – 1. El modo 01: Opera como contador de 16 bits. Cuentas desde 0 hasta 65.535. El modo 10: Denominado de autocarga, opera como contador de 8 bits(cuentas desde 0 hasta 255), y de tal forma que cuando TL es cero se ejecuta automáticamente TL = TH. El modo 11: El timer 1 no cuenta. TL0 queda controlado por el control del timer 0 y TH0 queda controlado por el control del timer 1. Contador de eventos. Si C/Ti = 1 funciona como contador de los pulsos que ingresen por Ti. Más específicamente cuenta los cantos de bajada de la señal externa Ti. Como esta señal es asincrónica respecto del reloj, la unidad de control toma un muestra de la señal en cada ciclo de máquina, si existe un cambio de 1 a 0 incrementa la cuenta; esto implica que el ancho del pulso debe ser a lo menos de un ciclo de máquina. La máxima velocidad que puede contar es la 24 ava parte de la frecuencia del reloj. T0 puede denominarse P3.4 y corresponde al pin 14 del microcontrolador; T1 puede denominarse P3.5 y es el pin 15 del chip. T0’ Pin 14 P3.4 T1’ Pin 15 P3.5 Como la habilitación del contador se realiza con: TRi & (Gatei’ # INTi’), esto puede lograrse con TRi =1 y con (Gatei’ # INTi’) = 1. Colocando el bit Gatei = 1, la habilitación queda: TRi & ( INTi’) lo cual permite detener la cuenta con un canto de bajada de la señal externa INTi. Puede medir desde continua hasta 500 kHz. Medición de tiempos. Si C/Ti = 0 y Gatei = 1, después que se aplique TRi = 1, se cuentan los ciclos de máquina(la doceava parte de la frecuencia del reloj) que transcurren mientras la señal INTi esté alta. Esta forma permite medir el ancho de un pulso. Mide intervalos de tiempo con resolución de 1 µseg, de hasta 65,5 mseg. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 47 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Registros. En general se manipulan al byte o al bit. TMOD. Sólo puede escribirse el byte, no hay acceso a cada bit en forma individual. Dirección 7 6 5 4 3 2 1 0 0x89 Gate1 C/T1 M11 M01 Gate0 C/T0 M10 M00 TCON Dirección 7 6 5 4 3 2 1 0 0x88 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 IE Dirección 7 6 5 4 3 2 1 0 0xA8 EA -- -- ES ET1 EX1 ET0 EX0 IP Dirección 7 6 5 4 3 2 1 0 0xB8 -- -- -- PS PT1 PX1 PT0 PX0 PSW Dirección 7 6 5 4 3 2 1 0 0xD0 CY AC F0 RS1 RS0 OV -- P CY Reserva de salida en unsigned int OV Rebalse en números con signo RS1 y RS0 número de banco activo de registros P Paridad del acumulador AC carry interdígito en suma BCD. Ver instrucción DA. bit 1 y 5 bits disponibles para el programador. Contadores 0x8A TL0 0x8B TL1 0x8C TH0 0x8D TH1 Contadores, sólo direccionables al Byte. Los nombres simbólicos para los bytes y bits pueden verse en las definiciones de datos en reg51.h Dirección 7 6 5 4 3 2 1 0 0x90 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 Puerta P1, después de un reset, se escribe 0xFF en el latch de salida. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 48 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Preparación Previa. Interrupciones. Modificar el programa en el CPLD, para que además de interconectar el 8031 con la memoria RAM, se logre: • generar interrupciones externas, cuando se cambien los valores de los bits 5 y 6 de la puerta paralela. • Mostrar en el led, con un 0 ó 1, la interrupción que se produjo. El siguiente diagrama muestra los pines del CPLD que es necesario programar. CPLD s5 s6 s4 s2 s3 s1 s0 dp S6 15 S5 14 S4 18 S3 17 S2 19 S1 23 S0 21 Dp 24 66 P1.6 71 P1.5 72 P1.4 5 P1.3 11 P1.2 7 P1.1 6 P1.0 67 P1.7 8031 Puerta P1 PCD6 81 69 Int0’ PCD5 52 68 Int1’ Escribir un programa, usando lenguaje C, que instale las rutinas de servicio de las interrupciones. Éstas deben escribir en la puerta P1, los valores hexadecimales que muestren el número 0 ó 1 en el led. (nótese que no hay decodificador en el CPLD). ¿Cómo puede simular un programa que tenga interrupciones externas? ¿Cómo asegura que las interrupciones operen correctamente, a pesar de que sucedan ambas simultáneamente? Decidiendo si operaran por nivel o por canto, y si una tiene prioridad sobre la otra. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 49 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA ELO312 Laboratorio de Estructuras de Computadores Timer a) Generar mediante el timer 0 una onda cuadrada, de período 60 ms, por el el pin 2 de la puerta 1, empleando en lenguaje C. Simular, visualizando el timer y la puerta 1. Usar modo animación. b) Escribir un programa en assembler o en C, mediante rutinas de retardo que genere igual forma de onda, que la especificada en a), sin emplear el timer. En esta situación se ejecutan instrucciones(que duran 12 ó 24 pulsos de reloj) para medir el tiempo. c) Escribir programa, en lenguaje C y empleando el timer del 8031, que genere tres señales a través de los pines: P1.1 , P1.2, P1.3. P1.1: Está en cero durante x mseg y en uno durante 3x mseg. P1.2: De ciclo 50 %, se coloca en uno en el canto de bajada de P1.1 P1.3: Se coloca en uno con el canto de subida de P1.1, durante x mseg. En el Laboratorio. Mostrar el funcionamiento de las interrupciones. Mostrar las señales generadas empleando un osciloscopio. Prof. Leopoldo Silva Bijit. Lab. 08 11-09-2002 50