Librería para control de tiempo en PIC Deja un comentario

En este artículo presentamos una librería para control de tiempo en PIC, escrita en lenguaje C, que cubre una amplia gama de microcontroladores y que puede ser utilizada dentro de cualquier programa como base de tiempo relativa para programar la ejecución de diversas tareas, generar retardos, medir el tiempo relativo entre eventos e incluso, podemos agregar código para utilizar la librería como una base de tiempo absoluta (tipo reloj en tiempo real). Las pruebas y diseño del código se realizaron con MPLAB X y el compilador XC8 de Microchip, sin embargo, debe ser relativamente fácil usar esta libería en cualquier otro compilador de C para PICs.

En muchos sitios de internet, es común ver programas con llamadas a las funciones de retardo (delay) incluidas con el compilador, sin embargo, mientras más complejo es nuestro programa y mientras más tareas debe atender, cada vez es menos indicado utilizar estas funciones en el flujo de ejecución del programa, ya que esencialmente desperdician el tiempo del CPU y no se pueden atender otras actividades mientras tanto.  Esto es especialmente cierto cuando llamamos en diversos lugares de nuestro programa a retardos de más de unas pocas centenas de milisegundos.

La librería propuesta es una mejor alternativa a las funciones de retardo o “delays” y permitirá hacer programas más profesionales y eficientes para un buen surtido de PICs. Para quienes han trabajado programando sobre la plataforma arduino, esta librería desarrolla las mismas funciones que la función millis() en arduino.

Funcionamiento de la librería para control de tiempo en PIC Tick.h

A continuación explicaremos un poco sobre la librería para control de tiempo en PIC que hemos llamado “Tick”. Esta librería provee una forma elegante y versatil de manejar muchas de las tareas relacionadas con el tiempo dentro de un programa para microcontroladores. La librería esencialmente implementa un contador de 32 bits de longitud que lleva la cuenta del tiempo desde que se ha encendido el dispositivo. Esto lo hace constantemente “en segundo plano”, incluso mientras se ejecuta nuestro programa principal, ya que se hace uso de un timer del microcontrolador.

El valor de este contador puede ser accesado utilizando la función tick_get(), que devuelve un entero sin signo de 32 bits. Dicho número representa el número de ticks que han ocurrido desde que se encendió el microcontrolador. Los bits menos significativos devueltos por esta función provienen directamente del registro del timer del microcontrolador (16 bits), mientras que los más significativos, provienen de otra variable de 32 bits que se incrementa cada vez que el timer se desborda (en la interrupción por desbordamiento).

Estas dos variables representadas de manera gráfica se verían mas o menos así:

librería para control de tiempo en PIC - Imagen que muestra la distribucion del contador de ticksEntonces tenemos un valor de 32 bits que se incrementa constantemente y que podemos leer en cualquier momento dentro de la ejecución de nuestro programa, ya que la librería toma en cuenta la sincronización y seguridad para leer el conteo de “Ticks” sin que se presenten comportamientos erroneos debido a que se produce una interrupción mientras leemos el valor del contador (garantizamos dentro de la librería que esta operación se realice de forma atómica).

¿Como utilizar la librería para control de tiempo en PIC?

El API de la librería es muy sencilla, solamente 3 funciones:

  • La función tick_init() prepara el timer del microcontrolador para iniciar la cuenta, debe llamarse a esta función al principio del programa.
  • La función tick_get() obtiene un valor de 32 bits con el conteo actual de ticks desde que inició el contador del sistema. Este valor se desborda (pasa del máximo valor posible a cero) en un determinado tiempo, que esta determinado por la frecuencia de reloj y la configuración del timer de acuerdo a la arquitectura .
  • La función tick_update() Se llama desde la rutina de servicio de interrupción del Timer para actualizar el valor de los bits mas significativos del contador. Esto es requerido solamente en algunas arquitecturas de PIC que solamente cuentan con un vector de interrupción.

Calculando la resolución del “tick” (Ejemplo a 4 Mhz)

En la arquitectura PIC16 el Timer 1 es utilizado para esta librería. Este timer es configurado SIEMPRE por la librería para funcionar con un divisor con factor 8. Esto quiere decir que si el reloj de instrucciones del PIC funciona a 1 Mhz (con cristal de 4 Mhz), el Timer se incrementa con una frecuencia de 125 Khz o cada 8 microsegundos, por lo que esa unidad pasa a ser la resolución del “tick”.

Como la variable retornada por tick_read() es un entero sin signo de 32 bits y el bit menos significativo representa 8 uS, podemos contar hasta:

  • 4294967296 ticks.
  • Que equivalen más o menos a 34359 segundos
  • El equivalente a 572 minutos
  • O bien: cerca de 9 horas y media.

Como podemos ver, el intervalo de tiempos que podemos manejar es bastante amplio, pudiendo hacer retardos o planificar la ejecución de eventos periodicos desde unos pocos milisegundos hasta horas.

La librería calcula en tiempo de compilación el número de ticks para completar un segundo, un minuto y una hora y lo pone a disposición del programador como una literal, que es util para escribir condiciones más legibles e independientes de la velocidad de reloj. Si continuamos con el ejemplo de 4 Mhz, la cantidad de “Ticks” que ocurren en 1 segundo es de 125000 (ciento veinticinco mil) que es la frecuencia de incremento del timer. Para obtener los ticks por minuto y por hora solamente debemos multiplicar la cantidad anterior por 60 y por 3600. Por ejemplo en el archivo tick.h encontramos algo así:

Comparación de tiempo y aritmética modular

Para ejecutar determinadas acciones tras un periodo de tiempo programado solo hace falta lo siguiente:

  • Guardar el valor de Tick actual
  • En un instante posterior, obtener el valor actualizado del contador de ticks
  • Obtener la diferencia entre el valor actual y el valor almacenado con anterioridad
  • Decidir si el intervalo de tiempo requerido ya ha transcurrido
  • Ejecutar una acción y guardar el valor del contador

Lo anterior se traduce al siguiente código en C:

Parpadeo de un led: programa tradicional vs programa sin retardo

A continuación presentamos dos programas que hacen parpadear un led a una frecuencia de 1 hert. Uno de ellos esta estructurado de forma tradicional con “retardos” y el otro utiliza la librería para control de tiempo con PIC.

El programa más básico CON retardos sería así:

Se puede observar que las rutinas de retardo tardan un segundo completo en ejecutarse. Cualquier otra tarea que requiera la atención del CPU no podrá ser atendida hasta que se termine la secuencia de retardos y el flujo del programa retorne al bucle principal.

El código SIN retardo quedaría de la siguiente manera:

El programa de arriba utiliza la librería para control de tiempo en PIC. En este caso el led también cambia de estado cada 500 milisegundos. La diferencia es que en vez de esperar medio segundo dentro de la rutina de retardo, el programa recorre constantemente el ciclo principal y compara si la diferencia entre el “tick” del sistema anterior  y el actual es mayor o igual al equivalente a 500 milisegundos o más. Cuando esta condición se cumple, se cambia el estado del pin del led.

Esta operación de resta y la comparación toma solamente algunas decenas de microsegundos, permitiéndonos ejecutar muchísimas veces por segundo todo el ciclo principal del programa y por lo tanto, atendiendo a todas las funciones que se encuentran dentro de este ciclo muchas veces cada segundo.

¿Que hace interesante a esta librería?

Lo que hace interesante es la forma en que este mismo timer se puede utilizar de manera simultanea para cubrir prácticamente todas las necesidades de temporización de una aplicación. Mediante una sencilla API podemos lograr retardos, medición de tiempos, planificación en la ejecución de tareas, timeouts, conteo de fecha y hora (reloj/calendario) y muchas otras funcionalidades requeridas en prácticamente cualquier programa para microcontroladores.

En algunos de los ejemplos y proyectos con PIC que publicamos observarás que habitualmente incluimos código similar a este ultimo para hacer parpadear un led a una frecuencia de 1 Hz. De esta manera,  uno puede saber facilmente que el programa se encuentra ejecutandose y también saber si la fuente de reloj funciona a la frecuencia adecuada.

¿Con que PICs se puede utiizar?

La librería para control de tiempo en PIC está diseñada para ejecutarse en una gran variedad de microcontroladores, actualmente se ha probado y se soportan las familias siguientes:

  • PIC16F
  • PIC18F
  • PIC24F
  • dsPIC30F
  • dsPIC33F

Si estas usando algun pic básico, nuestro favorito de este rango es el PIC16F88, pero también se puede utilizar esta librería con un PIC16F628. Si tienes un PIC16F84 costará más trabajo, ya que este solamente cuenta con el Timer 0 y la librería utiliza el Timer 1 de 16 bits. hablando de microcontroladores un poco más avanzados, la librería es adecuada para los populares PIC18F2550 y PIC18F4550 de la gama media que se utilizan en infinidad de proyectos escolares y profesionales.

Descarga de la librería para control de tiempo en PIC gestión de tiempo.

La librería está publicada en Github. Dentro del repositorio se encuentran también las versiones para PIC18 y PIC24 o dsPIC:

https://github.com/geekfactory/Tick

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

0
    0
    Tu Carrito
    Tu carrito esta vacíoVolver a la tienda
    Enviar Whatsapp
    Hola 👋
    ¿En qué podemos ayudarte?