Vous êtes sur la page 1sur 12

Recursos del PIC -Uso del TMR0 como

temporizador http://aquihayapuntes.com/indice-practicas-pic-
en-c/uso-del-tmr0-como-temporizador.html
Detalles
En esta práctica vamos a ver cómo utilizar el
Timer0 con el compilador CCS.
Pero antes vamos a ver un poco de teoría:
El Timer0 es un temporizador/contador
ascendente de 8 bits, cuando trabaja con el Como podemos ver solo están marcados de un
reloj del PIC se le suele llama temporizador y color diferente los que están implicados en el
cundo los pulsos los recibe de una fuente funcionamiento del TMR0, vamos a ver la
externa a través de la patilla RA4/TOCKI se le función que tienen:
llama contador, pero digamos que es el mismo TMR0: es un registro del que podemos leer el
perro con dos collares diferentes. Para no valor del contador en tiempo real, pero
liarnos con las patillas y el nombre de los también podemos escribir en él y alterar el
registros voy a mostrar los registros y patillas valor de conteo.
implicadas solo en el TMR0 utilizando el OPTION: los bits que están en color verde son
PIC16f84, aunque podría ser otro cualquiera ya los que están implicados en la configuración
que este temporizador viene incorporado en del TIMER0
todos los PIC.  PS0, PS1 y PS2: Configuración del
Patillaje: preescaler. El preescaler es un divisor de
pulsos que está a la entrada del Timer-
contador. El prescaler divide el número
de pulsos que le entran al timer-contador
o al Wachtdog. El factor de división es el
siguiente (según los valores de PS2, PS1
y PS0 respectivamente

RA4/TOCKI: cuando el temporizador trabaje


como contador, los pulsos externos los
recibirá a través de esta patilla.
OSC1/CLKIN y OSC2/CLKOUT: son para  PSA: Bit de asignación de prescaler. Si
conectar el oscilador que nos determinará a la está a "1" el prescaler se asigna a WDT
frecuencia que va a trabajar nuestro PIC, los (Wachtdog), si está a "0" se asigna al
dos tipos de osciladores más usados son el XT TMR0.
(cristal de cuarzo) y el RC (resistencia y  TOSE: Bit de selección del tipo de flanco
condensador). para el TMR0. A "1" se incrementa TMR0
Nota: cuando las patillas traen más de una por flanco descendente de RA4, a "0" se
función separadas por la barra del siete quiere incrementa TMR0 por flanco ascendente
decir que según la configuración de los de RA4.
registros SFR que se muestran más abajo se  TOCS: Selecciona la entrada de reloj de
utilizarán de una manera o de otra. TMR0. A "1" la entrada de reloj de TMR0
Banco de registros específicos (SFR) del PIC es por flanco de la patilla RA4, a "0" la
16f84A: entrada de reloj de TMR0 es por ciclo de
reloj interno.
Pero el PIC también permite que se produzca interrupción se utilizará para hacer parpadear
una interrupción por desbordamiento del un Led en la patilla RB7 del PIC. Para ello
TMR0. Cuando se produce una interrupción el vamos a utilizar en el circuito un cristal de
programa abandona temporalmente lo que cuarzo de 4 MHz. Si nos fijamos en la formula
estaba haciendo para atender la subrutina de anterior tenemos Interrupt_TMR0= 32 ms que
interrupción, pero antes guarda en una región es el valor que nos da el ejemplo, también
especial de la memoria llamada pila la tenemos F.Oscilador = 4 MHz y nos quedan
dirección de la siguiente instrucción de dos valores para tener resueltas todas las
programa, para que cuando acabe la subrutina variables de la ecuación el valor TMR0 que ya
de interrupción pueda seguir ejecutando el hemos dicho que se puede sobrescribir su valor
programa por donde se había quedado. El en cualquier momento durante la ejecución del
registro que configura todas las interrupciones programa y el Prescaler, pues le damos el valor
es el INTCON, como veis está mapeado en los que queramos al Prescaler por ejemplo 256 y
dos bancos, una cosa muy útil cuando se calculamos en la fórmula el valor que tenemos
trabaja en ensamblador para no tener que que escribir en el registro TMR0 para obtener
cambiar de banco constantemente para su los 32 ms:
configuración, 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. Si despejamos el valor del TMR0 nos sale un
Pues bien vamos a ver lo que significa cada valor de 131 que en hexadecimal es 0x83.
uno de los bits que están implicados en la Pues bien ya solo queda implementar todo esto
interrupción por el TMR0: en C, para ello en este ejemplo (y de paso
 TOIF: solo se puede leer su valor, es un vemos una nueva funcionalidad que nos
Flag o bandera que se pone a “1” cuando presenta este entorno de programación de
se produce un desbordamiento del TMR0, PIC) vamos a utilizar el Wizard o asistente para
(este o no este configurado para producir generar proyectos. Quiero aclarar primero que
una interrupción). Cuando se trabaja en este asistente está todavía en desarrollo por lo
Ensamblador, este bit hay que ponerlo a que es recomendable revisar el código que
"0" por programa, con CCS no tenemos genera antes de compilar, pues casi siempre
que preocuparnos por ello. (je, je,.. otra tendremos que corregir algún error de sintaxis
cosa que nos ahorramos) en el código generado, pero suele ser una gran
 TOIE (Habilita la interrupción por ayuda para el que empieza a trabajar con este
desbordamiento de TMR0). Si este bit compilador por que te genera un código que es
esta a "1" la interrupción por como una plantilla o esqueleto donde están ya
desbordamiento de TMR0 es posible. incluidas las funciones para manejar los
 GIE (Habilita las interrupciones recursos del PIC que hemos seleccionado con
globalmente). Este bit permite que el asistente, para ello hacemos clic con el ratón
cualquier interrupción sea posible. Para en el icono que pone PIC Wizard (si, si en el
poder usar cualquier interrupción hay que sombrero del mago), nos saldrá un cuadro de
habilitarla globalmente e individualmente. dialogo de Windows para que guardemos
Bueno como veis hay varias variables que nuestro proyecto donde queramos, una vez
podemos utilizar a nuestro antojo para utilizar hecho esto nos aparecerá la siguiente ventana:
este recurso del PIC, la fórmula 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
interrupción cada 32 ms utilizando el reloj
interno del microcontrolador. La función de
En ella podemos ver que a la izquierda Hay que decir que cuando creamos un
podemos seleccionar los diferentes recursos proyecto por medio del Wizard, este nos
que tienen los PIC y a la derecha tenemos dos genera tres archivos, que son los que se
pestañas: en Options configuramos el recurso muestran en la figura de abajo:
seleccionado y en la pestaña Code
visualizamos el código 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 pestaña code vemos
el código generado por el asistente para esta
opción.

Uno con extensión .c que es donde estará el


grueso de nuestra aplicación, otro con
extensión .h que es donde estarán los archivos
de cabecera y otro con extensión .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 aplicación
Inserted into .h file: no pertenece al código aparecerán mas archivos pero estos que
que se va a compilar, simplemente es una nota hemos mencionado aquí son los que
informativa que nos está diciendo que el necesitamos para editar nuestro código fuente.
código que hay mas abajo se va a insertar en Sigamos, cuando seleccionemos la pestaña
el archivo de cabecera con extensión .h. Communications debemos desmarcar la opción
#FUSES NOWDT, XT, NOPROTECT: fuses cuya de comunicación con el puerto serie RS232, ya
tradución literaria equivaldría a "fusibles" es que no la vamos a utilizar.
una directiva que establece unas Configuración de los timmers:
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 grabación que utilicemos, se
guardan en la memoria de programa y según
la versión 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 En las opciones de este recurso desmarcamos
tensiones antes de ejecutar el programa. la casilla Not used del Wachtdog por que no lo
NOPROTECT --> El código grabado en el PIC vamos a utilizar, en el Timer 0 en Source
no está protegido. seleccionamos Internal ya que vamos a utilizar
los pulsos de reloj del microcontrolador y en
Resolution marcamos 256 us, que es el
preescaler que habíamos decidido utilizar.
Vemos que las opciones del Timer 1 y el Timer
2 están deshabilitadas, ya que PIC 16f84A solo
tiene el temporizador timer 0.
Bien si ahora hacemos clic sobre la pestaña
Code vemos el código generado por el
asistente:

El código generado será el siguiente:

La primera línea como antes nos dice donde se


va a insertar el código, en este caso en el
archivo .C y dentro de la función principal
main(). La siguiente línea es una llamada a la
función setup_timer_0(
parametro1|parametro2|…), que ya está
declarada y definida dentro de las librerías del
compilador y es utilizada para configurar el Como vemos la rutina de interrupción va antes
registro OPTION del PIC, como vemos acepta de la función main y consta de la directiva del
parámetros, con el primero RTCC_INTERNAL, preprocesador #int_TIMER0, con esta
le estamos diciendo que vamos a utilizar el directiva el programa sabe a que dirección de
reloj interno, lo que viene después aunque en programa debe de ir cuando se dispare esta
la figura no se vea muy bien es una barra interrupción (podemos tener otras), y de la
vertical “|” y es el símbolo que hay que utilizar función de interrupción propiamente dicha,
para separar los diferentes parámetros que donde tenemos que incluir nuestro código,
utilicemos, el segundo parámetro que nos ha veámoslo aquí debajo de una forma más clara:
puesto es RTCC_DIV_1);); y como veis
aparece doble el cierre del paréntesis y el #int_TIMER0
punto y coma, ¡¡error del asistente!!, lo que Void TIMER0_isr(void)
realmente tenemos que poner es esto: {
RTCC_DIV_256, ya que este segundo //Nuestro código de interrupción.
argumento le pasa a la función el valor del }
preescaler y queremos que sea 256. Bueno
esto lo que me ha generado a mí, lo mismo a Dentro de la función main incluye lo siguiente:
vosotros os va bien. Vemos que no podemos enable_interrupts(INT_TIMER0);
corregir el código aquí, lo haremos después en enable_interrupts(GLOBAL);
los archivos fuente que nos genera. La primera instrucción habilita la interrupción
Por último nos queda configurar el registro particular del Timer 0 por desbordamiento y la
INTCON, para ello seleccionamos Interrups y otra habilita las interrupciones globalmente,
en Options marcamos la casilla Timer0 como dijimos al principio no hay que
overflow (usando como nombre de la preocuparse por resetear el flag de
interrupción TIMER0). interrupción TOIF, ni de desactivar las
interrupciones globales mientras se este dentro En el archivo principal TMR0.C añadiremos
del código de interrupción por si se produce también las sigientes líneas marcadas en
otra simultáneamente, como hay que hacer negrita:
cuando se trabaja en ensamblador, estas #include "C:\Prácticas PIC C\TMR0\TMR0.h"
funciones lo hacen también pero de una #int_TIMER0
manera transparente al programador, por eso void TIMER0_isr(void)
es un lenguaje de alto nivel. {
Después de terminar con la configuración de if (RB7==0)
los recursos pulsamos el botón de aceptar y el {
asistente nos creará los archivos RB7=1;
correspondientes: set_TIMER0(0x83); //inicializa el
Archivo de cabecera: timer0
}
else
{
RB7=0;
set_TIMER0(0x83); //inicializa el
timer0
}
}
Archivo .C principal:
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_25
6);
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
Pues bien este es el esqueleto de nuestra //desactiva la interrupción del TMR0
aplicación y sin escribir una línea de código. while(true);
Ahora sobre esta plantilla tenemos que escribir }
nuestro código para hacer nuestra aplicación
funcional. Con la directiva #include lo que se hace es
En el archivo de cabecera incluiremos la línea incluir un archivo dentro de otro, si queremos
que esta en negrita: tener todo el código fuente en un mismo
archivo lo único que tenemos que hacer es
#include<16F84A.h> sustituir esta línea por el contenido del archivo
#usedelay(clock=4000000) de cabecera, pero es recomendable separar los
#bit RB7=0x6.7 //definimos RB7 como el archivos de cabecera del resto del programa. C
pin 7 de la puerta B es un lenguaje estructurado y así es como
trabaja, cuanto antes nos acostumbremos a
Con la directiva #bit le podemos asignar la ello mejor. ¡ojo¡ si utilizamos los dos archivos y
dirección de memoria del bit de un registro a copiamos el código fuente y lo pegamos en un
una variable que podremos utilizar después directorio diferente tendremos que modificar la
para referirnos a ese bit. ruta actual al archivo de cabecera si no al
compilar dará un error de archivo no
encontrado. El funcionamiento del programa es
muy simple, después de inicializar el puerto B
inicializamos el TMR0 por medio de la función
set_TIMER0, el valor que recibe como
parámetro esta función es el valor que se
escribirá en el TMR0 que es 0x86, valor que
habíamos obtenido de la fórmula
anteriormente, como está activada la
interrupción 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
Bueno yo creo que mas mascado no puede
a la dirección de memoria donde está el vector
estar, para aquellos que no conozcan el
de interrupción del TMRO y ejecuta las
lenguaje C y les suene a chino lo que es una
instrucciones que están dentro de su función.
función y lo de pasar parámetros a una
La función de interrupción lo único que hace es
función. “No problem” en el curso de teoría se
a través de una sentencia de control if–else
verá detenidamente.
encender o apagar el led, fijaros que en cada
caso se vuelve a cargar el valor del TMR0 para jueves, 5 de julio de 2012
que el contador vuelva a empezar a contar por El timer TMR0 en los PIC con ejemplo
131 y no por cero, de esta manera la El timer TMR0 en los PIC
interrupción se producirá cada 32 ms que es lo Es un modulo que sirve como contador o como
que queríamos. Bueno a hora toca construir temporizador de 8 bit's.
nuestro circuito virtual y simularlo con Proteus Funcionando como temporizador el TMR0 es un
para comprobar que efectivamente es así. registro donde yo puedo almacenar un valor y este se
va incrementando de 1 en 1 con los ciclos de
instruccion, es decir, con cada ciclo se incrementa
en 1 el TMR0, cuando la cuenta llega a 255 y pasa a
0 (cero) se porduce una interrupcion por desborde
del TMR0, recordemos que en un registro de 8 Bit's el
valor mas alto que se puede almacenar es 255 y que
si lo incrementamos estando en 255 pasa a cero, y es
a esto a lo que se le denomina desborde.

