lunes, 6 de mayo de 2019


MICROCONTROLADORES

LABORATORIO N° 07

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.

  1. CONTENIDOS A TRATAR
        Interrupciones
        Timer cero.
      IV.     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.

Timers:


Un timer no es más que un contador cuya entrada está conectada al reloj del sistema. De hecho, la mayoría de los timers 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 TIMERS con interrupciones (timer)
Tras verificar que los TIMERS funcionan pasemos a usarlos en combinación con las interrupciones para poder establecer tareas a intervalos regulares. Por descontado, para poder usar interrupciones tenemos que habilitar las interrupciones globales y la interrupción del TMR0 en particular (aunque esto también se puede en la función OpenTimer con la máscara TIMER_INT_ON/OFF. Como vimos en el tutorial de interrupciones es conveniente trabajar con macros para no tener que recordar que bits habilitaban que interrupciones.
Ciertos timers 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).

Consideremos el modo 8 bits (sin divisor) y arranquemos con un valor 156 en TMR0L. Necesitaremos 100 ciclos (256-156) para rebosar el contador y provocar la interrupción. Al cabo de 100 x 0.2 usec = 20 usec se producirá la primera interrupción.


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.



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)
      

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

-Al presionar pulsador en D0, incrementar SEGUNDOS. el temporizador aún no debe estar contando el tiempo. (sirve para configurar tiempo de cuenta).

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


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

CODIGO 

#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); 
     }

}






OBSERVACIONES
  El registro TMR0 del timer0 en el PIC está formado por 8 bits por lo que se puede contar desde 0 hasta 255.
- Para generar los segundos, minutos y centésimas, debemos usar 3 variables de tipo entero  
 Si queremos saber el tiempo de un segundo real debemos usar el timer 0 el cual es de 8 bits
-  Si queremos 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


CONCLUSIONES

-Se concluye que los Timer para los PICs tiene una amplia gama de aplicaciones en la práctica. Sólo unos pocos programas no lo utilizan de alguna forma. Es muy conveniente y fácil de utilizar en programas o subrutinas para generar pulsos de duración arbitraria, en medir tiempo o en contar los pulsos externos (eventos) casi sin limitaciones.

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.

1 comentario: