viernes, 15 de noviembre de 2019

LABORATORIO NRO. 12

MICROCONTROLADORES

Laboratorio Nº 12

Manejo del Timer 

y las Interrupciones

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


2. COMPETENCIA ESPECÍFICA DE LA SESIÓN:
 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.
3. CONTENIDOS A TRATAR: 
Interrupciones.
● Timer cero.

4. RESULTADOS:

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

5. MARCO TEÓRICO:

INTERRUPCIONES:
Las interrupciones con el PIC son eventos que hacen que el programa principal se detenga, para que el microcontrolador PIC se dedique ha realizar otras tareas, mientras no ocurra una interrupción el microcontrolador solo realizará las tareas indicadas dentro del programa principal.
Para habilitar el uso de las interrupciones con el PIC se utiliza el registro INTCON, cada microntrolador PIC tiene su registro INTCON, algunos tendrán más de uno, es necesario revisar su hoja de datos para verificar para que se utilizan cada uno de sus bits, pero lo que si es común en ellos es el bit7 o bit GIE.


El siguiente es el registro INTCON para el PIC16F877A:

TEMPORIZADOR:
Un temporizador contador PIC es un registro que aumenta su valor en una unidad con cada 4 ciclos de reloj al cual se encuentre funcionando el microcontrolador PIC, si por ejemplo la frecuencia del oscilador es de 20MHz, entonces  el ciclo de trabajo del microcontrolador PIC será de 50ns, por lo que el temporizador contador PIC aumentará  su  valor de uno en uno en cada 50 nanosegundo; por ejemplo cuando el temporizador aumenta su valor en 10 unidades habrán transcurrido 0,5us.
El temporizador contador PIC puede producir interrupciones.

Los microcontroladores PIC suelen tener varios temporizadores, como ejemplo se utilizará el PIC16F877A, el cual tiene 3 temporizadores que son llamados timer0, timer1 y timer2, el tiempo que tarda el temporizador contador PIC en aumentar su valor de unidad en unidad, se puede modificar por programa mediante el uso de prescalers, siendo de esta manera mucho mas provechosos; dependiendo del modelo de microcontrolador PIC utilizado, no todos los temporizadores pueden ser utilizados como temporizador y también como contador.


El temporizador contador PIC puede aumentar sus valores de 0 a 255 si es de 8 bits como el timer0, o de 0 a 65535 si es de 16 bits como el timer1, cada vez que estos registros alcanzan su máximo valor se reinician, volviendo a contar desde su valor mínimo hasta su máximo, ademas pueden ser programados para provocar interrupciones.
Para el uso del temporizador contador PIC se cuenta además con un grupo de registros mediante los cuales se puede lo puede configurar de acuerdo a las necesidades que se tengan.

INTERRUPTOR TIMER 0:
Mediante la interrupción timer0 PIC se puede detener el programa  principal con el cual este trabajando el microcontrolador PIC, para indicarle al microcontrolador que se dedique a realizar otras tareas, al finalizar la interrupción timer0 PIC, se seguirá con el programa principal desde donde fue interrumpido.
Del registro INTCON se pondrá su bit7 GIE a 1 para habilitar el uso de las interrupciones, su bit5 TMR0IE se pondrá a 1 para habilitar el uso de la interrupción timer0 PIC por desborde, su bit2 TMR0IF es la bandera que detecta que se ha producido la interrupción del  timer0 por desborde y se tendrá que poner a 0 para que haga la detección, cuando ocurre la interrupción este bit se pone automáticamente a 1, y para seguir detectando mas interrupciones externas en al rutina de atención a las interrupciones se tendrá que poner nuevamente a 0 este bit.

Del registro OPTION_REG se pone a 0 su bit5 T0CS para indicarle al PIC que se utilizará el timer0 como temporizador, el bit4 se pone a 0 ya que este se usa cuando el timer0 es utilizado como contador, mediante su bit3 PSA=0 se indica a quien será asignado el prescaler, y con sus bits PS2:PS0 se indica de cuanto será el prescaler.