¿Cuál seria la ventaja entonces de usar el timer


TMR0? Cuando necesitemos temporizar, o lo que
normalmente llamamos un retardo, no
necesitaremos las acostumbradas rutinas para
retardos, esto lo vamos a ver con un ejemplo.

Hemos agregado una sonda de tensión y para El TMR0 tiene las siguientes caracteristicas:
poder ver los valores que toma en el tiempo -se puede leer y escribir
incluimos una grafica en simulación digital. Si -puede trabajar con relog externo o interno
ampliamos la gráfica veremos que cada -detecta el flanco de subida o bajada del relog
intervalo tiene una duración de 32 ms. Como externo
siempre el DSN y el código fuente os lo podéis -tiene un prescaler de 8 bit´s
-tiene una interrupcion por desborde de la cuenta de
bajar desde la sección Descargas –> Apuntes -
255 a 0
> Electrónica -> Microcontroladores ->
los registros asociados a el son el TMR0, INTCON y
Ejemplos prácticos programación PIC en C.
el OPTION_REG

El bit T0CS (OPTION 2) a 1 trabaja como


temporizador, 0 trabaja como contador

El bit T0SE (OPTION 4) en modo contador a 1 flanco


descendente, 0 flanco ascendente

El bit PSA (OPTION 3) 0 prescaler al temporizador, 1


