Anda di halaman 1dari 27

Interrupciones

Las interrupciones permiten a cualquier


evento de tipo exterior como interior
interrumpir la ejecucin de un programa
principal en cualquier momento.

En el momento de ejecutarse la
interrupcin, el pic hace un salto a la rutina
de interrupcin previamente definida, una
vez concluida, el pic regresa a la posicin
de memoria de donde se realizo la llamada.
Las fuentes de interrupcin dependen
del pic en cuestin, la familia de los
pic 16F6xx tienen 7 interrupciones y
la familia de los pic 16F8XX tienen 13
y 14 interrupciones.
Los pic de gama baja y media
(familias 12F y 16F) tienen un solo
vector de interrupcion ubicado en la
direcin 04H de la memoria, mientras
que los pic de gama alta (18F) tienen
dos y de distinta prioridad, es decir
alta y baja que se encuentran en la
posicin 08H y 18H de la memoria.
Registro INTCON (Interrupciones)

Bit GIE.- Interrupciones Globales


Bit PEIE.- Interrupcin por perifricos
Bit T0IE.- Interrupcin por Timer0
Bit INTE.- Interrupcin Externa por RB0
Bit RBIE.- Interrupcin por cambio en
RB4-RB7
Registro INTCON (Flags)

Bit T0IF.- Ocurri desbordamiento


Bit INTF.- Ocurri la interrupcin
Bit RBIF.- Ocurri la interrupcin
Interrupciones en C
En el compilador, el manejo de
interrupciones es tratado mediante la
siguiente instruccin:

#INT_xxxx

Donde las x representan el nombre


de la interrupcin y no necesitan mas
parmetros.
Interrupciones en C
Algunas de las interrupciones ms bsicas y
que usaremos son las siguientes:

#INT_EXT.- Interrupcin Externa por RB0


#INT_TIMER0.- Interrupcin del Timer0
#INT_RTCC.- Interrupcin del Timer0
#INT_RB.- Interrupcin por cambio en RB4-
RB7
#INT_RC.- Interrupcin por cambio en RB4-
RB7
#INT_RDA.- Interrupcin por puerto Serial
Interrupciones en C
Si se utilizan las directivas de
interrupcin, el compilador genera el
cdigo necesario para ejecutar la
funcin que le sigue a la directiva,
adems genera el cdigo necesario
para saltar al vector de interrupcin y
tambin para borrar los flags
involucrados en las interrupciones.
Funciones de manejo de
Interrupciones
enable_interrupts(nivel);
Donde nivel se refiere a la
configuracin del modo de
interrupcin a trabajar y afecta a los
bits del registro INTCON a nivel
ensamblador.

disable_interrupts(nivel);
Realiza la funcin contraria, inhabilita
las interrupciones
Interrupcin Externa RB0
Es la interrupcin mas bsica, comn a la
mayora de los pic. La directiva a utilizar es
#INT_EXT y maneja las siguientes funciones para
su configuracin:

ext_int_edge(H_TO_L);
Activa la interrupcin por flanco de bajada (1 a
0)

ext_int_edge(L_TO_H);
Activa la interrupcin por flanco de subida (0 a 1)
Ejemplo 6
Encender y apagar un led por el pin
RB7 cada vez que se produzca un
cambio de nivel por RB0
#include <16F876.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 4000000)
#use fast_io(B)

int1 cambio=0;

#INT_EXT
ext_isr()
{
output_toggle(pin_B7);
}

void main()
{
set_tris_B(0x01);
output_low(PIN_B7);
port_b_pullups(TRUE);

enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);

while (1)
{
}
}
Ejemplo 7
Realice un programa que efecte un
corrimiento a la izquierda del bit 0 al
bit 3 del puerto D. Cuando ocurra un
cambio de nivel en RB4 a RB7 deber
apagar el conteo, encender el pin
RD4 por dos segundos y continuar el
corrimiento donde se quedo. Utilizar
interrupcin por cambio de nivel
#include <16F877a.h>
#fuses XT,NOWDT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use fast_io(b)
#use standard_io(d)

int datoRB; //almacena el ltimo dato


int led;

