Contenido>Indice>Intro CursoC51

INTERRUPCIONES



Las interrupciones juegan un papel importante en muchas aplicaciones del 8051. Cuando se atiende a una interrupción se debe tener en cuenta diversos factores:

Funciones de interrupción

Para definir una función de interrupción en C, se utiliza un tipo especial interrupt:

    timer0_int() interrupt 1 using 2
    {
    unsigned char temp1;
    unsigned char temp2;
    siguen las sentencias C ejecutables;
    }

En primer lugar, para cada función de interrupción se genera un vector en la dirección de memoria de código (8*n+3), donde n es el argumento de interrupt (n=1 en el ejemplo anterior). En este caso en la dirección 0BH de memoria de código, el compilador C51 coloca un "LJMP timer0_int". Además el linker se ocupa de no solapar las variables locales de la función de interrupción, con las variables locales del programa principal.

Las funciones de interrupción no son llamadas por el usuario, se llaman de forma automática cuando se produce la interrupción. Por ello estas funciones no reciben parámetros ni devuelven valores. El compilador se encarga de guardar en la pila los registros que utilice la función de interrupción, en cuanto se entra en ella. También se ocupa de sacar de la pila los valores guardados, justo antes de salir de la función. Además C51 hace que las funciones de interrupción terminen en un RETI, en lugar del RET con el que terminan las funciones normales.

Uso del compilador C51 con tarjetas provistas de monitores&depuradores

Muchas tarjetas 8051, van provistas de un programa monitor&depurador en EPROM situado en dirección 0 del área CODE, con una RAM en dirección 0x8000 visible en las áreas CODE y XDATA gracias al producto de las señales PSEN y RD del µC. Esta situación tan común, presenta problemas con los vectores de interrupción que ocupan las direcciones: 3, 0Bh, 13H, 1BH, 23H, ....situadas en la EPROM. La mayoría de los programas monitor de estas tarjetas solucionan el problema redireccionando todos los vectores por encima de la dirección 0x8000 (hacia la RAM), para lo cual le añaden un desplazamiento de 0x8000 a cada vector. Así la rutina de atención al desbordamiento del timer 0 se trata en la dirección 0x800B en lugar de hacerlo en la dirección 0x0B.

Para realizar lo anterior, hasta la versión 3.40 de C51, la solución consistía en deshabilitar la generación automática de los vectores de interrupción, y escribir los vectores deseados en lenguaje ensamblador. Sin embargo desde la versión 3.40 se dispone del control INTVECTOR que facilita la tarea, ya que los vectores de interrupción se dirigen a las direcciones:

8 * n + 3 + INTVECTOR

Para utilizar este control se usa la directiva #pragma del preprocesador:

#pragma INTVECTOR(0x8000)/*Dirección inicial para los vectores = 0x8000*/

void timer0_int(void) interrupt 1 {

   /* Código...*/

   }

Lo cual produce un LJMP timer0_int en la dirección C:0x800B. Esta instrucción junto al salto que el programa monitor incluye desde la dirección C:0x0B hacia la dirección C:0x800B hace que las interrupciones funcionen correctamente.

Espaciado de Interrupciones distinto que 8

Algunos derivados del 8051 no mantienen el espaciado de 8 bytes entre los vectores de interrupción, haciendo inservible la fórmula (8 * n + 3 ). Afortunadamente, el "#pragma INTERVAL(n)" soluciona esta situación, ya que los vectores de interrupción se dirigen a las direcciones:

INTERVAL * n + 3 + INTVECTOR

#pragma INTERVAL(3)   /* Cambia el espaciado a 3 bytes */

Por omisión los valores utilizados son: INTERVAL(8) e INTVECTOR(0)

El control using

El control using n ordena al compilador que utilice el banco de registros n. El compilador C51 hace un uso intensivo de los registros R0...R7 del 8051. Normalmente se utiliza el banco de registros 0. Sin embargo, como puede apreciarse en la sección 5.2.1. se puede hacer que una función de interrupción utilice otro banco de registros diferente al utilizado por el programa principal. De esta forma el tiempo utilizado por las interrupciones se reduce, ya que no necesita empilar y desempilar los registros cada vez que se atienden.

Dos interrupciones de la misma prioridad pueden utilizar el mismo banco de registros debido a que no es posible que una de ellas interrumpa a la otra.

Si el tiempo de ejecución de las funciones de interrupción no es crítico, puede omitirse el uso del control using, en este caso C51 examina los registros que utiliza la interrupción, los guarda en la pila al entrar y los saca de la pila al salir. Esto lógicamente aumenta el tiempo utilizado por las funciones de interrupción.  


   Contenido>Indice>Intro CursoC51