prescaler al perro guardian WDT

Cuando se desborda el TMR0, se activa el bit 2 de


INTCON (T0IF) y si el T0IE esta activado el T0IF
generara interrupción y se debe borrar por software
cuando se atienda la interrupción

Para calcular el tiempo de temporización


Tiempo = 4 * Tosc * (256 - valor cargado en
TMR0)*(Rango presaler)

donde
Configuramos el INTCON
Tocs = 1 / Fosc (frecuencia del oscilador)
Registro donde activamos las interrupciones globales
y la del TMR0
Entonces si necesitamos un determinado tiempo
MOVLW B'10100000'
podemos despejar TMR0 y hallar su valor:
MOVWF OPTION_REG
BIT 7 Activamos las interrupciones Globales
Tiempo
BIT 6 interrupciones de otros periféricos
TMR0 = ---------------------------- - 256
desactivadas
4 * Tosc * Prescaler
BIT 5 Habilitamos la interrupción por desborde en
el TMR0
Formula que nos dara un valor muy aproximado
BIT 4 deshabilitamos interrupción externa INT
del Tiempo
BIT 3 deshabilitamos interrupción por cambio en el
Empecemos la configuración PORTB
Configuramos el OPTION_REG
BIT 2 bandera interrupción en TMR0
BIT 1 bandera interrupción en INT
BANKSEL OPTION_REG
BIT 0 bandera interrupción por cambio en PORTB
MOVLW B'00000000'
ANALICEMOS
BIT 7 Pull up PORTB Disable
BTI 6 interrupcion por flaco de subida en el INT Pin
BIT 5 fuente del clock para el TMR0, internal 1 ciclo
ed intruccion (1/Fosc)
BIT 4 Flanco de bajada para el incremento del
TMR0
BIT 3 Prescaler asignado al TMR0
BIT 2-0 Division del prescaler

