Sunteți pe pagina 1din 14

El temporizador Timer 0 en los microcontroladores PIC.

El Timer 0 es un modulo temporizador/contador de 8 bits que cuenta con un preescalador programable tambin de 8 bits. Puede funcionar como temporizador o como contador. En modo temporizador el valor del registro TMR0 se incrementa con cada ciclo de instruccin (o cada X ciclos dependiendo del preescalador). En modo contador el valor del registro TMR0 se incrementa en cada flanco (ascendente o descendente) del pin RA4/T0CKI. En ambos casos al desbordarse (pasar de 0xFF a 0x0) el registro TMR0 la bandera de interrupcin del timer 0 (bit T0IF del registro INTCON) se pone a 1. El modo temporizador se selecciona poniendo a cero el bit T0CS del registro OPTION. Poniendo a uno ese bit el modulo trabaja en modo contador, en este modo de operacin adems se debe seleccionar si el incremento se producir en cada filo ascendente o descendente, al poner a cero el bit T0SE del registro OPTION se selecciona el filo ascendente. El preescalador es compartido por el Timer 0 y por el Watchdog. Se asigna a un mdulo o a otro mediante el bit PSA del registro OPTION. Poniendo el bit a 1 el preescalador se asigna al Watchdog y poniendolo a 0 el preescalador se asigna al Timer 0. El valor del preescalador se selecciona con los bits PS2:PS0 de la siguiente manera: PS2:P20 000 001 010 011 100 101 110 111 Carga y temporizacin En modo temporizador el Timer 0 incrementa su cuenta en cada ciclo de instruccin. Este modo sirve para generar temporizaciones y bases de tiempo de la misma forma que los retardos por software, sin embargo las temporizaciones con el Timer 0 pueden ser ms exactas y adems se cuenta con la ventaja de que el mdulo puede trabajar mediante interrupciones as que el programa puede ejecutar otras isntrucciones mientras se realiza la temporizacin. La temporizacin que se puede obtener con este mdulo se obtiene de la siguiente relacin: Temporizacin = [(256 - precarga)*PS+2]*Tinstruccion Donde: precarga = Valor que se le asigna al registro TMR0 al comenzar la temporizacin PS = Preescalador. Si esta asignado al watchdog tomar el valor de 1 Tinstruccin = 4/frecuencia de oscilacin y la temporizacin est dada en segundos. La temporizacin mxima utilizando el oscilador interno del pic 16f628 es: Temp.max. = [(256 - 0)*256+2]*1uS = 65528uS De modo que la temporizacion mxima que se puede tener con el es solamente de 65.538mS. Si se desea obtener una temporizacion distinta solo se debe escribir en el registro TMR0 el valor de la precarga necesaria. TMR0 1:2 1:4 1:8 1:16 1:32 1:64 1:128 1:256 WDT 1:1 1:2 1:4 1:8 1:16 1:32 1:64 1:128

precarga = -[([Temporizacion/(4/fosc)]-2)/PS]+256 Donde, de nuevo, la temporizacin est dada en segundos. Veamos un ejemplo de aplicacin: Se desea complementar el valor del puerto B cada 50mS. Se estar revisando que se haya cumplido el tiempo de la temporizacin checando la bandera T0IF. Utilizando la expresin de la precarga y utilizando el preescalador ms grande (256) obtenemos el valor que necesitamos cargar al registro TMR0 para obtener una temporizacin de 50mS. precarga = -[([50mS/(4/4Mhz)]-2)/256]+256 = 60.69 60 Ya que no podemos cargar numeros fraccionarios el valor de precarga necesario es 60. Teniendo entonces el valor de la precarga el cdigo del programa sera el siguiente: INICIO bsf STATUS,RP0 clrf TRISB movlw b'00000111' movwf OPTION_REG bcf STATUS,RP0 clrf PORTB bcf INTCON,T0IF PRECARGA movlw .60 movwf TMR0 ESPERA btfss INTCON,T0IF goto ESPERA bcf INTCON,T0IF comf PORTB,f goto PRECARGA La configuracin del Timer 0 se realiza mediante las lneas "movlw b'00000111'" y "movwf OPTION_REG". Mediante estas lineas se configura el timer en modo temporizador (T0CS = 0), el preescalador se asigna al timer 0 (PSA = 0) y se selecciona el preescalador mximo (PS2:PS0 = 111). Una vez configurado el timer 0 se limpia el puerto B y la bandera T0IF. Posteriormente se realiza la precarga cargando un 60 al registro TMR0 y en ese momento la temporizacin comienza. Para saber si la temporizacin termin se est revisando la bandera T0IF. Mientras esta sea 0 la temporizacin an no habr terminado, cuando la bandera es 1 entonces la temporizacin finaliz, se borra la bandera, se complementa el puerto B y se vuelve a realizar la precarga. De este modo el programa est complementado el puerto B cada 50mS.

Recursos del PIC -Uso del TMR0 como temporizador El Timer0 es un temporizador/contador ascendente de 8 bits, cuando trabaja con el reloj del PIC se le suele llama temporizador y cundo los pulsos los recibe de una fuente externa a travs de la patilla RA4/TOCKI se le llama contador, pero digamos

que es el mismo perro con dos collares diferentes. Para no liarnos con las patillas y el nombre de los registros voy a mostrar los registros y patillas implicadas solo en el TMR0 utilizando el PIC16f84, aunque podra ser otro cualquiera ya que este temporizador viene incorporado en todos los PIC. Patillaje:

RA4/TOCKI: cuando el temporizador trabaje como contador, los pulsos externos los recibir a travs de esta patilla. OSC1/CLKIN y OSC2/CLKOUT: son para conectar el oscilador que nos determinar a la frecuencia que va a trabajar nuestro PIC, los dos tipos de osciladores ms usados son el XT (cristal de cuarzo) y el RC (resistencia y condensador). Nota: cuando las patillas traen ms de una funcin separadas por la barra del siete quiere decir que segn la configuracin de los registros SFR que se muestran ms abajo se utilizarn de una manera o de otra. Banco de registros especficos (SFR) del PIC 16f84A:

Como podemos ver solo estn marcados de un color diferente los que estn implicados en el funcionamiento del TMR0, vamos a ver la funcin que tienen: TMR0: es un registro del que podemos leer el valor del contador en tiempo real, pero tambin podemos escribir en l y alterar el valor de conteo.

