TERMOSTATO DIGITAL CON PANTALLA LCD
FASE 3: Manejo del Timer y las interrupciones
1. COMPETENCIAS ESPECIFICAS
- Conocer el funcionamiento y la configuración de las interrupciones.
- Conocer el funcionamiento y la configuración del Timer cero.
- Aplicar estos conocimientos en la realización de un cronometro.
2. MARCO TEÓRICO
INTERRUPCIONES EN UN PIC
Las interrupciones son señales recibidas por el sistema de un PIC para decirle que debe interrumpir la ejecución actual y pasar a tratar un código o señal especifica para tratar esta situación
Interrupciones del pic 16F876A
Las interrupciones permiten la interrupción del programa a cualquier suceso ya sea de tipo interno o externa, la interrupción que se da en el PIC salta a la dirección del vector (0004h) de interrupción y ejecuta el ciclo
Cuando la rutina del ciclo de interrupción finaliza (RETFIE) el programa retorna al punto donde se interrumpió el programa
El PIC 16F876A tiene un único vector de interrupción y todas las interrupciones que ocurran provocan un salto que se dirija ese vector, ademas para este suceso la rutina de manejo de la interrupción debe reconocer que evento o efecto interrumpió el programa para ejecutar la rutina correcta.
El PIC posee registros con flags de interrupción los cuales les permiten identificar el evento.
Para la interrupciones que se puedna dar en el PIC 16F876A existen tres tipos de registros de interupcion:
- Registros de interrupción numero 5
- Registros de interrupción numero 6
Las interrupciones se dan tmabien en los CCS pero en este caso las interrupciones se dan asi:
- Interrupciones en CCS CCS dispone de directivas para el manejo de interrupciones por ejemplo #int_XXXX. La directiva especifica que la función que la sigue es la función de interrupción correspondiente
Las funciones en el CCS 8 se ven validadas en una pantalla en la cual se ven reflejados los diferen tipos de conectores es decir los valores de recepción del PIC 16F876A
En el CCS se anexan diversas funciones para la interrupción:
El compilador incluye funciones para facilitar el manejo de interrupciones en C.
- enable_interrupts(level) Activa las interrupciones indicadas por level.
- disable_interrupts(level) desactiva las interrupciones indicadas por level.
- clear_interrupts(level) Borra el flag de interrupción indicado
De esta especificación obtenemos un variable que debemos reconocer el LEVEL
- Level es una constante definida en el fichero de cabecera (#include) genera el código necesario para activar las interrupciones correspondientes modificando los registros ITCON, PIE1 y PIE2. Cuando se activa alguna interrupción es necesario activar global mente las interrupciones.
Cada registro de level esta definido de la siguiente forma
´Para estos registros se muestra un ejemplo general del código de registro
TEMPORIZADOR
En este caso los temporizadores etarana referidos en base al PIC 16F876A:
El PIC 16F876A dispone de tres temporizadores/contadores:
- Timer 0: 8 bits.
- Timer 1: 16 bits.
- Timer 2: 16 bits.
Pueden funcionar como contadores de flancos externos o como temporizador (contador de ciclos máquina)y disponen de prescaler para ampliar el tamaño de la cuenta (hasta x256), ademas un temporizador posee una Cuenta de 16 bits en dos registros de 8 bits:
- TMR1H (parte alta)
- TMR1L (parte baja)
Los registros de cuenta se pueden leer y escribir ademas surge un interrupción por desbordamiento de FFFFh a 0000h. Controlado por el registro T1CON.
Funcionamiento como:
- Temporizador (incrementa cada ciclo máquina).
- Contador síncrono.
- Contador asíncrono
En la siguiente imagen podemos ver el diagrama de bloques del timer
El registro de control del timer es el siguiente:
El timmer en C proporciona diversas funciones de configuración de los temporizadores el set up, el get , el set se veran cada uno de ellos a continuacion:
- setup_timer_X (modo) Programa el modo de funcionamiento del timer X
- get_timerX () Lee el valor de la cuenta.
- set_timerX (valor) Escribe valor en los registros de cuenta.
3. EVIDENCIAS DENTRO DE LABORATORIO
1. Simule
y pruebe en el entrenador el programa mostrado de acuerdo al circuito y código
siguiente. Asegúrese que el LCD esté conectado al PUERTO D mediante
interruptores rojos debajo del mismo:
#include <16f877a.h> // Incluimos archivo con PIC a utilizar
#device adc=8 // Utilizamos 8 bits de RESOLUCION de lectura
#use delay (clock=20M) // Indicamos al compilador que trabajaremos a 20Mhz
#fuses HS, NOPROTECT, NOWDT // Configuración básica de los fusibles
#define LCD_ENABLE_PIN PIN_D3 //Definimos los pines a ser utilizados por la
#define LCD_RS_PIN PIN_D2 //pantalla LCD
#define LCD_RW_PIN PIN_C7
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c> // Incluimos librería para manejar Pantalla LCD
int centesimas=0,segundos=0,minutos=2;
#int_TIMER0 // FUNCION DE INTERRUPCION POR
void TIMER(VOID) // DESBORDAMIENTO DEL TIMER 0
{
++centesimas; // incrementar una centésima
if (centesimas>99)
{
++segundos; // si llegamos a 100, incrementar un segundo
centesimas=0;
}
if (segundos>59)
LABORATORIO MICROCONTROLADORES
Nro.
Página 4 de 4
{
++minutos; // si llegamos a 60, incrementar un minuto
segundos=0;
}
if (minutos==3) // si llegamos a 3 minutos, hacer alguna acción
{
minutos=0;
disable_interrupts (INT_TIMER0); //habilita interrupcion de timer0
// agregar cualquier otra acción necesaria.
}
set_timer0 (61); //reinicar cuenta desde 61
}
void main ()
{
lcd_init () ; // Inicializamos pantalla LCD
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //configuracion del timer0
set_timer0 (61); // interrupción cada centésima
enable_interrupts (INT_TIMER0); //habilita interrupcion de timer0
enable_interrupts (GLOBAL); //todas las interrupciones activadas
printf (lcd_putc, "\f***CRONOMETRO***") ; // Mandamos mensaje por única vez
WHILE (true)
{
lcd_gotoxy(2,2);
Printf(lcd_putc,"Tiempo %02u:%02u",minutos, segundos);
}
}
2. A
partir del código mostrado, realice los cambios necesarios para realizar un programa
que CUENTE EN FORMA DESCENDENTE, (temporizador regresivo), bajo las siguientes condiciones:
a. Al
presionar pulsador en A5, incrementar MINUTOS. el temporizador aún no debe
estar contando el tiempo. (sirve para configurar tiempo de cuenta).
b. Al
presionar pulsador en D0, iniciar CUENTA REGRESIVA desde los minutos
previamente configurados.
c. Si
la cuenta llega a 00:00, congelar la cuenta y sonar BIP 3 veces.
3. Para
verificar que una variable de tiempo (digamos “minutos”) llegó a cero, hacerlo
con la instrucción “if (minutos==-1)”
EVIDENCIA REALIZADA :
Programación realizado en CCS COMPILER:
#include <16f877a.h> // Incluimos archivo con PIC a
utilizar
#use delay (clock=20M) // Indicamos al compilador que
trabajaremos a 20Mhz
#fuses HS, NOPROTECT, NOWDT // Configuración básica de los fusibles
#define LCD_ENABLE_PIN PIN_D3
//Definimos los pines a ser utilizados por la
#define LCD_RS_PIN PIN_D2 //pantalla LCD
#define LCD_RW_PIN PIN_A0
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c> // Incluimos librería para
manejar Pantalla LCD
int centesimas=0,segundos=0,minutos=0;
INT encendido=0;
void BIP();
#int_TIMER0 // FUNCION DE INTERRUPCION
POR
void TIMER(VOID) // DESBORDAMIENTO DEL TIMER 0
{
++centesimas; //
incrementar una centésima
if
(centesimas>99)
{
--segundos; // si
llegamos a 100, incrementar un segundo
centesimas=0;
}
if
(segundos==-1)
{
--minutos; // si
llegamos a 60, incrementar un minuto
segundos=59;
}
if
(minutos==-1) // si
llegamos a 3 minutos, hacer alguna acción
{
minutos=0;
disable_interrupts (INT_TIMER0);
//habilita interrupcion de timer0
// agregar cualquier otra acción necesaria.
}
set_timer0 (61);
//reinicar cuenta desde 61
}
void main ()
{
lcd_init () ; // Inicializamos pantalla LCD
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); //configuracion del timer0
set_timer0 (61); // interrupción
cada centésima
enable_interrupts (INT_TIMER0); //habilita interrupcion de timer0
enable_interrupts (GLOBAL); //todas las interrupciones
activadas
printf (lcd_putc, "\f***Temporizador***") ; // Mandamos mensaje por única vez
WHILE (true)
{
lcd_gotoxy(2,2);
Printf(lcd_putc,"Tiempo %02u:%02u",minutos, segundos);
IF(!input(PIN_A5)) // AUMENTA 1 MIN
{
minutos = minutos + 1;
delay_ms(500);
}
IF(!input(PIN_E2))
{
disable_interrupts (INT_TIMER0);
//CUENTA REGRESIVA DESACTIVADOR
delay_ms(500);
}
IF(!input(PIN_D0))
//CUENTA REGRESIVA
{
enable_interrupts (INT_TIMER0);
encendido =1;
}
IF
(minutos==0 && segundos==0 && encendido==1)
{
delay_ms(100);
BIP();
delay_ms(500);
BIP();
delay_ms(500);
BIP();
delay_ms(500);
minutos=0;
segundos=0;
encendido =0;
}
}
}
void BIP()
{
int i; // Declaración de VARIABLE LOCAL
FOR (i=0;i<=50;++i)
{
output_high(PIN_E1); // Pone a "1" el pin E1 (envía 5 voltios)
delay_ms(1); // "Congela el tiempo" durante 1ms
output_low(PIN_E1); // Pone a "0" el pin E1
delay_ms(1); // "Congela el tiempo" durante 1ms
}
}
SIMULACIÓN :
4. OBSERVACIONES
4. OBSERVACIONES
·
Usamos el timer0 el cual es de 8 bits, el
cual nos dará el tiempo de un segundo real.
·
Usamos 3 variables de tipo entero para
generar los segundos, minutos y centésimas.
· Para parar el cronómetro, usamos la sentencia: “disable_interrups”
y el pulsador en el pin A5 el cual también aumenta los minutos y para iniciarlo
de nuevo: “enable_interrups” y el pulsador en el pin D0.
5. CONCLUSIONES
·
En este laboratorio
aprendimos a usar las interrupciones para programar un temporizador.
·
Para el caso de
realizar un cronómetro con cuenta hacia atrás. Fue necesario asignar a la
variable segundos 59 y terminarla en -1, igualmente con minutos.
·
También creamos una
función la cual llamamos BIP para emitir 3 pitidos cuando el temporizador
llegue a cero. Se tuvo que crear una variable llamada encendido la cual con una
función AND con los minutos y los segundos en cero se active estopara que al
iniciar el contador no suenen los bips.
6. INTEGRANTES:
*Benito Mendoza Gabriela
*Valdivia Apaza Percy
Faltan evidencias. Sólo hay marco teórico
ResponderBorrar