Ejemplo
Vamos a crear una señal de 1 KHz usando el TMR0.
END
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
también de 8 bits. Puede funcionar como
temporizador o como contador.
En modo temporizador el valor del registro TMR0 se
incrementa con cada ciclo de instrucción(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
Código fuente de 0xFF a 0x0) el registro TMR0 la bandera de
LIST P=16F886 interrupción del timer 0 (bit T0IF del registro INTCON)
INCLUDE P16F886.INC ERRORLEVEL -302 se pone a 1. El modo temporizador se selecciona
__CONFIG _CONFIG1, _INTOSCIO & _WDT_OFF & poniendo a cero el bit T0CS del
_PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF registro OPTION.Poniendo a uno ese bit el modulo
& _BOREN_ON & _IESO_OFF & _FCMEN_OFF & trabaja en modo
_LVP_OFF & _DEBUG_OFF contador, en este modo de operación además se
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF debe seleccionar si el incremento se producirá en
cada filo ascendente o descendente, al poner a cero
CBLOCK 0X20 el bit T0SE del registro OPTION se selecciona el filo
ENDC ascendente. El preescalador es compartido por
el Timer 0 y por el Watchdog. Se asigna a un
ORG 0X00 módulo o a otro mediante el bit PSA del
GOTO CONFIGURA registro OPTION. Poniendo el bit a 1 el preescalador
se asigna al Watchdog y poniendolo a 0 el
ORG 0X04 preescalador se asigna al Timer 0. El valor del
GOTO INTERRUPCION preescalador se selecciona con los bits PS2:PS0 de
ORG 0X05 la siguiente manera:
PS2:P20 TMR0 WDT
INTERRUPCION COMF PORTB,F 000 1:2 1:1
MOVLW .7 001 1:4 1:2
MOVWF TMR0 010 1:8 1:4
BCF INTCON,T0IF 011 1:16 1:8
RETFIE 100 1:32 1:16
101 1:64 1:32
CONFIGURA CLRF PORTB
110 1:128 1:64
BANKSEL ANSEL
111 1:256 1:128
CLRF ANSEL
Carga y temporización
CLRF ANSELH
En modo temporizador el Timer 0 incrementa su
BANKSEL TRISB
cuenta en cada ciclo de instrucción. Este modo sirve
CLRF TRISB
para generar temporizaciones y bases de tiempo de
BANKSEL OPTION_REG
la misma forma que los retardos por software, sin
MOVLW B'00000000'
embargo las temporizaciones con el Timer 0 pueden
MOVWF OPTION_REG
ser más exactas y además se cuenta con la ventaja
MOVLW B'10100000'
de que el módulo puede trabajar
MOVWF INTCON
mediante interrupciones así que el programa puede
BANKSEL PORTB
ejecutar otras isntrucciones mientras se realiza
la temporización.
CLRF TMR0
La temporización que se puede obtener con este
CLRF PORTB módulo se obtiene de la siguiente relación:

