MANEJO DEL TIMER Y LAS INTERRUPCIONES

I. CAPACIDAD TERMINAL
Utilizar al microcontrolador en aplicaciones de control electrónico.
Desarrollar y ejecutar programas en un microcontrolador PIC
Programar y configurar interfaces básicas del microcontrolador.

II. COMPETENCIA ESPECIFICA DE LA SESION
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 cronómetro.

III. CONTENIDOS A TRATAR
Interrupciones
Timer cero.

IV. RESULTADOS
Diseñan y optimizan sistemas y procesos para cumplir con las condiciones establecidas y gestionando adecuadamente los recursos materiales y humanos.

V. MATERIALES Y EQUIPO
CCS Compiler instalado.
Entrenador de PICS
Pantalla LCD
PIC16F877A
Guía de Laboratorio. El trabajo se desarrolla de manera GRUPAL.
PC con Software de simulación.
VI. REPASO DEL LABORATORIO ANTERIOR
Herramientas de Programación en Hardware y Software

VII. FUNDAMENTO TEÓRICO
Manejo de las interrupciones en un PIC
Manejo y configuración del Timer
VIII. DESCRIPCIÓN Y FUNCIONAMIENTO DE LAS INTERRUPCIONES Y LOS TEMPORIZADORES DE UN PIC

INTERRUPCIONES:

El PIC 16F876A tiene un único vector de interrupción y todas las interrupciones que ocurran  provocan un salto que se dirija ese vector, 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.

Al finalizar la rutina del ciclo de interrupción  (RETFIE) el programa retorna al punto donde fue interrumpido

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 

El PIC  posee registros con flags  de interrupción los cuales les permiten  identificar el evento.

TEMPORIZADORES:

Un temporizador no es más que un contador cuya entrada está conectada al reloj del sistema. De hecho, la mayoría de estos pueden reconfigurarse como contadores. En ese caso, en lugar de contar pulsos de reloj cuentan los pulsos que llegan a un determinado pin.

Uso de Temporizadores con interrupciones :
Tras verificar que los Temporizadores funcionan pasemos a usarlos en combinación con las interrupciones para poder establecer tareas a intervalos regulares. 
Ciertos temporizadores están considerados periféricos, por lo que también tendríamos que habilitar las interrupciones periféricas, aunque no es el caso del TMR0.
El fundamento del proceso es sencillo. La interrupción del TMR0 se producirá cuando el contador del timer pase por cero (cada 256 o 65536 ciclos dependiendo de si estamos en 8 o 16 bits). La idea es arrancar con un valor del contador tal que en el tiempo deseado alcance el valor máximo (256 o 65536).



IX. TAREAS GUIADAS DENTRO DEL 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:






X. EVALUACIÓN

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 D0, incrementar SEGUNDOS. el temporizador aún no debe estar contando el tiempo. (sirve para configurar tiempo de cuenta).

b. Al presionar pulsador en D1, iniciar CUENTA REGRESIVA desde los minutos previamente configurados.

c. Si la cuenta llega a 00:00, congelar la cuenta y sonar BIP 3 veces.

Para verificar que una variable de tiempo (digamos “minutos”) llegó a cero, hacerlo con la instrucción “if (minutos==-1)”
CÓDIGO USADO

#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_D0))                  
   {
   segundos = segundos + 1;
   delay_ms(500);
   }
   IF(!input(PIN_E0))                  
   {
   minutos = minutos + 1;
   delay_ms(500);
   }
   IF(!input(PIN_E2))
   {
   disable_interrupts (INT_TIMER0);   
   delay_ms(500);
   }
   IF(!input(PIN_D1))              
   {
   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; 
    FOR (i=0;i<=50;++i)
    {
    output_high(PIN_E1); 
    delay_ms(1); 
    output_low(PIN_E1); 
    delay_ms(1); 
     }
}

XI. OBSERVACIONES
-Se usaron tres variables tipo entero para poder generar los segundos, minutos y centésimas.

-Aplicamos enable y disable para poder darle orden al funcionamiento de nuestro cronometro.

-Podemos saber cual es el tiempo de un segundo real para esto debemos usar el temporizador 0 el cual es de 8 bits.

-Se tuvo que ingrsar el VOID bip para considerar los sonidos al momento de que el cronometro acabe.

-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.

XII. CONCLUSIONES

-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.

- Aprendimos el uso correcto de las interrupciones para programar un temporizador.

- El registro TMR0 del timer0 en el PIC está formado por 8 bits por lo que se puede contar desde 0 hasta 255.

Comentarios