OPTION: los bits que estn en color verde son los que estn implicados en la configuracin del TIMER0 PS0, PS1 y PS2: Configuracin del preescaler. El preescaler es un divisor de pulsos que est a la entrada del Timer-contador. El prescaler divide el nmero de pulsos que le entran al timer-contador o al Wachtdog. El factor de divisin es el siguiente (segn los valores de PS2, PS1 y PS0 respectivamente

PSA: Bit de asignacin de prescaler. Si est a "1" el prescaler se asigna a WDT (Wachtdog), si est a "0" se asigna al TMR0. TOSE: Bit de seleccin del tipo de flanco para el TMR0. A "1" se incrementa TMR0 por flanco descendente de RA4, a "0" se incrementa TMR0 por flanco ascendente de RA4. TOCS: Selecciona la entrada de reloj de TMR0. A "1" la entrada de reloj de TMR0 es por flanco de la patilla RA4, a "0" la entrada de reloj de TMR0 es por ciclo de reloj interno. Pero el PIC tambin permite que se produzca una interrupcin por desbordamiento del TMR0. Cuando se produce una interrupcin el programa abandona temporalmente lo que estaba haciendo para atender la subrutina de interrupcin, pero antes guarda en una regin especial de la memoria llamada pila la direccin de la siguiente instruccin de programa, para que cuando acabe la subrutina de interrupcin pueda seguir ejecutando el programa por donde se haba quedado. El registro que configura todas las interrupciones es el INTCON, como veis est mapeado en los dos bancos, una cosa muy til cuando se trabaja en ensamblador para no tener que cambiar de banco constantemente para su configuracin, pero que en C no es necesario saber ya que es el compilador el que se encarga de gestionar esto de una manera transparente para el programador.

Pues bien vamos a ver lo que significa cada uno de los bits que estn implicados en la interrupcin por el TMR0: TOIF: solo se puede leer su valor, es un Flag o bandera que se pone a 1 cuando se produce un desbordamiento del TMR0, (este o no este configurado para producir una interrupcin). Cuando se trabaja en Ensamblador, este bit hay que ponerlo a "0" por programa, con CCS no tenemos que preocuparnos por ello. (je, je,.. otra cosa que nos ahorramos)

TOIE (Habilita la interrupcin por desbordamiento de TMR0). Si este bit esta a "1" la interrupcin por desbordamiento de TMR0 es posible. GIE (Habilita las interrupciones globalmente). Este bit permite que cualquier interrupcin sea posible. Para poder usar cualquier interrupcin hay que habilitarla globalmente e individualmente. Bueno como veis hay varias variables que podemos utilizar a nuestro antojo para utilizar este recurso del PIC, la frmula que las relaciona es la siguiente:

Y para ver como funciona todo esto con el compilador CCS vamos hacer el siguiente ejemplo: Se trata de usar el Timer0 para generar una interrupcin cada 32 ms utilizando el reloj interno del microcontrolador. La funcin de interrupcin se utilizar para hacer parpadear un Led en la patilla RB7 del PIC. Para ello vamos a utilizar en el circuito un cristal de cuarzo de 4 MHz. Si nos fijamos en la formula anterior tenemos Interrupt_TMR0= 32 ms que es el valor que nos da el ejemplo, tambin tenemos F.Oscilador = 4 MHz y nos quedan dos valores para tener resueltas todas las variables de la ecuacin el valor TMR0 que ya hemos dicho que se puede sobrescribir su valor en cualquier momento durante la ejecucin del programa y el Prescaler, pues le damos el valor que queramos al Prescaler por ejemplo 256 y calculamos en la frmula el valor que tenemos que escribir en el registro TMR0 para obtener los 32 ms:

Si despejamos el valor del TMR0 nos sale un valor de 131 que en hexadecimal es 0x83. Pues bien ya solo queda implementar todo esto en C, para ello en este ejemplo (y de paso vemos una nueva funcionalidad que nos presenta este entorno de programacin de PIC) vamos a utilizar el Wizard o asistente para generar proyectos. Quiero aclarar primero que este asistente est todava en desarrollo por lo que es recomendable revisar el cdigo que genera antes de compilar, pues casi siempre tendremos que corregir algn error de sintaxis en el cdigo generado, pero suele ser una gran ayuda para el que empieza a trabajar con este compilador por que te genera un cdigo que es como una plantilla o esqueleto donde estn ya incluidas las funciones para manejar los recursos del PIC que hemos seleccionado con el asistente, para ello hacemos clic con el ratn en el icono que pone PIC Wizard (si, si en el sombrero del mago), nos saldr un cuadro de dialogo de Windows para que guardemos nuestro proyecto donde queramos, una vez hecho esto nos aparecer la siguiente ventana:

En ella podemos ver que a la izquierda podemos seleccionar los diferentes recursos que tienen los PIC y a la derecha tenemos dos pestaas: en Options configuramos el recurso seleccionado y en la pestaa Code visualizamos el cdigo que nos genera el asistente para ese recurso, para el ejemplo que estamos haciendo en General, lo dejamos tal y como se muestra en la figura de arriba. Si ahora hacemos clic en la pestaa code vemos el cdigo generado por el asistente para esta opcin.

Inserted into .h file: no pertenece al cdigo que se va a compilar, simplemente es una nota informativa que nos est diciendo que el cdigo que hay mas abajo se va a insertar en el archivo de cabecera con extensin .h.

#FUSES NOWDT, XT, NOPROTECT: fuses cuya traducin literaria equivaldra a "fusibles" es una directiva que establece unas configuraciones para el PIC que son necesarias a la hora de grabar el programa en el, se pueden incluir aqu o configurarlas en el programa de grabacin que utilicemos, se guardan en la memoria de programa y segn la versin de PIC que utilicemos tendremos mas o menos opciones, las que aqu aparecen tienen el significado siguiente: NOWDT --> No se va a utilizar el Wachtdog. XT --> Se va a utilizar un cristal de cuarzo para la base de tiempos del reloj del PIC. NOPUT -->( Power Up Timer), cuando se configura como PUT al alimentar el circuito el Microcontrolador espera un tiempo determinado para que se estabilicen las tensiones antes de ejecutar el programa. NOPROTECT --> El cdigo grabado en el PIC no est protegido. Hay que decir que cuando creamos un proyecto por medio del Wizard, este nos genera tres archivos, que son los que se muestran en la figura de abajo:

Uno con extensin .c que es donde estar el grueso de nuestra aplicacin, otro con extensin .h que es donde estarn los archivos de cabecera y otro con extensin .pjt que es el proyecto en si y que nos sirve para abrir y editarlo con el IDE del compilador Cuando compilemos y generemos nuestra aplicacin aparecern mas archivos pero estos que hemos mencionado aqu son los que necesitamos para editar nuestro cdigo fuente. Sigamos, cuando seleccionemos la pestaa Communications debemos desmarcar la opcin de comunicacin con el puerto serie RS232, ya que no la vamos a utilizar. Configuracin de los timmers:

En las opciones de este recurso desmarcamos la casilla Not used del Wachtdog por que no lo vamos a utilizar, en el Timer 0 en Source seleccionamos Internal ya que vamos a utilizar los pulsos de reloj del microcontrolador y en Resolution marcamos 256 us, que es el preescaler que habamos decidido utilizar. Vemos que las opciones del Timer 1 y el Timer 2 estn deshabilitadas, ya que PIC 16f84A solo tiene el temporizador timer 0. Bien si ahora hacemos clic sobre la pestaa Code vemos el cdigo generado por el asistente:

La primera lnea como antes nos dice donde se va a insertar el cdigo, en este caso en el archivo .C y dentro de la funcin principal main(). La siguiente lnea es una

llamada a la funcin setup_timer_0( parametro1|parametro2|), que ya est declarada y definida dentro de las libreras del compilador y es utilizada para configurar el registro OPTION del PIC, como vemos acepta parmetros, con el primero RTCC_INTERNAL, le estamos diciendo que vamos a utilizar el reloj interno, lo que viene despus aunque en la figura no se vea muy bien es una barra vertical | y es el smbolo que hay que utilizar para separar los diferentes parmetros que utilicemos, el segundo parmetro que nos ha puesto es RTCC_DIV_1);); y como veis aparece doble el cierre del parntesis y el punto y coma, error del asistente!!, lo que realmente tenemos que poner es esto: RTCC_DIV_256, ya que este segundo argumento le pasa a la funcin el valor del preescaler y queremos que sea 256. Bueno esto lo que me ha generado a m, lo mismo a vosotros os va bien. Vemos que no podemos corregir el cdigo aqu, lo haremos despus en los archivos fuente que nos genera.