Temporización = [(256 -precarga)*PS+2]*Tinstrucción


INICIO GOTO INICIO
Donde: OPTION_REG". Mediante estas lineas se configura el
precarga = Valor que se le asigna al registro TMR0 al timer en modo temporizador (T0CS = 0), el
comenzar la temporización preescalador se asigna al timer 0 (PSA = 0) y se
PS = Preescalador. Si esta asignado al watchdog selecciona el preescalador máximo(PS2:PS0 = 111).
tomará el valor de 1 Una vez configurado el timer 0 se limpia el puerto B y
Tinstrucción = 4/frecuencia de oscilación la bandera T0IF. Posteriormente se realiza la
y la temporización está dada en segundos. precarga cargando un 60 al registro TMR0 y en ese
momento la temporización comienza. Para saber si la
La temporización máxima utilizando el oscilador temporización terminó se está revisando la
interno del pic 16f628 es: bandera T0IF. Mientras esta sea 0 la temporización
aún no habrá terminado, cuando la bandera es 1
Temp.max. = [(256 - 0)*256+2]*1uS = 65528uS entonces la temporización finalizó, se borra la
bandera, se complementa el puerto B y se vuelve a
realizar la precarga. De este modo el programa está
De modo que la temporizacion máxima que se complementado el puerto B cada 50mS.
puede tener con el es solamente de 65.538mS. Si se Ejemplo del temporizador Timer 0
desea obtener una temporizacion distinta solo se Temporizador Timer 1 en los microcontroladores
debe escribir en el registro TMR0 el valor de PIC.
la precarga necesaria. El Timer 1 es un módulo temporizador /
contador de 16 bits, que consiste en dos registros de
precarga = -[([Temporizacion/(4/fosc)]-2)/PS]+256 8 bits (TMR1H y TMR1L) que son de lectura y
escritura. Este módulo incrementa su cuenta
Donde, de nuevo, la temporización está dada en desde 0x000 hasta 0xFFFF y al desbordarse vuelve
segundos. a 0x0000. Al presentarse el desborde la bandera de
Veamos un ejemplo de aplicación: Se desea interrupción TMR1IF se pone a 1 y, si está habilitada,
complementar el valor del puerto B cada 50mS. Se la interrupción se presenta. Este módulo al igual que
estará revisando que se haya cumplido el tiempo de el Timer 0 puede funcionar en modo temporizador y
la temporización checando la bandera T0IF. en modo contador. En modo temporizador el par de
Utilizando la expresión de la precarga y utilizando el registros TMR1 se incrementa en cada ciclo de
preescalador más grande (256) obtenemos el valor instrucción, este modo se selecciona poniendo a 0 el
que necesitamos cargar al registro TMR0 para bit TMR1CS del registro T1CON. En modo
obtener una temporización de 50mS. contador el par de registros TMR1 se incrementa en
cada flanco ascendente de una señal de reloj externa,
precarga=-[([50mS/(4/4Mhz)]-2)/256]+256=60.69 ≈ 60 este modo se selecciona poniendo a 1 el
bit TMR1CS del registro T1CON.
Ya que no podemos cargar numeros fraccionarios el
valor de precarga necesario es 60. Teniendo El preescalador del Timer 1 tiene un valor máximo
entonces el valor de la precarga el código del de 8 y se selecciona con los
programa sería el siguiente: bits T1CKPS1:T1CKPS0 de la siguiente manera:
00 = 1:1
INICIO bsf STATUS,RP0 01 = 1:2
clrf TRISB 10 = 1:4
movlw b'00000111' 11 = 1:8
movwf OPTION_REG A diferencia del Timer 0, el Timer 1 tiene la
bcf STATUS,RP0 posibilidad de activar o detener la cuenta mediante el
clrf PORTB bit TMR1ON del registro T1CON.
bcf INTCON,T0IF
PRECARGA movlw .60 Carga y Temporización En modo temporizador el
movwf TMR0
ESPERA btfss INTCON,T0IF Timer 1 incrementa su cuenta en cada ciclo de
goto ESPERA instrucción. La temporización que se puede obtener
bcf INTCON,T0IF con este módulo se obtiene de la siguiente relación:
comf PORTB,f
goto PRECARGA TempTMR1 = [(65536 - precarga)*PS]*Tinstr

