Timer 0 - Como Temporizador en CCS

Como podríamos saber, los microcontroladores poseen en su mayoría varios temporizadores, pero en este caso hablare del Timer 0 ya que este se encuentra en los microcontroladores mas económicos y antiguos. Este puede funcionar como Contador o como Temporizador.
Si lo configuramos como Contador este debe adquirir pulsos desde el exterior y si lo configuramos como Temporizador utilizara el mismo oscilador del microcontrolador. 
Mostrare un ejemplo de utilización simple como temporizador, esta función sera útil cuando necesitamos realizar una tarea que corra en paralelo a nuestro programa principal, por ejemplo, el multiplexado de displays para visualizar algún valor. En este ejemplo que comentaba debemos atender el multiplexado de los display de forma independiente al programa principal, esto nos resulta útil porque por ejemplo en un reloj tenemos el segundero que cambia cada 1 segundo pero el muestreo de los displays se debe realizar a una frecuencia mucho mayor a 1 segundo para lograr una persistencia en la visión.
Si configuramos este timer en lenguaje ensamblador tendremos que manipular directamente los registros TMR0 (Banco 0) y OPTION (Banco 1), dentro del registro OPTION se encuentran los bit PS2, PS1 y PS0, estos serán los que configuran el Prescaler del Oscilador del microcontrolador. En otras palabras, como antes mencionaba cuando el Timer 0 funciona como temporizador utilizara los pulsos de reloj del mismo microcontrolador pero por ejemplo para un cristal de 4MHz (donde el bus del microcontrolador funcionara a 1MHz) debemos dividir esta frecuencia ya que es demasiado rápido para realizar un timer, entonces con el prescaler seteando los tres bit PS2 al PS0 logramos setear el factor de división que les mostrare en la siguiente tabla:



Hay otros bit's obviamente en los registros del Timer pero en este caso tratare de hacer lo mas sencillo posible el funcionamiento del mismo como temporizador y dejare esos bit's extra para su investigación.
Dentro del datasheet podemos encontrar la formula para calcular el tiempo con el que se creara la interrupción del timer.
El timer funciona como un contador de 8 bits, (del 0 al 255) cuando este llega al máximo produce un overflow (desbordamiento) y cada vez que se produce se genera una interrupción que reinicia el timer y comenzara de nuevo.
Para calcular el tiempo debemos, aparte del divisor de frecuencia de reloj, setear una variable que modificara el valor de cuenta (0 a 255) para que desborde y produzca la interrupción antes o después del tiempo que divide el prescaler.


Ti: Tiempo de interrupción
fosc: Frecuencia del oscilador
Vs: Valor de seteo del timer
P: Prescaler

Si nosotros no usamos el valor de seteo del timer, la formula quedara:



Ejemplos [con prescaler en 4]:
Sin valor de seteo:

Con valor de seteo:

Podemos concluir que al no usar valor de seteo del timer, la interrupción sera de 1,024ms y con el valor de seteo sera de 1ms, entonces aquí podemos ver la importancia de esta variable cuando uno requiere una interrupción a un periodo mas exacta (si quisiéramos que sea a 1ms).
NOTA: este calculo sera eficiente cuando trabajemos en lenguaje ensamblador, lamentablemente al trabajar en C perdemos algo de precisión y este calculo tendrá un error de aproximadamente 3%, por eso debemos medir nuestra salida con un frecuencimetro u osciloscopio para saber exactamente si la interrupción es correcta, solo tendremos que ajusta el valor de seteo.

Cuando utilicemos este timer debemos tener en cuenta que el código que se ejecutara en este temporizador debe encontrarse dentro de la funciona timer0(); donde esta tendra el vector de interrupción inmediatamente antes de la función con la nomenclatura #int_timer0.
Dentro de esta función se pondrá el código que queramos, al final de nuestro código (Dentro de esta función pondremos el valor de seteo del timer set_timer0(valor); y luego cerramos la llave de la función.

Dentro de la función principal, tendremos que configurar el timer y las interrupciones.
1) setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); aquí decimos que el timer funcionara como temporizador con el reloj del microcontrolador "RTCC_INTERNAL" y también que el prescaler sera dividiendo por 4 "RTCC_DIV_4".
2) set_timer0(6); este es el valor de seteo del timer, valor decimal 6.
3) enable_interrupts(INT_TIMER0); y enable_interrupts(GLOBAL); tenemos la habilitación de las interrupciones.

Ahora veremos el ejemplo codificado en C.
Podremos analizar que dentro de la funcion timer0() tenemos output_toggle(PIN_A0); y como había mencionado antes al final tenemos el seteo del timer set_timer0(6);
Con este valor la función se interrumpirá cada 1ms, al hacer toggle o swap al bit 0 del puerto y A, cambiara de 0 a 1 y de 1 a 0 cada 1ms, esto podremos verlo en el osciloscopio donde veremos una señal cuadrada de 2ms (1ms tON + 1ms tOFF) con un ciclo de trabajo del 50% y una frecuencia de 500Hz.  
NOTA: estos son valores teóricos, debemos tener en cuenta el 3% de error del calculo en el lenguaje C.

#include <16f628a .h="">
#FUSES NOWDT 
#FUSES XT 
#FUSES MCLR 
#use delay(clock=4000000) 
#int_timer0 
void timer0(){ 
   output_toggle(PIN_A0); 
   set_timer0(6); 

void main(){ 
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); 
   set_timer0(6); 
   enable_interrupts(INT_TIMER0); 
   enable_interrupts(GLOBAL); 
   while(TRUE){
   } 
}