Sei sulla pagina 1di 18

MICROCONTROLADOR PIC

INTERRUPCIONES
Una interrupcin es un recurso del cual disponen la mayora de los
microcontroladores en el mercado hoy en da .Permiten cambiar la
continuidad de ejecucin de un programa, para atender una
necesidad, ya sea externa o interna.
Como ejemplo, un botn de RESET puede ser visto como una
fuente de interrupcin, ya que detiene todos los procesos y reinicia
sistema por completo sin importar la accin que est realizando el
microcontrolador.

Una subrutina es una


porcin de cdigo que
forma parte del programa
principal.

el

Una interrupcin tiene la caracterstica de la inmediatez, nace de la


necesidad de ejecutar una subrutina en el instante preciso y, por
tanto, se considera su intervencin urgente, su funcionamiento es similar al de las subrutinas a
diferencia que estas se ejecutan por software cada vez que son llamadas del programa principal, y
las interrupciones se activan por una mecanismo hardware al aparecer en cualquier instante un
evento externo o interno al microcontrolador.

La tcnica polling consiste en que


el propio microcontrolador se
encargar de sondear o testear los
dispositivos perifricos cada cierto
tiempo para averiguar si tiene
pendiente alguna tarea para l.
Este mtodo no es muy eficiente, ya
que el microcontrolador consume
constantemente tiempo y
recursos en realizar estas
El uso de interrupciones esinstrucciones de sondeo.
un mtodo muy eficaz en
comparacin con la tcnica
polling, pues el
microcontrolador ya no
A) LECTURA DE UNA
ENTRADA
perder
tiempo testeando
MEDIANTE LAlos
TCNICA
dispositivos perifricos,
POLLING Osolo
DE CONSULTA
atender dicha tarea
cuando sea necesario,
mientras tanto el
microcontrolador podra pasar
a un estado de bajo consumo
(modo sleep), mientras espera
que ocurra una interrupcin
sea interna o externa.

B) LECTURA DE UNA ENTRADA


MEDIANTE INTERRUPCIONES

El PIC16F84A dispone de 4 posibles fuentes de interrupcin:

Interrupcin INT. Por activacin del pin RB0/INT.


Interrupcin RBI. Por cambio de estado en los bits de mayor peso (RB7:RB4) del puerto B.
Interrupcin T0I. Por desbordamiento del TIMER 0.
Interrupcin EE1.Por la Finalizacin de la escritura en la EEPROM de datos.

El PIC16F877A dispone de 14 posibles fuentes de interrupcin:

Interrupcin INT. Por activacin del pin RB0/INT.


Interrupcin RBI. Por cambio de estado en los bits de mayor peso (RB7:RB4) del puerto B.
Interrupcin T0I. Por desbordamiento del TIMER 0.

Interrupcin EE1.Por la Finalizacin de la escritura en la EEPROM de datos.


Interrupcin por desbordamiento del Timer1
Interrupcin por desbordamiento del Timer2
Interrupcin por Captura o comparacin en el mdulo CCP1
Interrupcin por Captura o comparacin en el mdulo CCP2
Interrupcin por Transferencia en la Puerta Serie Sncrona
Interrupcin por Colisin de bus en la Puerta Serie Sncrona
Interrupcin por Fin de la trasmisin en el mdulo USART
Interrupcin por Fin de la recepcin en el mdulo USART
Interrupcin por Fin de la conversin del mdulo conversor A/D
Interrupcin por Transferencia en la Puerta paralela esclava

EL PIC18FXX2 dispone de 18 posibles fuentes de interrupcin:

Interrupcin INT0. Por activacin del pin RB0/INT0.


