Você está na página 1de 37

MICROCONTROLADOR PIC18FXX50

INTERRUPCIONES
MG. ING. JAVIER CAMILO POMA PALACIOS

PAMPAS -2017
INTERRUPCIONES
Características generales
Las interrupciones son
desviaciones del flujo de
control del programa
originadas asíncronamente por
diversos sucesos que no se
hallan bajo la supervisión de
las instrucciones.

Dichos sucesos pueden ser


externos al sistema, como la
generación de un flanco o nivel
activo en un pin del
microcontrolador, o bien
internos, como el
desbordamiento de un
contador. Mg. J. Camilo Poma P.
INTERRUPCIONES
DESCRIPCIÓN
Se detiene la ejecución del programa en curso, se salva la dirección
actual del CP en la Pila y se carga el CP con una dirección, en el
caso de una interrupción es una dirección “reservada” de la
memoria de código, llamada Vector de interrupción, en la gama alta
existen dos direcciones: 0x08 prioridad alta y 0x18 prioridad baja.

Esta fuente de interrupción es sumamente importante para atender


acontecimientos externos en tiempo real.

Por ejemplo cuando ocurre la interrupción por activar el pin


RB0/INT, se hace una petición de interrupción en forma automática.

Este método es más eficaz que la técnica de sondeo ya que el


microcontrolador no perderá tiempo preguntando a la línea de
entrada para leer su estado, sino que únicamente atenderá al
periférico cuando éste se lo pida mediante la solicitud de
interrupción.
Mg. J. Camilo Poma P.
INTERRUPCIONES
Interrupciones en C
En el compilador C, la directiva habitual en el manejo de las
interrupciones es: #INT_xxxx.
Ejm: #INT_EXT2
//Para config. se utiliza: ext_int_edge (source, edge)
//source, constante 0, 1, 2 o 3 en PIC18XX50 y por defecto es 0.
//edge is a constant H_TO_L or L_TO_H

//Configura interrupción por el pin RB2


enable_interrupts(INT_EXT2);
ext_int_edge(2, H_TO_L );
bit_set(IRQ_TR); //Pin de interrupción como entrada
enable_interrupts(GLOBAL);

Existen directivas más que pueden ser usadas, tanto para esta familia
como para otras. Para mayor información les sugiero revisar el
datasheet del microcontrolador.
Mg. J. Camilo Poma P.
INTERRUPCIONES
Interrupciones en C
Constantes usadas en ENABLE_ INTERRUPTS()/DISABLE_INTERRUPTS() son:

#GLOBAL Interrupción global


#PERIPH Interrupción de periférico
#INT_RTCC RTCC Timer 0 overflow (using RTCC name)
#INT_TIMER0 TIMER0 Timer 0 overflow (using TIMER0 name)
#INT_TIMER1 TIMER1 Timer 1 overflow
#INT_TIMER2 TIMER2 Timer 2 overflow
#INT_TIMER3 TIMER3 Timer 3 overflow
#INT_EXT EXT External interrupt
#INT_EXT_L2H
#INT_EXT_H2L
#INT_EXT1 EXT1 External interrupt #1
#INT_EXT1_L2H
#INT_EXT1_H2L
#INT_EXT2 EXT2 External interrupt #2
#INT_EXT2_L2H
#INT_EXT2_H2L
Mg. J. Camilo Poma P.
INTERRUPCIONES
Interrupciones en C
Constantes usadas en ENABLE_ INTERRUPTS()/DISABLE_INTERRUPTS() son:

#INT_RB RB Port B any change on B4-B7


#INT_AD AD Conversión AD completada
#INT_RDA RDA RS232 receive data available
#INT_TBE TBE RS232 transmit buffer empty
#INT_SSP SSP SPI or I2C activity
#INT_CCP1 CCP1 Unidad de captura 1, comparación y PWM
#INT_CCP2 CCP2 Unidad de captura 1, comparación y PWM
#INT_BUSCOL BUSCOL Colisión de bus
#INT_LOWVOLT LOWVOLT Low voltage detected
#INT_COMP COMP Comparator event
#INT_EEPROM EEPROM Escritura EEPROM finalizada
#INT_OSCF OSCF System oscilator failed
#INT_USB USB Universal Serial Bus activity

Mg. J. Camilo Poma P.


