Siguenos en ...

Google+facebooktwitter

youtubepinterest RSS aquihayapuntes

Últimos Tutoriales


Licencia

Creative Commons

 

Todo el contenido de este sitio está bajo una licencia de Creative Commons

 

Recursos del PIC -Uso del TMR0 como contador

Vamos a ver en este ejemplo como utilizar el TIMER 0 con una frecuencia de reloj externa al microcontrolador, la señal externa la aplicaremos, como no, a la patilla  RA4/TOCKI del PIC, dicha señal la utilizaremos para generar una interrupción a través del TIMER0 cada segundo, en la función de interrupción implementaremos el código necesario para hacer parpadear  un Led en la patilla RB7 del PIC.

 

 La frecuencia de la señal de reloj externa que utilizaremos será de 400 Hz y el Timer 0 lo configuraremos para qué empiece a contar  en el flanco de subida de la señal de reloj, el circuito que tenemos que implementar será el siguiente:

 

TMR0 modo Contador

 

Bien, primeramente vamos a ver como se tiene que configurar el registro OPTION para que el TMR0 trabaje de esta forma:

 

Registro Option

Primeramente el bit TOCS tenemos que ponerlo a 1, recordar que:

  • Si TOCS=1, el TMR0 actúa como contador.
  • Si TOCS=0, el TMR0 actúa como temporizador

Luego vamos hacer nuestros cálculos, teniendo en cuenta que queremos tener una interrupción cada segundo, si os fijáis en la formula de abajo es parecida a la que vimos en el ejemplo anterior, a excepción de que la frecuencia de reloj externa no está multiplicada por 4. Al igual que antes elegimos un Prescaler, en este ejemplo 4 (podíamos a ver elegido otro cualquiera que estuviera en la tabla)  y calculamos el valor con el que tenemos que inicializar el TMR0 para que se produzca su desbordamiento cada segundo.

 

 

Formula setup tmr0 modo contador

 

 

Si despejamos el valor que tenemos que cargar en el TMR0 nos sale un valor de 156 que en hexadecimal es de 0x9C.
La función en C para configurar el TMR0 lógicamente es la misma que en el ejemplo anterior pero con parámetros diferentes:

 

setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);


Las palabras utilizadas para declarar los parámetros definen ya su significado. Pero para ver directamente lo que hace la función, podemos ejecutar el programa paso a paso, o poner un breakpoint  en la línea siguiente a la instrucción de arriba, abrir la ventana de visualización de los registros internos del PIC que nos ofrece el entorno de Proteus y ver como queda el registro OPTION después de ejecutar la sentencia:

 

 

Pic CPU registers con Proteus

 

 

Como vemos en los registros del PIC, el bit 5  del registro OPTION está a 1 (reloj externo) y los bits PS2:PS0 tienen el valor 001 que corresponde a un preescaler de 1:4 que es el que habíamos elegido.

La señal de reloj externa la podemos simular por medio de Proteus, si seleccionamos Generator Mode -> DCLOCK nos saldrá una ventana que configuraremos según se muestra en la figura de abajo:

 

 

Parametros dclock Proteus

 

 

Si analizamos la tensión en el ánodo del Led  mediante una gráfica, observamos que la señal cuadrada generada a partir de la interrupción en el pic tiene entre el flanco de subida y el flanco de bajada una diferencia en el tiempo de 1 s  que es el valor que queríamos.

 

 

Grafica TMR0 contador con Proteus

 

 

Si utilizáis  el asistente para generar el esqueleto de la aplicación, tal como hicimos en el  ejemplo anterior el timer  hay que configurarlo de la siguiente forma:

 

Configuración TMR0 como contador con el Wizard del IDE PCW CCS

 

Veis que sale un Overflow de 2.5 s, esto es lo que saldría en la formula si dejamos al TMR0 que empiece a contar desde 0.


El código del ejemplo será el siguiente:


#include <16F877A.h>
#fuses XT,NOWDT
#use delay(clock=4000000)

#bit RB7=0x6.7 //definimos RB7 como el pin 7 de la puerta B


#int_TIMER0 //la siguiente función tiene que ser la de interrupción del TMR0
void  TIMER0_isr(void) //function interrupción TMR0
{
if (RB7==0)
  {
    RB7=1;
   set_TIMER0(0x9C); //inicializa el timer0
  }
 else
    {
    RB7=0;
  set_TIMER0(0x9C); //inicializa el timer0
    }

}


void main()
{
   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);

   set_tris_b(0b01111111); //configura RB7 como salida el resto como entrada
   RB7=0; //inicializo el bit RB7 a 0;

   set_TIMER0(0x9C); //inicializa el timer0
    //el bucle infinito es necesario ya que si el micro entra en sleep
   //desactiva la interrupción del TMR0
   while(true);
}


Como veis no he utilizado el PIC 16F84 sino el 16F877A pero es exactamente igual lo único que hay que cambiar es la directiva #include<16f84.h> por #include <16f877A.h>. Microchip hace coincidir por compatibilidad las direcciones de memoria de los registros de los dispositivos de inferior categoría, de está manera con solo cambiar una línea de código  podemos emigrar nuestra aplicación a otro PIC de mayor capacidad.

Bueno a lo mejor alguno piensa que para hacer parpadear un Led no hace falta tanta historia. Pero no se trata del que se hace, sino del como se hace, el contenido de la función de interrupción se puede cambiar por otro cualquiera según lo que queramos hacer en cada programa.

Una modificación que se podría hacer sería obtener la señal de reloj externa por medio de un circuito digital para poder implementar, si se quiere, el circuito en una placa.

 

indice prácticas PIC en C 

 

© 2007-2014 AquiHayapuntes.com