La configuración del Timer 0 se realiza mediante las


Donde:
líneas "movlw b'00000111'" y "movwf
precarga = Valor que se le asigna al par de registros
TMR1 al comenzar la temporización PRECARGA bcf T1CON,TMR1ON
PS = Valor del preescalador movlw 0xE7
movwf TMR1H
Tinstr = 4/frecuencia de oscilación movlw 0x96
TempTMR1 = Temporización dada en segundos movwf TMR1L
bsf T1CON,TMR1ON
La temporización máxima utilizando el oscilador
interno del pic 16f628 y el valor más grande de ESPERA btfss PIR1,TMR1IF
preescalador es: goto ESPERA
bcf PIR1,TMR1IF
comf PORTB,f
TempTMR1.Max = [(65536 - 0)*8]*1uS = 524288uS goto PRECARGA

De modo que la temporización máxima que se La configuración del Timer 1 se realiza mediante las
puede tener con este temporizador, utilizando el líneas “movlw b’01100000′” y “movwf T1CON“.
oscilador interno de 4Mhz del pic 16f628, Mediante estas lineas se configura el timer en modo
es de 524.288mS. Con la misma frecuencia de temporizador (TMR1CS = 0) y se selecciona el
oscilación el Timer 0 solamente podia lograr una preescalador máximo (T1CKPS1:T1CKPS0 = 11).
temporización de 65.538mS así que con el Una vez configurado el timer 1 se limpia el puerto B y
Timer 1 se logran temporizaciones de mayor la bandera TMR1IF del
duración. Si se desea obtener una temporización registro PIR1. Posteriormente se realiza la precarga
distinta solo se debe escribir en el par de registros cargando un 0xE7 al registro TMR1H y un 0x96 al
TMR1 el valor de la precarga necesaria para la registro TMR1L.Nótese que antes de realizar la
temporización deseada. carga se detuvo el timer poniendo a 0 el
bit TMR1ON,esto se hace para evitar errores al
precarga = -[([Temporizacion/(4/fosc)])/PS]+65536 momento de cargar el valor a los
registros TMR1,después de realizar la carga se
Veamos el mismo ejemplo que el del temporizador enciende el timer poniendo a 1 el bit TMR1ON y en
Timer 0 ahora aplicado al Timer 1: Se desea ese momento la temporización comienza. Para saber
complementar el valor del puerto B cada 50mS. Se si la temporización terminó se está revisando
estará revisando que se haya cumplido el tiempo de continuamente la bandera TMR1IF. Mientras esta sea
la temporización checando la bandera TMR1IF. 0 la temporización aún no habrá terminado, cuando la
Utilizando la expresión de la precarga y utilizando el bandera es 1 entonces la temporización finalizó,
preescalador más grande (8) obtenemos el valor que entonces se borra la bandera TMR1IF, se
necesitamos cargar al par de registros TMR1 para complementa el puerto B y se vuelve a realizar la
obtener una temporización de 50mS. precarga. De este modo el programa está
complementado el puerto B cada 50mS. Ejemplo del
precarga=-[([50mS/(4/fosc)])/8]+65536 = 59286 = temporizador Timer 1
0xE796