INTERRUPCIÓN (EXT)
#INT_EXT (Interrupcion por RB0)
En el caso de la interrupción externa RB0/INT de los
PIC18FXXX se tiene la siguiente directiva.
#INT_EXT – flanco en el pin RB0. Se activa la bandera
INTF.
La directiva #INT_Global indica que la función que va a
continuación sustituye todas las acciones que inserta el
compilador al aceptarse una interrupción. Sólo se
ejecuta lo que vaya en dicha función.
Si se utilizan las directivas de interrupción, el compilador
genera el código necesario para saltar a la función que
va tras esta directiva en el momento de la interrupción.

Mg. J. Camilo Poma P.


INTERRUPCIÓN (EXT)
#INT_EXT (Interrupcion por RB0)
Además, genera el código para salvar al principio y restituir al
final el contexto, y también borrará la bandera que se activó
con la interrupción. El programador, solo debe encargarse
. de habilitar las interrupciones.
Existe también otra función adicional destinada a configurar el
flanco activo que genera la interrupción externa (en RB0).
 ext_int_edge (0, H_TO_L);
equivale a INTEDG=0. Selecciona el flanco de bajada para
activar la bandera INTF ó
 ext_int_edge (0, L_TO_H);
equivale a INTEDG=1. Selecciona el flanco de subida para
activar la bandera INTF.
enable_interrupts (INT_EXT); Habilita la interrupción
enable_interrupts (GLOBAL); Habilita la interrupción ó
disable_Interrupts (GLOBAL); Deshabilita la interrupción
Mg. J. Camilo Poma P.
EJEMPLO DE APLICACIÓN
Ejemplo: Encender y apagar, consecutivamente, un LED conectado en el pin RB7 a
través de una resistencia de 1K, cuando se produzca un cambio de nivel en la pin
RB0.
#include <18F2550.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock=4000000)
#use fast_io(b)

#INT_EXT // Atención a interrupción por cambio en RB0


void ext_isr()
{ // Función de interrupción
output_toggle(pin_B7);
}

void main()
{set_tris_B(0x01); // B0 como entrada, B7 como salida
output_low(PIN_B7); // Apaga LED
port_b_pullups(TRUE); // Pull-up para RB0
enable_interrupts(int_ext); // Habilita int. RB0
ext_int_edge(0,L_TO_H); // por flanco de subida
enable_interrupts(GLOBAL); // Habilita int. general
WHILE (TRUE);} // Bucle infinito de espera
Mg. J. Camilo Poma P.
INTERRUPCIÓN (RB)
#INT_RB (Interrupción por cambio en RB7-RB4)
Los pines <RB7:RB4> del PORTB producen una sola
interrupción por cambio de su estado.

Para activar la interrupción por cambio de estado en los


pines <RB7:RB4> los bits RBIE y GIE del registro INTCON
deben estar a “1”, en estas condiciones cuando se produce
un cambio de nivel en cualquiera de las líneas RB7 a RB4
se activa la bandera RBIF del registro INTCON.

Entonces en la subrutina de interrupción se deberá hacer


el tratamiento respectivo para identificar cual de los pines
se activó.
Mg. J. Camilo Poma P.
INTERRUPCIÓN (RB)
#INT_RB (Interrupción por cambio en RB7-RB4)

En lenguaje C, la interrupción se activa con


enable_interrupts(INT_RB) y la subrutina de tratamiento de la
interrupción se llama con #INT_RB.

La directiva #INT_RB, debe acompañar de las siguientes


funciones.

EXT_INT_EDGE(H_TO_L); Cambio de estado de alto a bajo.


ó EXT_INT_EDGE(L_TO_H); Cambio de estado de bajo a alto.
ENABLE_INTERRUPTS (INT_RB); Habilita la interrupción
ENABLE_INTERRUPTS (GLOBAL); Habilita la interrupción de
forma global.

Mg. J. Camilo Poma P.


INTERRUPCIÓN (RB)
#INT_RB (Interrupción por cambio en RB7-RB4)
En caso que se estén atendiendo varias interrupciones, el
compilador C, también tiene la directiva #priority que sirve para
fijar la prioridad de las interrupciones, así, las interrupciones más
importantes están listadas al principio.

Por ejemplo:
#priority ext, rb; //la interrupción RB0/INT será atendida
antes de RB.

Ejercicio: Se conectan 4 pulsadores a RB4, RB5, RB6 y RB7 y


una LCD al puerto A y C. Se realiza un contador automático que
dependa de la detección de cambio de estado en cada pin RBx,
de acuerdo al siguiente detalle: +5, -3, -7, +10. Se inicia el
contador con el valor de 50.
Mg. J. Camilo Poma P.
MICROCONTROLADOR PIC18FXX50

