08 – Temporizador de 16 bits del PIC18F4550

Cuando se diseñan aplicaciones de control electrónico, es común encontrarse con la necesidad de incorporar tiempos de espera para los dispositivos “lentos” que se controlan ya que el microcontrolador es demasiado rápido. Por otra parte, los temporizadores son ideales para proveer bases de tiempo de alta precisión para la implementación de relojes de tiempo real.

El PIC18F4550 posee cuatro temporizadores: TIMER0 a TIMER3, al igual que los demás módulos especiales, cada uno de los temporizadores es controlado por un registro de configuración.

Temporizador Registro de control
TIMER0 T0CON
TIMER1 T1CON
TIMER2 T2CON
TIMER3 T3CON

En este post se describirá como configurar y utilizar el temporizador TIMER0, está información servirá como base para poder configurar los demás temporizadores ya que el procedimiento es similar.

El TIMER0 posee las siguientes características:

  • Modo de operación de 8 y 16 bits: El modo de operación de 8 y 16 bits determina la cantidad de conteos máxima que puede realizar el timer. Si es de 8 bits contará hasta 255, si es de 16 bits hasta 65535.
  • Registros de control de lectura y escritura.
  • Prescaler dedicado de 8 bits: el timer incrementa el valor del conteo cada Fosc / 4 pulsos de reloj. Para un microcontrolador que opera a 20Mhz, significa que el incremento se realiza 5 millones de veces en un segundo. Esta cantidad puede ser demasiado alta para ciertas aplicaciones en donde las bases de tiempo son bastante grandes. Para solucionar este inconveniente, se dispone del prescaler que es básicamente un divisor de frencuencia, la frecuencia se puede dividir entre: 2, 4, 8, 16, 32, 64, 128 y 256.
  • Fuente de reloj seleccionable (interna / externa).
  • Interrupción por desbordamiento: cada vez que el valor del conteo llega a su límite se genera un desbordamiento (overflow) que genera una interrupción interna que activa el bit TMR0IF del registro INTCON.

Librerías C18 para el manejo del módulo temporizador

Puede utilizarse la librería timers.h de C18 (hoy XC8) para facilitar la configuración del módulo temporizador, los métodos que proporciona son los siguientes:

timers

En la tabla, sustituimos la letra x al final del nombre de la función, por el número del timer con el cual estamos trabajando. Ej. OpentTimer0.

Para hacer funcionar el módulo de temporización, se requiere únicamente de OpenTimer y WriteTimer.

El método OpenTimer(), se utiliza para configurar el temporizador, definiendo:

  1. Activación de la interrupción: TIMER_INT_OFF, TIMER_INT_ON
  2. Modo de operación (8 , 16 bits): T0_8BIT, T0_16BIT
  3. Origen de la señal de reloj: T0_SOURCE_INT, T0_SOURCE_EXT
  4. Prescaler: T0_PS_1_1 1:1, T0_PS_1_2 1:2, T0_PS_1_4 1:4, T0_PS_1_8 1:8, T0_PS_1_16 1:16, T0_PS_1_32 1:32, T0_PS_1_64 1:64, T0_PS_1_128 1:128, T0_PS_1_256 1:256

El siguiente ejemplo muestra como configurar el método:

unsigned char Timer0Config;
Timer0Config = TIMER_INT_ON &T0_16BIT & T0_SOURCE_INT & T0_PS_1_25;
OpenTimer0(Timer0Config);
WriteTimer0(0x48E4);

Observe como se utiliza una variable tipo char Timer0Config para almacenar la configuración de timer0. Posteriormente el valor de la variable se pasa como argumento del método OpenTimer0. La configuración establecida se lee: Interrupción activada, modo de operación de 16 bits, señal de reloj interna y, prescaler de 1:256.

El método WriteTimerx, se utiliza para indicar (en formato hexadecimal) al temporizador la cantidad de conteos que debe realizar (de acuerdo a un intervalo de tiempo establecido) antes de activar la bandera de interrupción TMRxIF. Mediante la activación de TMRxIF, sabremos que ha transcurrido el tiempo correspondiente.

En este ejemplo, se desea un temporizador de:

  • Timer: 1 segundo
  • Fosc: 48MHZ