#INT_RB
void RB_isr()
{ //Funcin de interrupcin
datoRB=input_b();
output_d(0);
output_high(pin_d4);
delay_ms(2000);
output_low(pin_d4);
}
void main()
{
set_tris_b(0xf0);
output_d(0x00);
datoRB=input_b();
enable_interrupts(int_RB);
enable_interrupts(GLOBAL);
while(true)
{
led=1;
do{
output_d(led);
rotate_left(&led,1);
delay_ms(300);
}while(bit_test(led,4)==0);

datoRB=input_b();
}
}
Timer 0
El Timer0 es un contador de 8 bits
incrementado por hardware y
programable. La cuenta mxima es
de 255 y funciona en dos modos:

Contador por RA4 (cuenta pulsos


externos)
Temporizador (cuenta pulsos
internos)
El Timer0 funciona como un temporizador o contador, segn la
procedencia de la seal de reloj que recibe. Debemos sealar que
en ambos caso funciona de la misma forma, solo que el origen de
la seal de entrada cambia y determinara cual de las funciones
realizar.
En el caso que seal provenga del reloj interno de instrucciones
(fint), el Timer0 se utiliza para generar interrupciones
peridicas a travs de una cuenta programada, pues
conocemos la frecuencia de funcionamiento y en base al
valor cargado en el contador podemos temporizar
tiempos.
Por otra parte cuando la seal se genera en una fuente externa al
microcontrolador (fext), es especialmente til para contar el
nmero de pulsos que dicha seal genera en el tiempo ya
que cada pulso de dicha seal incrementa el TMR0.
Prescaler
Existe un circuito que permite modificar la
frecuencia del reloj de entrada del Timer0,
dividiendo esta y generando una nueva seal
de menor frecuencia a la salida que
funcionara como la seal de reloj de entrada
al registro TMR0 llamado prescaler, el cual es
es activado a travs de 4 bits en el registro
OPTION, permitiendo dividir la frecuencia de
una seal por 1, 2, 4, 8, 16, 32, 64, 128 o
256.
Clculo de temporizaciones
Supongamos que el mdulo Timer0
se alimenta con una seal de
frecuencia ftimer0 = fosc/4=fint. Por
lo tanto el tiempo de desbordamiento
del Timer 0 (Tretmr0) se calcula de la
siguiente manera:
Funciones del Timer0 en C
setup_timer_0(modo);
Donde modo indica la operacin del
timer 0
RTCC_INTERNAL RTCC_DIV_32
RTCC_EXT_H_TO_L RTCC_DIV_64
RTCC_EXT_L_TO_H RTCC_DIV_128
RTCC_DIV_1 RTCC_DIV_256
RTCC_DIV_2
RTCC_DIV_4
RTCC_DIV_8
RTCC_DIV_16
Los modos de trabajo se pueden
agrupar usando el smbolo | (or) de la
siguiente manera:
setup_timer_0(RTCC_DIV_2 |
RTCC_EXT_L_TO_H);
set_timer0(valor);
Valor entero de 8 bits que permite
cargar al timer para poder
desbordarse

valor= Get_timer0();
Valor es una variable de 8 bits que
permite obtener una lectura del
timer0
Ejemplo de Timer 0
Se genera una seal cuadrada de
periodo total de 1ms utilizando un
prescaler de 2, por lo que el
semiperiodo alto y bajo de la seal es
de 500 us
#include <16f877a.h>
#fuses XT,NOLVP,NOBROWNOUT,NOWDT

#use delay(clock=4M)

#use standard_io(b)

#INT_TIMER0
void interrupcion()
{
output_toggle(PIN_B3);
set_timer0(6);
}

void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(6);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);

for(;;)
{
}
}
Ejemplo 2 de Timer 0
Se calcula el timer0 para generar una
seal de periodo total de 1 seg, esto
se consigue realizando un contador
para poder aumentar el ciclo de
trabajo de la interrupcin. Se utiliza
un prescaler de 8
#include <16F877a.h>
#fuses XT,NOWDT,NOLVP
#use delay(clock=4000000)
#use standard_io(d)

int nint=250;
int salida=0xf0;

#INT_TIMER0
void TIMER0_isr()
{
set_timer0 (256-250);
--nint;
if(nint==0)
{
salida=~salida;
output_d(salida);
nint=250;
}
}

void main()
{
output_d(salida);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); //Configuracin timer0
set_timer0 (6); //Carga del timer0
enable_interrupts(INT_TIMER0); //Habilita interrupcin timer0
enable_interrupts(global);
while (true)
{
}

Anda mungkin juga menyukai