TIMERS/CONTADOR
MG. ING. JAVIER CAMILO POMA PALACIOS

PAMPAS -2017
TEMPORIZADOR/CONTADOR
Características generales
Una de las labores más habituales en los
programas de control de dispositivos es
determinar intervalos concretos de tiempo, el
encargado de realizar esta función, recibe el
nombre de temporizador (timer).

También es frecuente contar los pulsos que se


producen en el exterior del sistema, y el
elemento destinado a este fin se llama
contador.

Mg. J. Camilo Poma P.


TEMPORIZADOR/CONTADOR
Características generales
Timer0(TMR0): como temporizador/contador de 8 bits/16
bits. Pre-escalar de 8 bits programable e interrupción por
desbordamiento; para 8 bits: TMR0L ó para 16 bits:
TMR0L y TMR0H.
Timer1(TMR1): como temporizador/contador de 16 bits
(TMR1H:TMR1L). Dispone de un oscilador propio que
puede funcionar como: Señal de reloj del temporizador
1. Pre-escalar de 3 bits programable e interrupción por
desbordamiento. Puede incrementarse en modo sleep
de forma externa por un cristal o clock.

Mg. J. Camilo Poma P.


TEMPORIZADOR/CONTADOR
Características generales
Temporizador TMR2 de 8 bits. Registro de periodo PR2.
Pre-escalar de 2 bits programable (1:1, 1:4, 1:16). Post-
escalar de 4 bits (1 :1...1 :16). Interrupción por igualdad
entre TMR2 y PR2. Se puede utilizar junto con los
módulos CCP y ECCP. Se puede utilizar como señal de
reloj del módulo MSSP en modo SP.
Temporizador TMR3: temporizador/contador de 16 bits.
Dispone de varias opciones de señal de reloj en el modo
temporizador: Oscilador principal con o sin pre-escalar.
Oscilador del temporizador 1 con o sin pre-escalar. Pre-
escalar de 3 bits programable.
Mg. J. Camilo Poma P.
TIMER 0 (RTCC)
Características generales
TMR0 es un contador/temporizador de 8/16 bits.
Se puede leer y escribir.
Puede trabajar con reloj interno o con señal de reloj
externa.
Selección de flanco en el reloj externo.
Predivisor de frecuencia de reloj programable por
software de 8 bits.
Interrupción opcional por desbordamiento.
Temporizador: Cuenta los pulsos internos del reloj.
Contador: Cuenta los eventos externos, a través
del pin RA4/T0CKI.
Mg. J. Camilo Poma P.
TMR0 TEMPORIZADOR/CONTADOR

TMRO

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR
DIAGRAMA DE BLOQUE PROGRAMACIÓN DE TMR0

Se puede insertar un preescaler, es decir un divisor de frecuencia


programable que puede dividir por 2, 4, 8, 16, 32, 64, 128 o 256.
El tiempo de desbordamiento del timer 0, para 8 bits se calcula según
la siguiente ecuación:

Ejemplo 1: Generar una interrupción de 20 ms. Para evitar los rebotes de unas teclas.
Se utiliza un cristal de 4 MHz ¿Cuanto debe cargarse en TMR0 si el predivisor esta en
256? TMR0_1 Mg. J. Camilo Poma P.
TMR0 TEMPORIZADOR/CONTADOR
Como no se obtiene tiempos muy cercanos podemos cambiar por ejemplo
predivisor = 8.
Comprobar el retardo utilizando el osciloscopio del simulador Proteus o similar.

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR
El tiempo empleado en una temporización se puede calcular a partir de un
ciclo de instrucción (es decir una instrucción por cada 0.5
microsegundo, si se trabaja con un cristal HS de 8 MHz), también
necesitamos el valor del Divisor de Frecuencia (el que seleccionamos con
los bits PS2, PS1 y PS0), y finalmente con el complemento del valor
cargado en TMR0 (es decir 65536-TMR0), la ecuación del tiempo de
desbordamiento para 16 bits es:

T =(4/fosc)*Divisor de Frecuencia*(65536-TMR0)

Se desea una temporización de 100 ms (100 milisegundos), con un HS


