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)
#INT_xxxx
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_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:
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)
{
}