TIMER0.pdf
Transcript of TIMER0.pdf
TIMER0
sesion11
TEMPORIZADORES/CONTADORES
Los microcontrol adores AVR tienen en su interior 3
temporizadores/Contadores, a saber:
TMR0 y TMR2 de 8 bits,
TMR1 de 16 bits.
Pueden ser configurados de manera general como:
temporizadores,
contadores de eventos externos ,
comparadores,
generadores PWM,
etc.
Analicemos a continuación la estructura y
funcionamiento de cada uno de ellos.
Objetivos
Describir el funcionamiento de los
temporizadores/Contadores. Configurar los temporizadores
y habilitar sus interrupciones para realizar contadores
temporizados, contadores de eventos externos,
comparadores, capturas de señales externas, generadores
PWM .
Fundamento teórico y esquemas
TIMER/COUNTER0
Las características principales de este temporizador son:
Contador de un solo canal.
Generador de frecuencias.
Contador de eventos externos.
Posee un prescaler de reloj de 10 bits.
Produce una interrupción por sobreflujo ( al pasar de 0xFF
a 0x00 ) .
Como podemos observar en la figura de bloques, el TMR0 puede
recibir pulsos del reloj interno ( temporizador) o del exterior por el Pin
4 ( T0, Contador de eventos externos ) . Cuando existe un sobreflujoproduce una interrupción.
Para configurar y trabajar con el TMR0 se deben tener en cuenta los
bits de los siguientes registros:
REGISTRO DE CONTROL TIMER/COUNTER0 – TCCR0
Los bits TCCR0<2:0>, permiten seleccionar la f uente de reloj,
conforme la siguiente tabla
Cuando se emplea el prescaler, por ejemplo CLK/8 significa que cada 8 pulsos
de reloj el registro TCNT0 se incrementa en una unidad, lo que significa que el
tiempo de desborde ( de 0xFF a 0x00) se multiplica por 8 veces
Cuando se configura como contador, por el pin T0 entran los pulsos y el
incremento de la cuenta , se puede configurar en el registro TCCR0 en falling (
flanco descendente ) o rising ( flanco ascendente ) .
REGISTRO TIMER/COUNTER0 – TCNT0
Es un registro de 8 bits que se puede leer o escribir directamente. Cuando
se realiza una determinada temporización, en este registro se precarga con
cierto valor dependiendo del tiempo necesitado, conforme la siguiente
fórmula:
De aquí, por ejemplo, si necesitamos un tiempo de 4 milisegundos a un
oscilador de 4MHz, el registro TCNT0 se deberá cargar con TCNT0 = 6.
Con este valor, el TMR0 cada 250 conteos dará una señal de
interrupción. Los valores que se cargan en TCNT0 habrá que ajustarlos,
pues no se toma en cuenta el tiempo que tarda en ejecutarse las
instrucciones de la subrutina de TMR0.
REGISTRO DE MASCARA DE INTERRUPCIONES TIMER/COUNTER0 –
TIMSK
El bit 0, permite habilitar la interrupción del TMR0 si se escribe 1.
REGISTRO DE BANDERA S DE INTERRUPCIONES – TIFR
Cuando se produce una interrupción el bit TOV0 se pone automáticamente en
1, indicando que el TCNT0 pasó de 0xFF a 0x00
PARA CONFIGURAR EL TMR0 COMO TEMPORIZADOR SE SIGUEN
LOS SIGUIENTES PASOS:
Configurar el TMR0 como temporizador y el prescaler:
Config Timer0 =Timer, Prescaler = 64
Se apaga el TMR0: Stop Timer0
Se direcciona el vector de interrupción: On Timer0 Over0
Se precarga el registro TCNT0: Timer0 = ….
Se habilita la interrupción por TMR0: Enable Timer0
Se habilitan las interrupciones globales: Enable Interrupts
Se inicia el temporizador: Start Timer0
PROGRAMA QUE INCREMENTA CONTEO BINARIO EN
PTOB CADA SEGUNDO USANDO INTERRUPCIÓN POR
TIMER0 CONSIDERANDO UNA FRECUENCIA DE
RELOJ DE 4 MHZ
CK/64 tiempo mínimo=16us
4ms/16us=250 conteos
256-250=6 -> TCNT0
4ms x 250conteos= 1s
.include “m8def.inc“
.org 0x00
rjmp main
.org 0x0020
rjmp timer
main:
LDI R17,0x00
out portb,r17
clr r25 ;pone a cero contador 4ms
ser r16 ; poner todo a ‘1’
out ddrb,r16 ;ptoB de salida
out timsk,r16 ;habilita int. por timer
ldi r16,6
out tcnt0,r16 ;manda el 6 a timer
sei ;habilita I en SREG habilitassem global
ldi r16,$03 ;
out tccr0,r16 ;011 en escala: CK/64
clr TIFR ; se pone a cero el bit TOV0
Ciclo: nop ;pasa el tiempo
rjmp ciclo
timer: inc r25 ;inc. conteo de 4ms
cpi r25,$fa ;250d = fah
breq increm ;se va a inc. ptoB
pon_conteo: ldi r16,$06
out tcnt0,r16 ;comienza tiempo 4ms otra vez
CLR TIFR
reti ;regresa de interrupción
;habilitando I en SREG
increm: inc r17 ;inc conteo en ptoB
out portb,r17 ;saca conteo
clr r25 ;borra conteo de 4ms
rjmp pon_conteo
Este programa hace parpadear un led conectado al pin RB0 del puerto
B durante aprox. 1seg. utilizando el timer0 para esto con su interrupcion
Registros: r0 -> sirve para el parpadeo del led al aplicarle un eor
r16 -> On/Off led, r17 para precargar al timer/counter0,
r18 contador de interrupciones,
r19 flag indicación de que paso un segundo
Conexiones: B1 -> LedDIRECTIVAS EN ENSAMBLADOR
.include "m8def.inc" ;ATmega8
;DEFINICION DE REGISTROS
.def led_cambio=r0 ;registro para parpadeo del led
.def count=r18
.def flag=r19
;reset-vector address $0000
.org $0000
rjmp main ;ve al main
.org $009
rjmp int_tmr0 ;va a la interrupcion por desborde del timer0
;PROGRAMA PRINCIPAL
main:
ldi r16,$04 ;Configuracion de...
out sph,r16
ldi r16,$5F out spl,r16 ;...la pila: Stack: $045F=RAMEND
ser r16 ;r16 <- $FF
out ddrb,r16 ;portB salida
clr flag ;ponemos a cero la bandera para indicar que ha pasado 1seg.
clr count ;ponemos a cero el contador de interrupciones
ldi r16,4 ;r16 <- 4
out tccr0,r16 ;configuramos el Timer/Counter0 con reloj interno preescaler 256
ldi r16,130 ;r16 <- 130
out tcnt0,r16 ;valor de precarga para contar solamente 125 estados del timer
ldi r16,1 ;r16 <- 1
out timsk,r16 ;se habilita la interrupción por desborde del Timer/Counter0
ldi r16,$01 ;r16 <- $01 -> Iluminar led conectado pin RB0
mov led_cambio,r16 ;led_cambio <- r16 :variable para el parpadeo
sei ;se habilita las interrupciones globales
loop:
cpi flag,255 ;pasó 1seg?
breq toggle ;saltamos a cambiar estado
rjmp loop ;bucle infinito
toggle:
out portb,r16 ;actuamos sobre el led(conectado al pin RB0)
eor r16,led_cambio ;cambiamos estado on/off
clr flag ;limpiamos la bandera de indicación de 1seg pasado
rjmp loop ;bucle infinito
Les explico los registros del TIMER:
TIMSK - Habilita la interrupción por sobreflujo del contador TCNT0
TIFR - Es la bandera que dice si hubo sobreflujo del TCNT0
TCCR0 - Aquí uno da las escalas de división de TCNT0
TCNT0 - Aquí se lleva la cuenta
En TCCR0 Se tiene CS02, CS01 y CS00 los cuales indican la escala y el
funcionamiento del Timer, los datos que llevan son CS02, CS01 y CS00
respectivamente:
*Cristal de 4MHz
000 - stop, no cuenta
001 - CK, la escala es igual al cristal que uno le ponga (0.25us por conteo y 4MHz)
010 - CK/8 (2us)
011 - CK/64 (16us)
100 - CK/256 (64us)
101 - CK/1024 (256us)
110 - Flanco derecho en patita T0 PD4
111 - Flanco izquierdo en T0
R25 va a contar 250 veces el desbordamiento del timer. El timer se va a desbordar
cada 4ms ya que se usó CK/64. R16 lleva un 6 para que el conteo se haga 250
veces.
;RUTINA DE INTERRUPCION
int_tmr0:
inc count ;incrementar contador de interrupciones
cpi count,125 ;se han producido 125 interrupciones
brne salir ;si no han pasado 125 interrupciones, salimos de la rutina
ser flag ;pasaron las 125 interrupciones = 1 seg, activamos bandera
clr count ;reiniciamos contador de interrupciones
salir:
ldi r17,130 ;r17 <- 130
out tcnt0,r17 ;valor de precarga para contar solamente 125 estados del timer
reti ;fin de rutina de interrupción