Procedimiento:

  1. Si Fosc es 48MHZ, para el módulo de temporización se divide por cuatro = 48MHZ / 4 = 12MHZ
  2. El período es 1 / 12000000 = 8.3333333×10-8 Seg
  3. Utilizando un prescaler de 1:256, el período es: 8.3333333×10-8 Seg x 256 = 2.133333×10-5 Seg
  4. Como el timer requerido es de 1 segundo, el ciclo de instrucción efectivo es: 1 seg / 2.133333×10-5 seg = 46,875
  5. Si el temporizador trabaja en modo 16 bits, la activación de la bandera de interrupción ocurrirá cada: 65,535 – 46,875 = 18,660 conteos.
  6. Se convierte este valor a hexadecimal 18,66010 = 48E416
  7. El valor 48E416 será el argumento del método WriteTimer(0x48E4) para que active la bandera de interrupción cada 1 segundo.

El código de aplicación propuesto es el siguiente:

#include <xc.h>
#include <plib/timers.h>

//Bits de configuración para Fosc = 48Mhz
#pragma config PLLDIV = 5, CPUDIV = OSC1_PLL2, USBDIV = 2
#pragma config FOSC = HSPLL_HS, FCMEN = OFF, IESO = OFF
#pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF
#pragma config WDT = OFF, WDTPS = 32768
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF
#pragma config STVREN = ON, LVP = OFF, ICPRT = OFF, XINST = OFF

#define _XTAL_FREQ 48000000
unsigned char Timer0Config;
void main()
{
TRISBbits.RB4 = 0; //RB4 es salida.
LATB4 = 1; //Poner RB4 4n uno.

Timer0Config = TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256;
OpenTimer0(Timer0Config);
WriteTimer0(0x48E4);

INTCONbits.TMR0IF = 0; //inicializar la bandera de interrupción

ei();

while(1)
{}
}

void interrupt TimerOverflow()
{
if(INTCONbits.TMR0IF == 1)
{
LATB4 = ~LATB4; //Cambiar el estado de RB4
INTCONbits.TMR0IF = 0;
WriteTimer0(0x48E4);
}

}

Como puede observarse, exactamente cada un segundo, se activará TMR0IF, indicando el desbordamiento del timer (interrupción), lo cual será utilizado para activar/desactivar un led conectado a RB4.

Conclusiones

Existen otros métodos para implementar timers. Sin embargo, se ha descrito este procedimiento ya que lo considero mas sencillo que los demás, aunque tiene como desventaja que no se profundiza en el funcionamiento del módulo, lo cual es esencial para aplicaciones mas complejas. A todo interesado en este tema lo invito a implementar su temporizador con estos valores de ejemplo y posteriormente  hacer modificaciones.

En el siguiente post, utilizaremos el timer2 para hacer funcionar el módulo PWM del PIC18F4550. Un saludo.

Nota importante: He recibido algunos comentarios de post anteriores respecto a que no les funcionan los ejemplos. Les comento a mis apreciables lectores que todo principiante debe pasar por una curva de aprendizaje, por lo que es posible que no le funcione el código a la primera. Pero deben prestar atención a los detalles ya que allí se encuentra la solución, no es recomendable solo copiar y pegar el código en nuestro editor sin antes haber leído la teoría correspondiente y haberla comprendido. Si no se hace esto, es casi seguro que los programas no les funcionarán. Se debe analizar el  código y asegurarse que esté acorde a nuestras necesidades o adaptarlo convenientemente. Esto es lo mismo que aconsejo a mis estudiantes, con la práctica y análisis constante al final las cosas funcionarán correctamente por lo que los animo a seguir intentando hasta lograrlo.

De igual manera agradezco sus comentarios y propuestas. Mas adelante publicaré ejemplos de aplicación mas complejos donde se integrarán varios módulos, pero antes los explicaré de forma individual con ejemplos sencillos para que tod@s aquellos que se inician en el mundo de los microcontroladores los conozcan y sepan utilizarlos.

Acerca de jjguevara09

Me gusta la electrónica
Esta entrada fue publicada en Microcontroladores PIC y etiquetada , , , , . Guarda el enlace permanente.

3 respuestas a 08 – Temporizador de 16 bits del PIC18F4550

  1. Antonio dijo:

    que tal buen post, tengo una pregunta espero puedas ayudarme, lo que quiero realizar es enviar un unico pulso en estado alto que tiene una duracion de 500ms para activar un dispositivo se puede hacer mediante estas interrupciones?

    Me gusta

  2. Muy excelente el tutorial, me ayudo mucho en mis aprendizajes de timer0, le felicito por postear dicho material, pero veo que no esta actualizando sus post. con mas temas. Espero que actualice con mas información. gracias y salu2.

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s