Interrupcin INT1. Por activacin del pin RB1/INT1.
Interrupcin INT2. Por activacin del pin RB2/INT2.
Interrupcin RBI. Por cambio de estado en los bits de mayor peso (RB7:RB4) del puerto B.
Interrupcin T0I. Por desbordamiento del TIMER 0.
Interrupcin por escritura en la memoria FLASH/EEPROM
Interrupcin del SPP
Interrupcin por Fin de la conversin del mdulo conversor A/D
Interrupcin de recepcin de la EUSART
Interrupcin de transmisin de la EUSART
Interrupcin por desbordamiento del Timer1
Interrupcin por desbordamiento del Timer2
Interrupcin por desbordamiento del Timer3
Interrupcin por Captura o comparacin en el mdulo CCP1
Interrupcin por Captura o comparacin en el mdulo CCP2
Interrupcin por Transferencia en la Puerta Serie Sncrona (MSSP)
Interrupcin por Colisin de bus en la Puerta Serie Sncrona (MSSP)
Interrupcin por Transferencia en la Puerta paralela esclava

El PIC18F4550 posee 21 posibles fuentes de interrupcin:

Interrupcin INT0. Por activacin del pin RB0/INT0.


Interrupcin INT1. Por activacin del pin RB1/INT1.
Interrupcin INT2. Por activacin del pin RB2/INT2.
Interrupcin RBI. Por cambio de estado en los bits de mayor peso (RB7:RB4) del puerto B.
Interrupcin T0I. Por desbordamiento del TIMER 0.
Interrupcin por escritura en la memoria FLASH/EEPROM
Interrupcin del SPP
Interrupcin por Fin de la conversin del mdulo conversor A/D
Interrupcin de recepcin de la EUSART
Interrupcin de transmisin de la EUSART

Interrupcin por Transferencia en la Puerta Serie Sncrona (MSSP)


Interrupcin por Colisin de bus en la Puerta Serie Sncrona (MSSP)
Interrupcin por Transferencia en la Puerta paralela esclava
Interrupcin por Captura o comparacin en el mdulo CCP1
Interrupcin por Captura o comparacin en el mdulo CCP2
Interrupcin por desbordamiento del Timer1
Interrupcin por desbordamiento del Timer2
Interrupcin por desbordamiento del Timer3
Interrupcin por fallo en el oscilador
Interrupcin del puerto USB
Interrupcin por deteccin de anomalas en VDD

FUNCIONAMIENTO DE UNA INTERRUPCIN


Cuando se produce cualquiera de los sucesos indicados anteriormente se origina una peticin de
interrupcin que, si se acepta, origina el siguiente mecanismo hardware:

Salva el valor actual del contador de programa (PC), guardando su contenido en la pila
El PC se carga con el valor 004H para el caso de los PIC16 ya que tenemos un solo vector
de interrupcin, para los PIC18 tenemos 2 vectores de interrupcin uno de alta prioridad y
otro de baja prioridad ubicados en la posicin 0008H y
0018H respectivamente.
Comienza a ejecutarse el programa de atencin a la
interrupcin que se encuentra partir de la direccin 004H.

Los bits de control localizados en el registro INTCON habilitan y


configuran las interrupciones. Cada causa de interrupcin acta
con dos flags (banderas):

Uno de ellos acta como flag de sealizacin que indica si se ha producido o


no la interrupcin : Ejemplo (T0IF,INTF,RBIF,EEIF, TMR3IF, SSPIF, TXIF, entre
otros )
El otro funciona como permiso o prohibicin de la interrupcin en s:
Ejemplo: (T0IE, INTE, RBIE, EEIE, GIE, CCP1IE, TMR1IE, TMR2IE, TMR3IE,
TXIE, RCIE, entre otros.)

Interrupciones en el
PIC16F84A

Interrupciones en el
PIC18F4550

Interrupciones en el
Interrupciones en el
PIC16F877A
PIC18F4550

Interrupciones en el
PIC18FXX2

Hay un nico vector de interrupcin en la direccin 004H para el caso de los PIC16. Sea cual sea
la interrupcin el contador de programa se carga con la direccin 004H, para este caso. Por otro
lado para la familia de los PIC18 existen dos vectores de interrupcin de alta y baja prioridad ya
mencionados anteriormente, el contador de programa se cargar dependiendo de cmo definamos
la interrupcin. Dentro de la subrutina de atencin a la interrupcin, el programa deber identificar
la causa de la interrupcin .Para ello, debe testear el estado de los flags de interrupcin de cada
una de las fuentes habilitadas, para deducir cual fue la que caus la interrupcin y as decidir que
accin tomar.
En XC8 para el caso de los PIC18 la interrupcin la podemos definir de la siguiente manera:

void interrupt name (void) //Si no se especifica nada es de alta prioridad


void interrupt low_priority name (void) //Interrupcin de baja prioridad
*Las palabras resaltadas son partes del compilador nosotros debemos darle un nombre a
esta subrutina de interrupcin y colocar la tarea que deseamos que realice el
microcontrolador cada vez que se produzca la interrupcin.

INTERRUPCIN EXTERNA INT


La fuente de interrupcin externa INT es muy importante para atender eventos externos en
tiempo real. Veamos el caso para un PIC16F84A ,cuando en la lnea RB0/INT, se hace una
peticin de interrupcin el bit INTF del registro INTCON se pone a 1 de forma automtica y, si el
bit GIE est a 1, se pone en marcha el mecanismo ya comentado de la interrupcin.
Mediante el bit INTDEG del registro OPTION es seleccionado el flanco activo de RB0/INT, ya que
con ste puesto a 1, el flanco activo es ascendente y cuando est a 0, el flanco activo es
descendente.

Es importante que en el programa de atencin a la interrupcin, antes de regresar al programa


principal, borre el flag INTF, es decir ponerlo nuevamente a 0 por software.
Ahora veamos un ejemplo :
// Ejemplo con el PIC16F84A
#include <xc.h>

//Incluye las libreras del compilador XC8

#define _XTAL_FREQ 20000000

// Define Frecuencia de Oscilacin

#pragma config FOSC=HS,WDTE=OFF,PWRTE=ON,CP=OFF //Configuracin de fusible


// Subrutina de interrupcin externa INT/RB0
void interrupt isr(void) {
if (INTF) {

//Pregunta si la bandera INTF =1 (Si se activ la interrupcin)

__delay_ms(100);

// Antirebote

if(INTF){
PORTA=PORTA+1;

//Incrementa el puertoA en 1

__delay_ms(100); } }

//Retardo para visualizar la cuenta

INTCONbits.INTF=0; }

//Se desactiva la interrupcin (INTF=0) Importante!

Nota es importante volver a poner la bandera a 0 (INTCONbits.INTF=0) dentro de la subrutina de interrupcin, sino lo hacemos entonc

// Programa principal
void main(void) {
TRISB=0b00000001;

// Configura solo el puertoB.0

TRISA=0xF0;

// (PORTA<0:3>) como salida

PORTB=0x00;

// Inicializa todo el puertoB en 0 (OFF)

PORTA=0x00;

// Inicializa todo el puertoA en 0 (OFF)

INTCONbits.INTE=1;

// INTCONbits.INTE=1 Habilita la interrupcin externa RB0/INT


// INTCONbits.INTE=1 Habilita la interrupcin externa RB0/INT

OPTION_REGbits.INTEDG=1; // OPTION_REGbits.INTEDG=1 activo por flanco ascendente


// OPTION_REGbits.INTEDG=1 activo por flanco descendente
INTCONbits.INTF=0;

// Flag INTF=0; deshabilita una posible interrupcin de RB0

INTCONbits.GIE=1;

// INTCONbits.GIE=1 Habilita todas las interrupciones

//INTCONbits.GIE=0 Deshabilita todas las interrupciones


while (1){

//Bucle infinito

SLEEP();

// el microcontrolador entra en modo bajo consumo


// hasta que se produzca la interrupcin.

}
}

//Ejemplo con el PIC16F877A


#include <xc.h>
#define _XTAL_FREQ 20000000
#pragma config
FOSC=HS,WDTE=OFF,PWRTE=ON,BOREN=OFF,LVP=OFF,CPD=OFF,WRT=OFF,CP=OFF

void interrupt isr(void) {


if (INTF) {
__delay_ms(100);
if(INTF){
PORTD=PORTD+1;
__delay_ms(100);
}}
INTCONbits.INTF=0;
}
void main(void) {
TRISB=0b00000001;

TRISD=0b00000000;
PORTB=0x00;
PORTD=0x00;
INTCONbits.INTE=1;
OPTION_REGbits.INTEDG=1;
INTCONbits.INTF=0;
INTCONbits.GIE=1;
while (1){
SLEEP(); } }