Así que para obtener una temporización de 50mS


mediante el Timer 1 se debe cargar 0xE7al
registro TMR1h y 0x96 al registro TMR1L. El código
del programa sería el siguiente:
INICIO bsf STATUS,RP0
clrf TRISB
bcf STATUS,RP0
movlw b'00110000'
movwf T1CON
clrf PORTB
bcf PIR1,TMR1IF
Temporizador Timer 2 en los microcontroladores
PIC. La temporización máxima que puede alcanzar el
El Timer 2 es un temporizador de 8 bits que tiene Timer 2 es la misma que alcanza el Timer 0.
la particularidad de tener un preescalador y Utilizando el oscilador interno del pic 16f628 la
un post-escalador. Además este módulo cuenta temporización máxima sería de 65536uS. Si se desea
con un registro de periodo PR2 que marca el valor otra temporización se puede lograr cargando el valor
máximo que puede alcanzar la cuenta del necesario al registro PR2.
registro TMR2. A diferencia de los otros
temporizadores, el temporizador Timer 2 no PR2=[([TempTMR2/(4/fosc)])/(Preescaler*Postscal
incrementa su cuenta hasta llegar a 0xFF y er)]-1
después al desborde sino que incrementa su
cuenta desde 0x00 con cada ciclo de instrucción Veamos el mismo ejemplo de los temporizadores
hasta que el valor del registro TMR2 coincide con anteriores, ahora aplicado al Timer 2: Se desea
el del registro PR2 y después, en el siguiente ciclo complementar el valor del puerto B cada
reinicia la cuenta desde 0x00. Este módulo cuenta 50ms. Se estará revisando que se haya cumplido el
con un preescalador y un post-escalador. El tiempo de la temporizacion checando la bandera
preescalador tiene la misma función que en los TMR2IF. Utilizando la expresión de la
otros dos timers y sirve precarga y utilizando el preescalador y el post-
como divisor de frecuencia antes de cada escalador más grande (16) obtenemos el valor quer
incremento. El post-escalador funciona como un que necesitamos cargar al registro PR2 para obtener
divisor de frecuencia después de cada una temporizacion de 50mS.
coincidencia entre los registros TMR2 y PR2. Si el
post-escalador es 1:1 la bandera de interrupción PR2=[([50mS/(4/4Mhz)])/(16*16)]-1=194.31
TMR2IF se habilitará en cada coincidencia entre
TMR2 y PR2, en cambio si por ejemplo el post- Ya que no podemos cargar numeros fraccionarios el
escalador es 1:16, la interrupción se presentará valor del registro PR2 necesario es 194. El código del
cada 16 coincidencias. programa sería el siguiente:
INICIO bsf STATUS,RP0
Este temporizador, al igual que el Timer 1, puede clrf TRISB
habilitarse y deshabilitarse mediante el bcf STATUS,RP0
bit TMR2ON. movlw b'01111010'
movwf T2CON
El preescalador se selecciona con los clrf PORTB
bits T2CKPS1:T2CKPS0 y el post-escalador con bcf PIR1,TMR2IF
los bits T0UTPS3:TOUTPS0 de la siguiente PRECARGA bcf T2CON,TMR2ON
manera: bsf STATUS,RP0
Preescalador Post-escalador movlw .194
00 = 1:1 0000 = 1:1 movwf PR2
01 = 1:4 0001 = 1:2 bcf STATUS,RP0
1x = 1:16 0010 = 1:3 bsf T2CON,TMR2ON
. ESPERA btfss PIR1,TMR2IF
. goto ESPERA
. bcf PIR1,TMR2IF
1111 = 1:16 comf PORTB,f
Carga y Temporización goto PRECARGA
La temporización del Timer 2 está dada por la Descargar código: Ejemplo del temporizador Timer 2
siguiente expresión:
¿Cómo multiplexar una matriz de leds?
TempTMR2 =
Vamos a empezar con un nuevo tutorial, esta vez con
[Preescaler*(PR2+1)*Postscaler]*Tinstr
un cómo sobre multiplexación, cómo multiplexar una
Donde matriz de leds. Si se quisiera controlar una sola
Preescaler = Valor del preescalador columna de una matriz de 5x7 leds se necesitaría un
PR2 = Valor cargado al registro PR2 puerto completo de un pic, 7 pines para controlar las
Postscaler = Valor del post-escalador filas y 1 para controlar la columna, eso significa que
Tinstr = 4/frecuencia de oscilación para controlar todos los leds de la matriz se
TempTMR2 = Temporización dada en segundos
necesitarían 4 puertos de 8 bits, demasiado para un
microcontrolador, sobre todo para un 16F628a.