Por ultimo nos queda configurar el registro INTCON, para ello seleccionamos Interrups y en Options marcamos la casilla Timer0 overflow (usando como nombre de la interrupcin TIMER0).

El cdigo generado ser el siguiente:

Como vemos la rutina de interrupcin va antes de la funcin main y consta de la directiva del preprocesador #int_TIMER0, con esta directiva el programa sabe a

que direccin de programa debe de ir cuando se dispare esta interrupcin (podemos tener otras), y de la funcin de interrupcin propiamente dicha, donde tenemos que incluir nuestro cdigo, vemoslo aqu debajo de una forma ms clara:

#int_TIMER0 Void TIMER0_isr(void) { //Nuestro cdigo de interrupcin. } Dentro de la funcin main incluye lo siguiente: enable_interrupts(INT_TIMER0); enable_interrupts(GLOBAL); La primera instruccin habilita la interrupcin particular del Timer 0 por desbordamiento y la otra habilita las interrupciones globalmente, como dijimos al principio no hay que preocuparse por resetear el flag de interrupcin TOIF, ni de desactivar las interrupciones globales mientras se este dentro del cdigo de interrupcin por si se produce otra simultneamente, como hay que hacer cuando se trabaja en ensamblador, estas funciones lo hacen tambin pero de una manera transparente al programador, por eso es un lenguaje de alto nivel. Despus de terminar con la configuracin de los recursos pulsamos el botn de aceptar y el asistente nos crear los archivos correspondientes: Archivo de cabecera:

Archivo .C principal:

Pues bien este es el esqueleto de nuestra aplicacin y sin escribir una lnea de cdigo. Ahora sobre esta plantilla tenemos que escribir nuestro cdigo para hacer nuestra aplicacin funcional. En el archivo de cabecera incluiremos la lnea que esta en negrita: #include <16F84A.h> #use delay(clock=4000000) #bit RB7=0x6.7 //definimos RB7 como el pin 7 de la puerta B Con la directiva #bit le podemos asignar la direccin de memoria del bit de un registro a una variable que podremos utilizar despus para referirnos a ese bit.

En el archivo principal TMR0.C aadiremos tambin las sigientes lneas marcadas en negrita: #include "C:\Prcticas PIC C\TMR0\TMR0.h" #int_TIMER0 void TIMER0_isr(void) { if (RB7==0) { RB7=1; set_TIMER0(0x83); //inicializa el timer0 } else { RB7=0; set_TIMER0(0x83); //inicializa el timer0 } } void main()

set_tris_b(0b01111111); //configura RB7 como salida el resto como entrada RB7=0; //inicializo el bit RB7 a 0; setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); enable_interrupts(INT_TIMER0); enable_interrupts(GLOBAL); set_TIMER0(0x83); //inicializa el timer0 //el bucle infinito es necesario ya que si el micro entra en sleep //desactiva la interrupcin del TMR0 while(true);

Con la directiva #include lo que se hace es incluir un archivo dentro de otro, si queremos tener todo el cdigo fuente en un mismo archivo lo nico que tenemos que hacer es sustituir esta lnea por el contenido del archivo de cabecera, pero es recomendable separar los archivos de cabecera del resto del programa. C es un lenguaje estructurado y as es como trabaja, cuanto antes nos acostumbremos a ello mejor. ojo si utilizamos los dos archivos y copiamos el cdigo fuente y lo pegamos en un directorio diferente tendremos que modificar la ruta actual al archivo de cabecera si no al compilar dar un error de archivo no encontrado. El funcionamiento del programa es muy simple, despus de inicializar el puerto B inicializamos el TMR0 por medio de la funcin set_TIMER0, el valor que recibe como parmetro esta funcin es el valor que se escribir en el TMR0 que es 0x86, valor que habamos obtenido de la frmula anteriormente, como est activada la interrupcin por desbordamiento del contador este empieza a contar a partir de 0x86 131 en decimal hasta 255 que equivale a 11111111 en binario como es un contador de 8 bits al siguiente pulso de reloj se produce el desbordamiento y el contador de programa va a la direccin de memoria donde est el vector de interrupcin del TMRO y ejecuta las instrucciones que estn dentro de su funcin. La funcin de interrupcin lo nico que hace es a travs de una sentencia de control ifelse encender o apagar el led, fijaros que en cada caso se vuelve a cargar el valor del TMR0 para que el contador vuelva a empezar a contar por 131 y no por cero, de esta manera la interrupcin se producir cada 32 ms que es lo que queramos. Bueno a hora toca construir nuestro circuito virtual y simularlo con Proteus para comprobar que efectivamente es as.

Hemos agregado una sonda de tensin y para poder ver los valores que toma en el tiempo incluimos una grafica en simulacin digital. Si ampliamos la grfica veremos que cada intervalo tiene una duracin de 32 ms. Como siempre el DSN y el cdigo fuente os lo podis bajar desde la seccin Descargas > Apuntes -> Electrnica -> Microcontroladores -> Ejemplos prcticos programacin PIC en C.

Bueno yo creo que mas mascado no puede estar, para aquellos que no conozcan el lenguaje C y les suene a chino lo que es una funcin y lo de pasar parmetros a una funcin. No problem en el curso de teora se ver detenidamente.