El TIMER 0
(c) Domingo Llorente 2010 1
Características
• Se trata de un registro de 8 bits. (SFR: 01h, 101h)
• Puede trabajar como contador o temporizador.
• Se puede leer o escribir en él.
• Dispone de un preescaler de 8 bit programable por software.
• Puede trabajar con señal de reloj interna o externa.
• Generación de interrupción por desbordamiento (FF->00)
• Flanco programable (ascendente/descendente) para la señal de
reloj externa.
(c) Domingo Llorente 2010 2
TIMER 0: Modo Temporizador (I)
• El modo temporizador se
selecciona poniendo a cero el
bit T0CS (OPTION_REG<5>).
• En modo temporizador, el
Timer0 incrementa su valor con
cada ciclo de instrucción (sin
preescaler).
• Si se escribe en el registro
TMR0, éste deja de
incrementarse durante 2 ciclos
de instrucción.
(c) Domingo Llorente 2010 3
TIMER 0: Modo Temporizador (II)
Para configurar el TIMER0 en modo temporizador se utiliza la
función:
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_N );
RTCC_INTERNAL, indica el modo temporizador y RTCC_DIV_N
configura el preescaler en función de N.
Donde N puede tomar uno de los siguientes valores:
1,2,4,8,16,32,64,128,256.
(c) Domingo Llorente 2010 4
TIMER 0: Modo Contador (I)
• El modo contador se
selecciona poniendo a uno el
bit T0CS (OPTION_REG<5>).
• En modo contador, el Timer0
incrementa su valor con cada
flanco de (subida/bajada) que
se produce en RA4/TOCK1.
• Para TOSE=1 flanco
descendente y para TOSE=0
flanco descendente.
(c) Domingo Llorente 2010 5
TIMER 0: Modo Contador (II)
Para configurar el TIMER0 en modo contador se utiliza una de las
funciones siguientes:
setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_N );
O bien:
setup_timer_0(RTCC_EXT_H_TO_L | RTCC_DIV_N );
RTCC_EXT_L_TO_H, configura el modo contador y hace que el registro
TIMER0 se incremente con cada flanco ascendente en RA4.
RTCC_EXT_L_TO_H, configura el modo contador y hace que el registro
TIMER0 se incremente con cada flanco descendente en RA4.
(c) Domingo Llorente 2010 6
Lectura y escritura del TIMER0
Para leer el contenido del TIMER0 se utiliza la función:
get_timer0();
Ejemplo:
int valor; // Declarar una variable de 8 bits
valor=get_timer0(); // Asignamos el valor del timer a la variable
Para escribir un valor en el registro TIMER0 se utiliza la función:
set_timer0(valor);
Ejemplo:
int valor=156; // Declarar una variable de 8 bits
set_timer0(valor); // Asignamos el valor 156 al timer
o simplemente:
set_timer0(156);
(c) Domingo Llorente 2010 7
Interrupción del TIMER0
• Para habilitar la interrupción del
TIMER0 hay que poner a uno el bit
TMR0IE del registro INTCON.
• La interrupción se produce cuando
el registro TMR0 pasa de 0xFF a
0x00. En ese momento el bit
TMR0IF se pone a uno.
• El bit TMR0IF debe ponerse a
cero por software antes de salir de
la rutina de atención a la
interrupción.
• La interrupción del Timer0 no saca
al pic del modo sleep ya que en este
modo el Timer0 permanece
desactivado.
(c) Domingo Llorente 2010 8
Interrupción del TIMER0 en CCS (I)
Para habilitar la interrupción del TIMER0 se utilizan las funciones:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_N); // N=1,2,4,…..
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
Para deshabilitar la interrupción:
disable_interrupts(INT_TIMER0);
La función de atención a la interrupción es:
#int_TIMER0
int TIMER0_isr()
{
(c) Domingo Llorente 2010 9
Interrupción del TIMER0 en CCS (II)
Ejemplo:
Utilizar el Timer 0 como temporizador con un pre-escaler de 256 y
un retardo base de 50ms para realizar un programa que muestre
un contador binario en el PORTB a intervalos de 250ms.
(c) Domingo Llorente 2010 10
Interrupción del TIMER0 en CCS (III)
Paso 1: Configuración del TIMER0 como temporizador, programar el
preescaler y habilitar la interrupción (dentro de la función main() ):
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
Paso 2: Programar la función de interrupción, antes de la función main():
int8 conta=0,valor=0;
#int_TIMER0
TIMER0_isr()
{
conta++;
if(conta==5) // Cuando interrumpe 5 veces han pasado ±250ms
{ // 5x50ms=250ms
valor++;
conta=0;
}
set_timer0(256-195); // Recarga para interrumpir cada 195x256us=49920us
}
(c) Domingo Llorente 2010 11
Interrupción del TIMER0 en CCS (IV)
Paso 3: Completamos la función main() con los mensajes del LCD y la
configuración de los puertos.
//////////// MENSAJES DE TEXTO //////////////
char msg1[]="Int. de 250ms";
char msg2[]="con TIMER-0";
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
set_tris_b(0x00);
output_b(0x00);
set_timer0(256-195);
LCD_Init();
LCD_Escribecadena(msg1);
LCD_Cambiolinea();
LCD_Escribecadena(msg2);
while(true) // Bucle infinito
{
output_b(valor);
}
}
(c) Domingo Llorente 2010 12
Programa completo
realizado sin utilizar
el asistente
(c) Domingo Llorente 2010 13
Captura de la simulación:
(c) Domingo Llorente 2010 14