Documentos de Académico
Documentos de Profesional
Documentos de Cultura
INTERRUPCIONES Y
TEMPORIZADORES
TEMA 2
(PIC16F84) CAUSAS DE INTERRUPCIÓN
1. Activación del pin RB0/INT
2. Desbordamiento del TMR0
3. Cambio de estado de una de los 4 pines de más peso
(RB7:RB4) del puerto B
4. Finalización de la escritura en la EEPROM de datos
REGISTRO INTCON
Microcontroladores II
INTERRUCCIONES PIC16F87X
PIE1 PIR1
PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE
PIE2 PIR2
--- 0 --- EEIE BCLIE -- -- CCP2IE
Microcontroladores II
REGISTRO PIE1
R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE
Bit 7 Bit 0
………………
Vector de Interrupción 0004h
0005h
Página 0
07FFh
0800h
Página 1
0FFFh
1000h
Página 2
17FFh
1FFh
Página 3
INTERRUPCIONES EN LENGUAJE C
Ventajas de usar las directivas de interrupciones
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.
También genera el código para salvar al principio
y restituir al final el contexto (salvar y restaurar el
entorno), y borrará el flag que se activó con la
interrupción.
El programador debe seguir encargándose
únicamente de habilitar las interrupciones y establecer
las sentencias que se ejecutarán en cada función de las
interrupciones deseadas a ejecutarse.
Las directivas #INT_xxxx
Indican que la función que aparece a
continuación corresponde al tratamiento de una
interrupción (no tiene ni necesita parámetros):
Para los PICs 16F877 hay 14 posibles directivas:
Microcontroladores II
#INT_RTCC Desborde del TMR0 TOIF
#INT_RB Cambio en RB<4:7> RBIF
#INT_EXT Cambio en RB0 INTF
#INT_AD Fin de conversión A/D ADIF
#INT_TBE Fin de transmisión USART TXIF
#INT_RDA Dato recibido en USART RCIF
#INT_TIMER1 Desborde del TMR1 TMR1IF
#INT_TIMER2 Desborde del TMR2 TMR2IF
#INT_CCP1 Captura/Comparación en CCP1 CCP1IF
#INT_CCP2 Captura/Comparación en CCP2 CCP2IF
#INT_SSP Envío/Recepción de dato serie síncrono SSPIF
#INT_PSP Dato entrante en puerto esclavo paralelo PSPIF
#INT_BUSCOL Colisión de bus I2C BCLIF
#INT_EEPROM Fin de escritura EEPROM EEIF
INTERRUPCIONES EN LENGUAJE C
La directiva #INT_DEFAULT
Indica que la función que viene a
continuación será llamada si se dispara una
interrupción y ninguno de los flags está activo.
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.
GLOBAL equivale a GIE=PEIE=1 y debe activarse de
forma independiente. El resto activarán la máscara
correspondiente.
Microcontroladores II
FUNCIONES PARA GESTIÓN DE
INTERRUPCIONES
enable_interrupts (nivel);
nivel es una constante definida en el 16F877.h y genera el
código necesario para activar las máscaras necesarias.
Etiquetas de nivel definidas para el 16F877:
GLOBAL INT_RTCC INT_RB
INT_EXT INT_AD INT_TBE
INT_RDA INT_TIMER1 INT_TIMER2
INT_CCP1 INT_CCP2 INT_SSP
INT_PSP INT_BUSCOL INT_EEPROM
La máscara global (hace a GIE=1) debe activarse de
manera independiente. Las otras activan la máscara particular y
el PEIE si es necesario.
disable_interrupts(nivel);
Hace la acción contraria a la función anterior, poniendo a
0 las máscaras relacionadas con la interrupción indicada.
Microcontroladores II
INTERRUPCIÓN EXTERIOR POR RB0
Es una interrupción clásica en la mayoría de
los PICs. Permite generar una interrupción por
cambio de nivel en la entrada RB0.
La directiva que se utiliza es #INT_EXT y se
debe acompañar de las siguientes funciones:
ext_int_edge(H_TO_L);
La interrupción es activada por flanco de
bajada (antiva el flag INTF).
ext_int_edge(L_TO_H);
La interrupción es activada por flanco de
subida (activa el flag INTF).
Microcontroladores II
EJEMPLO 1. INTERRUPCIÓN POR RB0/INT
#INT_EXT
ext_isr( ){
…..//aquí se colocan las sentencias que se
…..//desean ejecutar durante esta interrupción.
}
void main ( ){
enable_interrupts(INT_EXT); //Activa INTE
ext_int_edge(H_TO_L); //Flanco de bajada
enable_interrupts(GLOBAL); //Habilita GIE
while (TRUE){
}
}.
Microcontroladores II
EJEMPLO 2. Active dos leds de forma intermitente cada 1 segundo. Si
presiona RB0/INT, los leds se activan a razón de 250 ms de manera
intermitente hasta que se presione RA0 para volver a su estado
normal.
#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use fast_IO(B)
#use fast_IO(D)
#use fast_IO(A)
#INT_EXT
void ext_interm( ){ //función de interrupción por RB0/INT:
while (TRUE){
if (input(PIN_A0)==0)
{break;}
delay_ms(250);
output_toggle(PIN_D0);
output_toggle(PIN_D1);
}
}
Microcontroladores II
Continuación Ejemplo 2.
void main(){
set_tris_b(0x01);
set_tris_d(0);
set_tris_a(0x01);
output_d(0);
port_b_pullups(true);
enable_interrupts(int_ext);
ext_int_edge(H_to_L);
enable_interrupts(global);
while(TRUE){
output_high(PIN_D0);
output_low(PIN_D1);
delay_ms(1000);
output_low(PIN_D0);
output_high(PIN_D1);
delay_ms(1000);}
}
Microcontroladores II
TIMER 0
00H
(28 – N10)
00H
Si el TMR0 se carga con un valor, FFH
éste comenzará a contar desde el
valor cargado hasta que se desborda Valor cargado
(cuando pasa a 00H) En el TMR0
00H
Microcontroladores II
CÁLCULOS CON EL TMR0
• Cuando se carga en el registro TMR0 un valor XXH, él mismo
contará: (FFH – XXH) impulsos y el tiempo que tarda en
hacerlo viene dado por la expresión:
Temporización= 4 * TOSC * Valor Real TMR0 * Rango del
divisor de Frecuencia
Valor Real TMR0 = (28 – N10) = (256 – N10)
N10= Valor a cargar en el TMR0
Microcontroladores II
OTROS EJEMPLOS
• Se desea saber: ¿Qué valor debemos cargar en el TMR0, si deseamos
obtener una temporización de 10,24 ms, utilizando un preescaler de 128
y un cristal XT?
Solución:
Temporizac ión 10,24ms
(256 – N ) =
10 = = 80
4 TOSC Rgodivisor 4 0.25s 128
(256 – N10) = 80, despejando N10 = (256 – 80) = 176, el valor que debemos
cargar en el TMR0 es 176, para que éste cuente desde 176 hasta 256.
Microcontroladores II
CONTINUACIÓN EJEMPLO ANTERIOR
• Nota: En este ejercicio resuelto, usted puede darse cuenta de que no hay
un solo resultado para los ejercicios, pero lo que si debe cumplirse es que
sea cualquiera que sean los valores que se tomen para los cálculos, estos
deben de estar cercanos a la respuesta que se espera del temporizador
que esté diseñando.
Microcontroladores II
TIMER0 EN LENGUAJE C
La función para configurar el TIMER0 es:
setup_timer_0 (modo);
Donde modo está definido en el fichero de cabecera y afecta
a los bits 5:0 del OPTION_REG:
setup_timer_0 (modo); OPTION_REG (81h)
RTCC_INTERNAL 00000000
RTCC_EXT_L_TO_H 00100000
RTCC_EXT_H_TO_L 00110000
RTCC_DIV_1 00001000
RTCC_DIV_2 00000000
RTCC_DIV_4 00000001
RTCC_DIV_8 00000010
RTCC_DIV_16 00000011
RTCC_DIV_32 00000100
RTCC_DIV_64 00000101
RTCC_DIV_128 00000110
RTCC_DIV_256 00000111
TIMER0 EN LENGUAJE C
Los distintos modos se pueden agrupar mediante el
empleo del símbolo |. Ejemplo:
setup_timer_0 (RTCC_DIV_2 | RTCC_EXT_L_TO_H);
El compilador C suministre una serie de funciones
para leer o escribir en el TIMER0. Para escribir un valor en el
registro:
set_timer0(valor);
valor : es un entero de 8 bits.
Para leer el valor actual del registro:
valor= get_timer0 ( );
valor: entero de 8 bits.
Microcontroladores II
Ejemplo 3. Generar una señal cuadrada de 1 kHz
utilizando la interrupción del TIMER0
#INCLUDE <16F877.h>
#FUSES XT,NOWDT,NOPROTECT,NOLVP
#USE DELAY(CLOCK=4000000)
#USE fast_io(B)
#INT_RTCC
RTCC_isr(){ NOTA: El compilador se encarga
output_toggle(PIN_B7); al entrar en la interrupción de
set_timer0(198);} inhabilitar las interrupciones y
void main(){ al salir de borrar los flags, por lo
set_tris_B(0x00);
output_low(PIN_B7); que no es necesario hacerlo por
setup_timer_0(RTCC_DIV_8); programa
set_timer0(198);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while (TRUE){
}
}
Microcontroladores II
TIMER 1
Características básicas:
1. Es de 16 bits.
2. Puede actuar como temporizador o como contador
bit (TMR1CS).
3. Se puede leer y escribir en los registros TMR1H,
TMR1L.
4. Puede pararse o habilitarse mediante el bit TMR1ON.
5. Tiene un pre-divisor programable por software.
6. El oscilador de bajo consumo está situado entre los
pines T1OSI (entrada) y T1OSO (salida).
Microcontroladores II
TIMER 1
7. Al desbordase (FFFFh -> 0000h) produce la interrupción
TMR1:
• El bit de interrupción del timer1 es TMR1IF
[Registro PIR1(0)].
• Puede deshabilitarse mediante TMR1IE
[Registro PIE1(0)].
8. La frecuencia de oscilación máx. es 200kHz. No se apaga
durante SLEEP.
9. Monitorea tiempo entre transiciones de una señal en pin de
entrada.
10. Controla con precisión el tiempo de transición de pin de
salida.
11. Sirve para contar eventos externos y generar interrupciones
cuando ha ocurrido un número deseado.
Microcontroladores II
DIAGRAMA DE BLOQUE TIMER 1
Microcontroladores II
REGISTROS ASOCIADOS AL TIMER 1
Microcontroladores II
T1CON
• Bit 7-6: No implementados: Se lee como “0”
• Bit 5-4: TlCKPS1:T1CKPS0: bit de selección del preescaler de la señal de reloj delTIMER1:
11 = valor del preescaler 1:8
10 = valor del preescaler 1:4
01 = valor del preescaler 1:2
00 = valor del preescaler 1: 1
• Bit 3: T1OSCEN: bit de habilitación del oscilador del TIMER1. Cuando se emplea un oscilador
externo, hay que poner este bit a 1. El TMR1 puede trabajar a una frecuencia totalmente
independiente de la del sistema.
1 = Habilita el oscilador
0 = Deshabilita el oscilador
Nota: El oscilador y la resistencia se desconectan para reducir el consumo
• Bit 2: #TlSYNC: bit de control de sincronización de la señal de entrada.
Con TMR1CS = 1
1= No sincroniza la entrada de reloj externa
0 = Sincroniza la entrada de reloj externa
Con TMR1CS = 0
En esta condición se ignora. El TIMER1 utiliza el reloj interno cuando TMRICS=0
• Bit 1 TMR1CS: bit de selección de la fuente de reloj del TIMER1
1 = Reloj externo por el pin RC0/T1OSO/T1CK1 (flanco ascendente)
0 = Reloj interno (FOSC/4)
• Bit 0: TMR1ON: TIMER1 activo. Hace entrar o no en funcionamiento el TIMER1.
1 = Habilita el TIMER1
0 = Deshabilita el TIMER1 Microcontroladores II
CÁLCULOS PARA EL TIMER 1
Ejercicio:
¿Cuál es el máximo valor de temporización que se
puede alcanzar con el TIMER 1?
Microcontroladores II
• Realice un programa para que se genere una interrupción
cada 0,5 segundos, utilizando un XT.
INICIO RSI
SLEEP
RETFIE
FIN
Microcontroladores II
TIMER1 EN LENGUAJE C
La función para configurar el TIMER0 es:
setup_timer_1 (modo);
Donde modo está definido en el fichero de cabecera y afecta
a los bits 5:0 del T1CON:
setup_timer_1 (modo); T1CON (10h)
T1_DISABLED 00000000
T1_INTERNAL 10000101
T1_EXTERNAL 10000111
T1_EXTERNAL_SYNC 10000011
T1_CLK_OUT 00001000
T1_DIV_BY_1 00000000
T1_DIV_BY_2 00010000
T1_DIV_BY_4 00100000
T1_DIV_BY_8 00110000
Microcontroladores II
TIMER1 EN LENGUAJE C
Los distintos modos se pueden agrupar mediante el
empleo del símbolo |. Ejemplo:
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2);
El compilador C suministre una serie de funciones
para leer o escribir en el TIMER1. Para escribir un valor en el
registro:
set_timer1(valor);
valor : es un entero de 16 bits.
Para leer el valor actual del registro:
valor= get_timer1 ( );
valor: entero de 16 bits.
Microcontroladores II
Ejemplo 4. Generar una interrupción cada un segundo
utilizando el TIMER1
• Para generar un retardo de 1 segundo, se deben generar dos
veces 0,5 segundos, motivado a que directamente el TIMER1
no puede alcanzarlo.
• Paso 1. Cálculos: Aplicando las fórmulas del TIMER1:
Solución: Nota: este término debe ser
menor o igual a 65536. Es por ello
que se utilizó el predivisor de 8.
Temporizac ión 0,5s
(65536 – N16) = = = 62500
4 TOSC Rgodivisor 4 0.25s 8
(65536 – N16) = y despejando N16 = (65536 – 62500) = 3036,
por lo tanto el valor que debemos cargar en el TMR1 es 3036,
para que éste cuente desde 3036 hasta 65536, generándonos
la temporización de 0,5 s.
Microcontroladores II
EJEMPLO 4. Generar una interrupción cada un
segundo utilizando el TIMER1
#INCLUDE <16F877.h>
#FUSES XT,NOWDT,NOPROTECT,NOLVP
#USE DELAY(CLOCK=4000000)
#USE fast_io(B)
int1 cont=0;
#INT_TIMER1
temp1_isr(void){
if (cont==1) output_toggle(PIN_B0);
set_timer1(3036);
cont++;}
void main(){
set_tris_B(0x00);
output_low(PIN_B0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(3036);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while (TRUE){
}
} Microcontroladores II
Otra forma de realizar el ejemplo 4:
• Mediante la espera de desborde del TIMER1:
#INCLUDE <16F877.h>
#FUSES XT,NOWDT,NOPROTECT,NOLVP
#USE DELAY(CLOCK=4000000)
#USE fast_io(B)
temp1s( ){
int cont=0;
output_toggle(PIN_B0);
while (cont<2)
{ //para contar dos tiempos de 0,5 s.
set_timer1 (3036);
while (get_timer1()>=3036);
cont++;}
}
void main(){
set_tris_B(0x00);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
while (1){
temp1s();} //llama a función de temporización
} Microcontroladores II
TIMER 2
Características básicas:
1. Es de 8 bits.
2. Se puede leer y escribir en los registros TMR2.
3. Puede pararse o habilitarse mediante el bit TMR2ON.
4. Tiene un pre-divisor y un post-divisor programable
por software
5. Sólo tiene modo temporizador.
6. Posee un registro (PR2) que ajusta el momento de
desborde.
7. PR2(Registro de 8 bits) que puede leerse y escribirse
PR2 con el cual compara su valor:
– Si los valores de TMR2 y PR2 se igualan, TMR2 pasa a cero.
8. Maneja el período de una señal PWM
Microcontroladores II
TIMER 2
9. Al igualarse TMR2 y PR2 se produce la interrupción
TMR2:
1. El bit de interrupción del timer2 es TMR2IF
(Registro PIR1(1)).
2. Hay un post-divisor a la salida del comparador.
10. Los registros de pre-divisor y post-divisor se limpian
al:
1. Escribir en TMR2.
2. Escribir en el registro T2CON.
3. Cualquier tipo de RESET.
11. TMR2 no se limpia al escribir en T2CON.
Microcontroladores II
REGISTROS ASOCIADOS AL TIMER2
Microcontroladores II
DIAGRAMA DE BLOQUE DEL TIMER 2
Microcontroladores II
T2CON
• Bit 7: No implementado: Se lee como 0
• Bit 6-3:TOUTPS3:TOUTPS0: bit de selección del rango del divisor del
– Postescaler para el TIMER2:
0000 Divisor del postescaler 1:1
0001 Divisor del postescaler 1:2
0010 Divisor del postescaler 1:3
0011 Divisor del postescaler 1:4
0100 Divisor del postescaler 1:5
0101 Divisor del postescaler 1:6
0110 Divisor del postescaler 1:7
0111 Divisor del postescaler 1:8
1000 Divisor del postescaler 1:9
1001 Divisor del postescaler 1:10
1010 Divisor del postescaler 1:11
1011 Divisor del postescaler 1:12
1100 Divisor del postescaler 1:13
1101 Divisor del postescaler 1:14
1110 Divisor del postescaler 1:15
1111 Divisor del postescaler 1:16
• Bit 2: TMR2ON: bit de activación del TIMER2
1 = habilita el funcionamiento del TIMER2
0 = Inhibe el funcionamiento del TIMER2
• Bit 1-0:T2CKPS1:T2CKPS0 Selección del rango de divisor del Preescaler del TIMER 2
0 0 Divisor del Preescaler 1:1
0 1 Divisor del Preescaler 1:4
1 X Divisor del Preescaler 1:16
Microcontroladores II
CÁLCULOS TIMER2
Temporización= 4 * TOSC * Valor PR2 * Rango del
prescaler Timer2 * Rango del postcaler Timer2
Ejercicio
Determine, cuanto tarda en desbordarse el TMR2, si se
utiliza un XT, con un prescaler = 4 y un postcaler = 10,
considerando que PR2 = D’200’. Cargue el TMR2 con
00H
Microcontroladores II
TIMER2 EN LENGUAJE C
La configuración del TIMER2 en el compilador de
C se realiza con la función:
setup_timer_2(modo , periodo , postcaler);
donde:
período es un valor entero de 8 bits (0-255) que se
carga en el registro PR2.
postcaler es el valor del postcaler (1 a 16). Afecta a los
bits 6:3 del registro T2CON
modo afecta a los bits 2:0 del registro T2CON.
Microcontroladores II
TIMER2 EN LENGUAJE C
setup_timer_2(modo , periodo , postcaler); T2CON(12h)
T2_DISABLED 00000000
T2_DIV_BY_1 00000100
T2_DIV_BY_4 00000101
T2_DIV_BY_16 00000110
Para escribir un valor en el registro:
set_timer2(valor);
valor : es un entero de 8 bits.
Para leer el valor actual del registro:
valor= get_timer2( );
valor: entero de 8 bits. Microcontroladores II
Ejemplo 5. Generar una señal de 1 kHz
utilizando interrupción con el TIMER2
Microcontroladores II
#INCLUDE <16F877.h>
#FUSES XT,NOWDT,NOPROTECT,NOLVP
#USE DELAY(CLOCK=4000000)
#USE fast_io(B)
int1 cont=0;
#INT_TIMER2
void temp2_isr(void){
output_toggle(PIN_B0);
set_timer2(11);}
void main(){
set_tris_B(0x00);
output_low(PIN_B0);
setup_timer_2(T2_DIV_BY_4 , 124 , 1);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while (TRUE){
}
}
Microcontroladores II