de 8 MHz., y que además seleccionamos como Divisor de frecuencia
256 (es decir PS2,PS1,PS0 = 1,1,1). La pregunta, sería ¿Cuál es el
valor que se debe cargar en TMR0?
Mg. J. Camilo Poma P.
TMR0 TEMPORIZADOR/CONTADOR
Despejando: 65536-TMR0 = T ∕ ((4 ∕ Fosc)* Div. de Frec.)
Reemplazando en la ecua. tenemos: 65536-TMR0 = 100000
us/((4/8MHz)*256), entonces tenemos:
65536-TMR0 = 781.25
Eso significa que en la diferencia deberemos cargar: 65536-
781= TMR0, luego TMR0=64755.
A partir de allí el TMR0 contará los 781 ciclos que faltan para
desbordarse y producir la interrupción, y el tiempo que tardará
en hacerlo es 100ms aproximadamente.
Se debe comprobar el retardo utilizando el osciloscopio del
Simulador Proteus o similar.

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR
TIMER 0 en C
La función para configurar el timer 0 es:
setup_timer_0 (modo); donde modo puede ser:

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR
Los distintos modos lo podemos agrupar con | de la siguiente
manera:
Ejm:
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16);
setup_timer_0(T0_INTERNAL | T0_DIV_16); //Similar al anterior. TMR0 en 16
bits, reloj interno-temporizador, div 16.
setup_timer_0(T0_8_BIT | T0_INTERNAL | T0_DIV_256); //TMR0 en 8 bits,
reloj interno-temporizador, div 256.
setup_timer_0(T0_EXT_L_TO_H | T0_DIV_128); //TMR0 en 16 bits, reloj
externo-contador, div 128.

Para cargar un valor en el registro TMR0 se utiliza la instrucción:


set_timer0 (valor); donde valor es un entero de 8 o 16 bits.
Para leer un valor actual del registro se utiliza la instrucción:
VALOR=get_timer0(); donde VALOR es entero de 8 o 16 bits.
Mg. J. Camilo Poma P.
TMR0 TEMPORIZADOR/CONTADOR
EJERCICIO 1 (TMR0_2):
Desarrollar un programa que encienda y apague secuencialmente
un LED cada 300ms.
Para la temporización se empleará la interrupción del TMR0.
 Calculamos la carga del TMR0 para 10 ms con un divisor de
frecuencia de 8 (Prescaler de 8), con 256 no es tan exacto.
 Entonces usaremos un registro auxiliar con un contenido de
30 para obtener los 300ms.
 Cargar registro auxiliar con 30 para obtener los 300ms de
temporización.
 Bucle infinito en el programa principal.

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR

Para la subrutina de interrupción, tenemos:

 Recarga del TMR0 con su valor correspondiente


para obtener una temporización de 10ms.
 Disminuir (o aumentar) el Contador Auxiliar
hasta obtener los 300ms.
 Verificar el estado del LED. Si está apagado lo
enciende y viceversa.
 Mantener en ese estado (prendido o pagado)
durante 300ms.
 Bucle indefinido en el programa.

Mg. J. Camilo Poma P.


TMR0 TEMPORIZADOR/CONTADOR
EJERCICIO 2 (TMR0_3):
Desarrollar un programa que encienda y apague secuencialmente
un primer LED cada 250ms y otro LED cada 5s.
Para la temporización se empleará la interrupción del TMR0.
 Calculamos la carga del TMR0 para 250 ms con un divisor de
frecuencia de 256 (Prescaler de 256).
 Entonces TMR0 se carga con 64559 para obtener los 250ms.
 Cargar registro auxiliar con 20 para obtener los 5s de
temporización.
 Bucle infinito.

Mg. J. Camilo Poma P.


TMR1 TEMPORIZADOR/CONTADOR
Características:
Trabaja con 16 bits ( 2 registros de 8 bits los cuales
son: TMR1H y TMR1L).
Ambos registros se pueden leer y escribir.
El timer 1 puede operar en uno de los siguientes
modos:
 Temporizador
 Contador Síncrono
 Contador Asíncrono

Mg. J. Camilo Poma P.


TMR1 TEMPORIZADOR/CONTADOR
Se puede insertar un preescaler, es decir un divisor de
frecuencia programable que puede dividir por 1, 2, 4, 8.
El tiempo de desbordamiento del timer 1 se calcula según
la siguiente ecuación:

Mg. J. Camilo Poma P.


TMR1 TEMPORIZADOR/CONTADOR
TIMER 1 EN C
La función para configurar el timer 1 es:
setup_timer_1(modo); donde modo:

Para cargar un valor en el registro TMR1:


set_timer1(valor); donde valor: es un entero de 16 bits.

Para leer un valor actual del registro: get_timer1();