INTERRUPCIN RBI
Para activar la interrupcin por cambio de nivel en los pines <RB7:RB4> los bits RBIE y GIE del
registro INTCON deben estar a 1 para el caso de un PIC16F84A y un PIC16F877A , en estas
condiciones cuando se produce un cambio de nivel en cualquiera de las lneas RB7 a RB4 se
activa el flag RBIF del registro INTCON. Ahora veamos un ejemplo :

#include <xc.h>
#define _XTAL_FREQ 20000000
#pragma config FOSC =
HS,WDTE=OFF,PWRTE=ON,BOREN=OFF,LVP=OFF,CPD=OFF,WRT=OFF,CP=OFF

void interrupt isr(void) {

INTCONbits.GIE=0;
if (RBIF) {
__delay_ms(100);
if(RBIF){
__delay_ms(100);
PORTD=PORTD+1;
}}
INTCONbits.RBIF=0;
}
void main(void) {

TRISB=0b11110000;
TRISD=0x00;
PORTB=0x00;
PORTD=0x00;
INTCONbits.RBIE=1;
INTCONbits.RBIF=0;
INTCONbits.GIE=1;
while (1){
SLEEP();
}
}

#include <xc.h>
#define _XTAL_FREQ 20000000
#pragma config FOSC = HS,WDTE=OFF,PWRTE=ON,CP=OFF

void interrupt isr(void) {

INTCONbits.GIE=0;
if (RBIF) {
__delay_ms(100);
if(RBIF){
__delay_ms(100);
PORTA=PORTA+1;
}}
INTCONbits.RBIF=0;
}
void main(void) {

TRISB=0b11110000;
TRISA=0x00;
PORTB=0x00;
PORTA=0x00;
INTCONbits.RBIE=1;
INTCONbits.RBIF=0;
INTCONbits.GIE=1;
while (1){
SLEEP();
}
}

EL TIMER0
El Timer 0 es un contador / temporizador de 8 bits. El registro principal de este mdulo es TMR0.
Este registro se incrementa continuamente a una frecuencia seleccionable manejada por un
preescalador y el reloj interno Fosc/4 (modo temporizador) o bien, por un preescalador y una
seal externa (modo contador), su contenido se incrementa con cada impulso de entrada hasta
llegar a su valor mximo (TMR0=255).

Carga inicial del contador

Contador Ascendente

Fin de contaje

Impulsos de entrada

Esquema simplificado de un TIMER


Con el siguiente pulso de entrada el contador se desborda, es decir su valor cambia de 255 a 0,
circunstancia que se advierte mediante la activacin del flag T0IF del registro INTCON,
producindose as la interrupcin.
Los impulsos aplicados al TMR0 pueden provenir de los pulsos aplicados al pin T0CKI o de la
seal de reloj interna (Fosc/4), lo que le permite actuar de dos formas diferentes.

Contador de los impulsos que le llegan al pin T0CKI


Temporizador de tiempos

La configuracin como temporizador o contador se realiza mediante el bit T0CS del registro
OPTION.

(T0IF)

TMR0 COMO CONTADOR


Cuando el TMR0 trabaja como contador se le introducen los impulsos desde el exterior por el pin
RA4/T0CKI (TMR0 External Clock Input). Su misin es contar el nmero de acontecimientos
externos representados por impulsos que se aplican al pin T0CKI.
El tipo de flanco activo se elige mediante el bit T0SE del registro OPTION: (Para un PIC16F84A)
Si T0SE = 1; El flanco activo es descendente.
Si T0SE = 0; El flanco activo es ascendente.

TMR0 COMO TEMPORIZADOR


Cuando el TMR0 trabaja como temporizador cuenta los impulsos de Fosc/4 (Fosc=Frecuencia de
oscilacin).Se usa para determinar intervalos de tiempo
concretos. Estos impulsos tienen una duracin conocida de
41
ciclo mquina=
un ciclo mquina que es cuatro veces el periodo de la seal
4 MHz
de reloj. Para una frecuencia de reloj igual a 4MHz el TMR0
incrementa cada 1us.
Cuando se trata de un contador ascendente el TMR0 debe
ser cargador con el valor de los impulsos que se desean
contar restados de 256 que es el valor de desbordamiento.

