Hola a todos!! bueno hoy os escribo para contaros un poco mas sobre los microcontroladores en general, y sobre la gama PIC18 de Microchip en particular.
En nuestro ejemplo del cruce de semáforos, o en el que hacíamos parpadear un led, si nos fijamos en el código, mientras esperamos a que el temporizador cuente hasta el final, el microcontrolador se encuentra "bloqueado", es decir, tenemos el código parado de forma que no podemos hacer nada mas que eso, esperar. Estaría genial que mientras nosotros hacemos otra cosas, hubiera algo que nos avisara cuando el temporizador llega al final, en ese momento nosotros dejamos de hacer lo que estabamos haciendo, atendemos al temporizador y luego seguimos con lo nuestro a la espera de que ese algo nos vuelve a avisar. Esto justamente es lo que hacen las interrupciones.
Una Interrupción (también conocida como interrupción hardware o petición de interrupción) es una señal recibida por la cpu del microcontrolador, indicando que debe "interrumpir" el curso de ejecución actual y pasar a ejecutar código específico para tratar esta situación. Estas señales que recibe la cpu del microcontrolador pueden venir de muchos sitios como pueden ser:
- Desbordes del temporizador/contador.
- Dato recibido en el buffer RS-232.
- Dato recibido mediante comunicación serie síncrona.
- Captura realizada por el modulo CCP.
- Fin de conversión analogico - digital.
- Cambio de estado en un PIN.
- ...
Cuando un microcontrolador está ejecutando una programa, existe un elemento llamado pila (stack) que va memorizando la linea que está ejecutando, en el momento de produce una interrupción, que hemos activado previamente, el microcontrolador detiene la ejecución del programa principal y se va a una dirección de memoria, en nuestro caso 0x08, en la que se encuentra el código que pertenece a esa interrupción, una vez ejecutado ese código, el microcontrolador va a la pila, lee la instrucción por donde se había quedado, y sigue su ejecución hasta recibir otra interrupción.
Para configurar las interrupciones, el microcontrolador dispone de los siguiente registros:
- RCON: Configuración del sleep-mode y reset.
- INTCON,INTCON2,INTCON3: Control de interrupciones:
- PIR1,PIR2: Flag de periféricos.
- PIE1,PIE2: Habilitación de interrupciones de periféricos.
- IPR1,IPR2: Configuración de prioridades.
No voy a analizar uno a uno todos los registros ya que son todos muy parecidos, asi que os explicaré los mas representativos.
- GIE/GIEH: Habilita o deshabilita las interrupciones a nivel global.
- PEIE/GIEL: Habilita o deshabilita las interrupciones de periféricos.
- XXXIF: Todos los bits que terminen con IF, son los bits que se pondrán a 1 cando salte la interrupción (IF= Interrupt Flag).
- XXXIE: Todos los bits que terminen con IE, son los que debemos poner a uno para activar cierta interrupción. (IE = Interrupt Enable).
En principio siempre trabajaremos con los niveles de prioridad desactivados, por lo que todas las interrupciones serán de alta prioridad, pero aún asi tenemos que decidir una prioridad entre ellas. La prioridad sirve para que, en el caso de que salten dos interrupciones al mismo tiempo, seamos nosotros quienes decidamos cual es más importante. Esta selección la haremos por hardware. A continuacion os pongo un ejemplo de codigo para que veais como implementar las interrupciones:
##--------------------------------------------------------------
#include <p18F4550.h>
// Bits de configuración
// Declaración de la rutina de tratamiento interrupción de alta prioridad
void R_Int_Alta(void);
// Vectorización de las interrpciones de alta prioridad
#pragma code Vector_Int_Alta=0x08 // Dieccion de memoria donde iremos
//cuando salte la interrupción.
void Int_Alta (void)
{
_asm GOTO R_Int_Alta _endasm // Cuando se produce una interrupción de alta
} // Prioridad se ejecuta la función R_Int_Alta
#pragma code
#pragma interrupt R_Int_Alta
void R_Int_Alta (void)
{
//LA PRIORIDAD LA ASIGNAMOS CON EL ORDEN EN QUE PONGAMOS LOS COMANDOS IF.
//EL QUE ESTE MAS HACIA ARRIBA SERÁ EL PRIMERO QUE SE EJECUTE, POR TANTO SERA LA
//INTERRUPCIÓN MÁS IMPORTANTE
if(XXXIF){
XXXIF=0;
//Codigo que queremos que se ejecute para esta interrupción.
}
if(XXXIF){
XXXIF=0;
//Codigo que queremos que se ejecute para esta interrupción.
}
if(XXXIF){
XXXIF=0;
//Codigo que queremos que se ejecute para esta interrupción.
}
}
void main (void)
{
while (1){
//CODIGO NORMAL
} // Bucle sin fin
}
##--------------------------------------------------------------
En la próxima entrada haremos los mismos ejemplos que hemos programado anteriormente, pero esta vez utilizando interrupciones.
Un saludo
No hay comentarios:
Publicar un comentario