6. TAREA GUIADA 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:


   #include <16f877a.h>             // Incluimos archivo con PIC a utilizar
#device adc=8                    // Utilizamos 8 bits de RESOLUCIÓN 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_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=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)
      {
      ++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);
    }
}
      
  



7. TAREA A SER EVALUADA:
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 en 1 MINUTO y el pulsador E0, incrementa. 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)”

     
#include <16f877a.h>             // Incluimos archivo con PIC a utilizar
#device adc=8                    // Utilizamos 8 bits de RESOLUCIÓN 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_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 i=0,z=0;
int enclave=0;
int habilitador=0;

void BIP()
{
  FOR (i=0;i<=100;++i)
  {
    output_high(PIN_E1);    // Pone a "1" el pin E1 (envía 5 voltios)
    delay_ms(1);
    output_low(PIN_E1);     // Pone a "0" el pin E1
    delay_ms(1);
  } 
}

#int_TIMER0                      // FUNCION DE INTERRUPCION POR
void TIMER(VOID)                 // DESBORDAMIENTO DEL TIMER 0
{
  IF (!input(PIN_D0))
      {
         minutos++;
         while (!input(PIN_D0))     // Rutina ANTIRREBOTE por software
         {}
      }
  IF(!input(PIN_E0)& (segundos<55))
      {
         segundos = segundos + 5;
         while (!input(PIN_E0))     // Rutina ANTIRREBOTE por software
         {}
         IF(segundos>=55)
         {
            segundos=59;
         }
      }
 
  IF(!input(PIN_D1))
  {
  habilitador=!habilitador;
  }
   if(habilitador==1){
   ++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 && enclave==0)
      {
       minutos=0;
       segundos=0;
       FOR (z=0;z<=2;z++)
       {
        BIP();
        delay_ms(500);
       }
        enclave=1;
        disable_interrupts (INT_TIMER0);
      }
    }
    set_timer0 (61);              //reinicar cuenta desde 61
}

void main ()
{
   lcd_init () ; // Inicializamos pantalla LCD
   minutos = 00;
   segundos = 00;
   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);
    }
}

8. EVIDENCIA DE TRABAJO EN LABORATORIO:



Link del video: https://youtu.be/zLBit0xiogc

9. OBSERVACIONES:
  • Se mostraba en el LCD valores como 256, 128 entre otros; sucediendo cuando se realizó las condiciones dentro del bucle void main y cuando superaba el valor escrito en la programación al no tener un límite.
  • Es importante tener habilitado la interrupción global, ya que si no está activada y la específica si, no se dará su ejecución correcta, debido a que la global tiene control sobre toda interrupción.
10. CONCLUSIONES:
  • La interrupción de Timer0 trabaja con un registro de valor de 256 (0-255), el cuál es configurable para que se obtengan tiempo más aproximados al que se estima o requiera.
  • El set timer (61) toma ese valor del registro de 256 para iniciar la cuenta desde 61 hasta 255, por medio de este conteo progresivo y cíclico se obtuvo el valor de las centésimas, que al ir cumpliéndose cada ciclo incrementaba los segundos y progresivamente los minutos.
  • Se llama interrupción a aquello que hace cambiar la dirección de la atención (en este caso del microcontrolador PIC), así sea sea por un tiempo mínimo, se les emplea cuando se requiere ejecutar una acción prioritaria.
  • Se puede realizar tanto un conteo ascendente como descendente, siendo la diferencia en los segundos y minutos; las centésimas continuarán su cuenta normal (ascendente) al completar su cíclo en el conteo ascendente incrementará un segundo, pero en caso del descendente disminuirá en uno. Para los minutos, cada vez que los segundos tengan el valor de 59 su valor incrementa en uno y cuando llegase a 0 disminuirá.
  • Las interrupciones citadas se pueden habilitar y deshabilitar cuando se requiera, por ende es necesario saber en que momento se debe cambiar de estado.
  • Se puede introducir valores prestablecidos para mostrar en la pantalla LCD, antes de la citación de la reserva de espacios para cada valor.

No hay comentarios:

Publicar un comentario