Para reducir el número de pines requeridos las cinco


columnas de la matriz son multiplexadas, esto
significa que solamente se necesitarán siete pines,
uno por cada fila de la matriz, y cinco para habilitar
cada una de las columnas.

Usando un pic 16F628a se puede utilizar el puerto B


para controlar las filas y el puerto A para las
El diagrama del circuito de ejemplo es el siguiente: A
columnas. La técnica de multiplexación consiste en
continuación pueden ver el video de este ejemplo:
mostrar una columna a la vez, mientras eso se haga
Descargar código: Multiplexar una matriz de 5x8 leds
lo suficientemente rápido parecerá que todas las
Este tutorial está basado en el tutorial How to
columnas estan encendidas a la vez y no se verá
multiplex a matrix of LED's.
ningún parpadeo, por esa misma razón la base de
tiempo para la multiplexación es muy importante por
lo que se utiliza la interrupción del timer 2 para esa
tarea.

La multiplexación es muy sencilla y se ejecuta dentro


de la rutina de interrupción del timer 2, se realiza más
o menos de la siguiente manera:

 Espera interrupción
 Se deshabilitan las columnas
 Se escribe en el puerto B el valor de las filas
 Se habilita la primer columna
 Espera interrupción
 Se deshabilitan las columnas
 Se escribe en el puerto B el valor de las filas
 Se habilita la siguiente columna
 Espera interrupción

Así se repite hasta llegar a la quinta columna,


entonces la ejecución de la multiplexación vuelve al
principio y se vuelve a repetir. El programa de
ejemplo muestra en conteo descendente los números
del 9 al 0. La multiplexación se lleva a cabo en la
rutina de interrupción del timer 2. El programa
principal lo que hace es leer un número almacenado
en una variable (un registro de memoria) y
decodificarlo para ser desplegado en la matriz, como
la matriz es de 5 columnas para decodificar el número
se necesitan 5 registros donde se guardaran los
valores de las filas de cada columna.

Vous aimerez peut-être aussi