ciclo mquina=1us

Es decir si el registro TMR0 es


cargado con 200 (TMR0 = 200)
despus de 1us el nuevo valor del
TMR0=201, 1us despus TMR0
=202 y as sucesivamente hasta
desbordarse. Al desbordarse el
flag T0IF se pone a 1 y podremos
decir que ha transcurrido un

Diagrama de bloques el TIMER0


DIVISOR DE FRECUENCIA (PREESCALER)
A veces es necesario controlar tiempos largos y aumentar la duracin de los impulsos que el
incrementan el registro TMR0. Para cubrir esta necesidad se dispone de un circuito programable
llamado Divisor de frecuencia o preescaler que divide la frecuencia utilizada por diversos rangos
para poder conseguir temporizaciones ms largas
En realidad casi todos los microcontroladores actuales disponen de ms de un Temporizador
En el caso del microcontrolador PIC16F84A dispone de dos temporizadores

TMR0, que acta como temporizador principal.

WATCHDOG (perro guardin), que vigila que el programa no se cuelgue, para ello cada
cierto tiempo Comprueba que el programa est ejecutndose normalmente de no ser as
reinicializa todo el sistema.

Los microcontroladores PIC ms avanzados como son PIC16F877A, PIC18FXX2, PIC18F4550


disponen de cuatro a ms temporizadores incluyendo el watchdog. (TIMER0, TIMER1, TIMER2,
TIMER3).
En el caso del PIC16F84A, el preescaler puede aplicarse a uno de los dos temporizadores, al
TMR0 o al watchdog. Cuando se asigna al TMR0 los impulsos pasan primero por el divisor de
frecuencia y una vez aumentada su duracin se aplican al TMR0.

Esto es relativamente sencillo,


pongamos un ejemplo:
Supongamos que
seleccionamos un preescaler de
1:8 y se lo asignamos al
TIMER0, que nos quiere decir
esto que cada 8 impulsos (8us
empleando un cristal de 4 MHz),
el registro TMR0 incrementar
en 1. Recuerda que
anteriormente incrementaba
cada 1us utilizando un cristal de
4MHz ya que no tena asignado
el preescaler. En conclusin el

INTERRUPCIN PRODUCIDA POR EL TIMER0


Para autorizar la interrupcin por desbordamiento del TMR0 los bits T0IE y GIE del registro
INTCON deben establecerse a 1. En estas condiciones cuando el temporizador TMR0 se
desborda activa el flag T0IF del registro INTCON produciendo una interrupcin.
Ahora veamos unos ejemplos:
Interrupcin del TMR0 como temporizador, para el clculo del tiempo se emplear la siguiente
formula
Temporizacin=TCM*Preescaler*(256-CargaTMR0)
Temporizacin = tiempo deseado
TCM = periodo de un ciclo maquina = 4 Tosc (ejm: Para 4MHz TCM=1us)
Preescaler = Rango de divisor de frecuencia elegido
(256-CargaTMR0) = # total de impulsos a contar antes de desbordarse el TMR0
Ejemplo con un PIC16F877A
int contador;
void interrupt isr (void)

//Rutina de interrupcin se interrumpira cada 20ms

{ contador++;
if(contador>4){
PORTDbits.RD0=!PORTDbits.RD0;
contador=0;
}
INTCONbits.T0IF=0;
TMR0=99;}

void main(void) {
TRISD=0;
PORTD=0;
INTCON=0;
OPTION_REGbits.PS0=1;
OPTION_REGbits.PS1=1;
OPTION_REGbits.PS2=1;
OPTION_REGbits.PSA=0;
OPTION_REGbits.T0CS=0;
OPTION_REGbits.T0SE=0;
INTCONbits.T0IE=1;
INTCONbits.T0IF=0;
INTCONbits.GIE=1;
TMR0=99;
while(1);
}

Potrebbero piacerti anche