Mg. J. Camilo Poma P.
EJEMPLOS DE APLICACIÓN
Ejemplo: Generar una función que permita realizar retardos de 1
segundo empleando el TIMER1.
#include <18F2550.h>
#fuses XT,MCLR,PUT,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOPBADEN
#use delay (clock=4000000)
#use standard_io(b)
Int1 cont=0;
#INT_TIMER1 // Interrupción TIMER1
void tempis (void) // Función
{if (cont==1) output_toggle(PIN_B1); //Cada 2 interrupciones de 0.5s
set_timer1(3036); //Recarga del TMR1
cont++;}
void main()
{setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(3036); // recarga del TMR1
enable_interrupts(INT_TIMER1) ; // habilita interrupción timerl
Enable_interrupts(global); //habilita interrupción general

WHILE (TRUE);}
Mg. J. Camilo Poma P.
TMR 2 TEMPORIZADOR/CONTADOR
Características generales
El timer 2 es un módulo temporizador que tiene las
siguientes características:

Registro de 8 bits de temporización.


Solo en modo temporizador.
Interrupción por desbordamiento en FFH a 00H.
Registro de periodo de 8 bits.
Ambos registros se pueden leer y escribir.
Preescaler programable (1, 4 y 16).
Postscaler programable (1 a 16).

Mg. J. Camilo Poma P.


TMR 2 TEMPORIZADOR/CONTADOR
TIMER 2 en C
La función para configurar el timer 2 es:
setup_timer_2(modo, periodo, postscaler);
donde modo:

periodo: entero de 8 bits


postscaler: valor de de 1 a 16.

T = (4/Fosc)*Pre. Div.* (256 -TMR2)* Post. Div.


Para cargar un valor en el registro TMR2: set_timer2(valor);
Donde valor es un entero de 8 bits.
Para leer un valor actual del registro: get_timer2();
Mg. J. Camilo Poma P.
TMR 2 TEMPORIZADOR/CONTADOR
Configurando el tiempo de desborde(Overflow) para que se ejecute el código de la interrupción:
Nos interesa esta parte del código para configurarlo:
setup_timer_2(T2_DIV_BY_1,0,1)

El prescaler puede ser 1, 4 o 16 y tiene como objetivo dividir la frecuencia del oscilador.
El registro PR2 que indica el momento de desborde del timer, es un numero que varia de 0 a
255.
El postscaler indica cuantas veces se debe desbordar el timer para ejecutar la interrupción y
ejecutar el código correspondiente para posteriormente resetear la cuenta, varia entre 1 a 16.
Resumiendo las configuraciones del Timer 2:
1. Se divide la frecuencia mediante el prescaler.
2. Se establece un desborde(overflow) cuando se llena la cuenta del registro PR2.
3. El postscaler nos indica cuantas veces debe suceder el desborde para que se ejecute
la interrupción.

La formula para calcular el valor de uno de los parametros del Timer 2 es:
PR2 = [([Tiempodeseado/(4/fosc)])/(Prescaler*Postscaler)] - 1

Los valores máximos para prescaler es 16, para PR2 es 255 y para postscaler 16.
Por lo tanto el Timer 2 nos queda: setup_timer_2(T2_DIV_BY_16,255,16);
Mg. J. Camilo Poma P.
TMR 2 TEMPORIZADOR/CONTADOR
Ejemplo 2: Realizar un programa para realizar una temporización de
50ms con pre y post divisor de frecuencia de 16, por interrupción del
TMR2 . La temporización debe ser visualizado en un led conectado al
pin RB2.

Solución:
Como 50ms esta cerca de la temporización máxima que es 65.536ms
ocupamos los valores máximos permitidos para prescaler y postscaler.
Así mediante la formula calculamos PR2:

PR2 = [([50ms/(4/4E6)])/16*16)] - 1

PR2=194.3125  Como debe ser un valor entero entonces lo


aproximamos a 195 (mejor que sobre a que falte) lo que nos da una
temporización exacta de 50.176ms (un valor muy muy cercano!)

Por lo tanto el Timer 2 nos queda:


setup_timer_2 (T2_DIV_BY_16,195,16);
Mg. J. Camilo Poma P.
TMR3 TEMPORIZADOR/CONTADOR
Características generales

TMR3 es un contador/temporizador de 16 bits.


Puede trabajar con reloj interno o con señal de reloj
externo.
Trabaja con 16 bits (2 registros de 8 bits los cuales son
TMR3H y TMR3L).
Ambos registros se pueden leer y escribir.
Interrupción por desbordamiento de FFFFH a 0000H.
Preescaler programable (1, 2, 4 y 8).

Mg. J. Camilo Poma P.