Você está na página 1de 6

Timers

Introdução
Os “timers”, também referidos como temporizadores ou cronômetros, são na verdade
contadores digitais assíncronos. Para funcionar, eles precisam ser alimentados com pulsos de
clock. Cada pulso de clock faz o timer incrementar o seu valor de contagem. A figura 1 mostra
um contador composto de 4 flip-flops JK sensíveis à borda de descida do clock CK. A figura 2
mostra as formas de onda da entrada E e das saídas S0, S1, S2 e S3.

Figura 1: Diagrama esquemático de um contador assíncrono crescente.


Fonte: http://www.mspc.eng.br/eledig/eledig2A.asp

Figura 2: Formas de onda do contador.


Fonte: http://www.mspc.eng.br/eledig/eledig2A.asp

Os contadores além de realizarem uma contagem também tem um outro papel importante:
eles podem funcionar como divisores de frequência. Basta observar as saídas S0, S1, S2 e S3
para observar que elas correspondem a divisões por 2, por 4, por 8 e por 16 da frequência da
forma de onda de entrada E.

Os sistemas de timers dos microcontroladores possuem divisores programáveis de frequência


na entrada dos contadores. Isto permite selecionar clocks mais lentos para o contador do timer
e fazê-lo contar mais lentamente. O divisor programável é chamado de PRESCALER.

Os PIC possuem duas fontes primárias de clock: (1) o clock interno (fosc/4) e (2) clock
externo (sinal T0CKI, pino 6, para o timer 0 ou T1CKI, pino 15, para o timer 1). No caso de
um PIC com cristal de 8 MHz, temos um clock interno de 2 MHz que alimenta o sistema do
timer.

Os PIC possuem 3 timers chamados Timer 0, Timer 1 e Timer 2. A tabela a seguir mostra as
suas características.

Timer 0 Timer 1 Timer 2


Nº de bits 8 16 8
Reg. contador TMR0 TMR1H/TMR1L TMR2
Fontes de clock interna/externa interna/externa Interna
(T0CKI) (T1CKI)
Prescaler 8 bit prescaler 2 bit prescaler 4 bit pescaler / 4 bit
postscaler
Habilit. interrupção INTCON,TMR0IE PIE1,TMR1IE PIE1,TMR2IE
Flag sinalizador INTCON,TMR0IF PIR1,TMR1IF PIR1,TMR2IF

O diagrama esquemático do timer 0 do PIC é mostrado na figura 3. Neste diagrama, nota-se


primeiramente que há duas fontes possíveis de clock, uma interna e outra externa
selecionáveis através do bit de configuração T0CS. Caso seja externa, o bit T0SE seleciona a
borda que causará incremento no timer.

T0CKI
(pino 6)
(externo) WATCHDOG
(T0SE)

TMR0IF
PRESCALER TIMER 0
fOSC/4
(T0CS) (PSA)
(interno)
(PS2...0)
Figura 3: Diagrama esquemático do Timer 0 do PIC16F877A.
Fonte: Autoria própria.

O prescaler é o divisor programável cujo fator de divisão é selecionado a partir dos bits de
configuração PS2, PS1 e PS0. Finalmente, a saída do prescaler pode ser usada para alimentar
ou o Timer 0 ou o Watchdog. Todos os bits descritos aqui fazem parte do registrador
OPTION_REG.

81h (banco 1) = OPTION_REG


RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
A explicação sobre cada bit está na página 56 do datasheet (54 no doc. Impresso).

O bit T0CS (Timer 0 Clock Source) seleciona se o clock é interno (=0) ou externo (=1).

O bit T0SE (Timer 0 Source Edge) seleciona a borda do sinal externo. Se =0 seleciona borda
de subida, se =1 seleciona a borda de descida.

O bit PSA (Prescaler Assignment) seleciona se o prescaler será usado pelo Timer 0 (=0) ou se
será usado pelo watchdog (=1).

Os bits PS2...0 selecionam a escala do divisor do prescaler.

PS2...0 Taxa Timer 0 Taxa watchdog


000 1:2 1:1
001 1:4 1:2
010 1:8 1:4
011 1:16 1:8
100 1:32 1:16
101 1:64 1:32
110 1:128 1:64
111 1:256 1:128
CONSIDERAÇÕES SOBRE ERRO
Para fazer um estudo dos erros de contagem do timer, será usado o seguinte cenário:
construir uma rotina que gere um intervalo de 1 segundo. O dado inicial é a frequência de
clock do microcontrolador

f CLK =8 MHz
O período do clock que vai na entrada do prescaler equivale a

4
T TMR = =0,5 s
8 MHz
Ao passar pelo prescaler, ocorre uma divisão da frequência de TTMR. Isto equivale a uma
multiplicação do período

T PRE=T TMR×DIV
DIV respresenta o fator de divisão do prescaler.

Para gerar cada estouro são necessárias 256 contagens. O período de cada estouro é

T EST =256×T PRE


Por fim, resta apenas calcular quantos estouros seriam necessários para se obter 1 segundo.
Faz-se

1
N EST =
T EST

Como N EST somente pode ser inteiro, existe um erro de aproximação. A tabela a seguir
demostra todos estes cálculos em função do divisor DIV escolhido.

Prescaler TPRE TEST NEST Erro Erro %


1:2 1 μs 256 μs 3906 64 μs 0,0064
1:4 2 μs 512 μs 1953 64 μs 0,0064
1:8 4 μs 1,024 ms 976 576 μs 0,0576
1:16 8 μs 2,048 ms 488 576 μs 0,0576
1:32 16 μs 4,096 ms 244 576 μs 0,0576
1:64 32 μs 8,192 ms 122 576 μs 0,0576
1:128 64 μs 16,384 ms 61 576 μs 0,0576
1:256 128 μs 32,768 ms 30 1696 μs 1,69

Observando a tabela nota-se que:

• Há três faixas de erros;


• Para o divisor de 1:2 até 1:16 o contador do número de estouros é maior que 256 e
precisaria de mais de uma variável de contagem; Para o divisor de 1:32 até 1:256 a
contagem de estouros é menor que 256 bastando usar uma única variável para a
contagem.

Considerando que

• O erro 0,0576% seja aceitável;


• Deseja-se usar uma única variável de contagem;
• Se o intervalo entre as interrupções for pequeno, haverá um grande número de
interrupções e a execução do programa normal pelo microcontrolador será prejudicada.
Conclui-se que a melhor escolha para o divisor do timer é 1:128, pois possui erro de 0,056%,
61 estouros (menor que 256) e o menor número de interruções dentro da faixa de erro
escolhida.

Exemplo: Piscar LEDs em intervalos de 1 segundo sem uso de


interrupções
Este primeiro exemplo não fará uso de interruções. Será necessário observar dentro do
programa o estado do bit sinalizador TMR0IF aguardando que seja setado pelo timer.
CBLOCK 0x20
CEST ; CONTADOR DE ESTOUROS
ENDC

INICIO BANK1
MOVLW B'00000000'
MOVWF TRISD
MOVLW B'00000110'
MOVWF OPTION_REG
BANK0

BCF INTCON,TMR0IF ; ASSEGURA SINALIZADOR ZERADO INICIALMENTE


CLRW
MOVWF PORTD ; APAGA LEDS
MOVLW D'61'
MOVWF CEST ; VALOR INICIAL PARA CONTADOR DE ESTOUROS

REP BTFSS INTCON,TMR0IF ; AGUARDA ESTOURO


GOTO REP

BCF INTCON,TMR0IF ; ZERA O SINALIZADOR


DECFSZ CEST,F ; DECREMENTA CONTADOR DE ESTOUROS
GOTO REP ; SE NÃO FOR ZERO, REPETE
; PASSOU 1 SEGUNDO
MOVLW D'61' ; RECOLOCA 61 NO CONTADOR DE ESTOUROS
MOVWF CEST
BTFSS PORTD,0 ; TESTA SE LEDS ESTÃO ACESOS
GOTO ACENDE
MOVLW 0x00 ; APAGA LEDS
MOVWF PORTD
GOTO REP
ACENDE MOVLW 0xFF ; ACENDE LEDS
MOVWF PORTD
GOTO REP

Exemplo de rotina de tratamento de interrupção causada pelo Timer 0


Neste segundo exemplo, mostra-se a rotina de interrupção

CBLOCK 0x20
CEST ; CONTADOR DE ESTOUROS
SEGUNDO_U ; UNIDADE DE SEGUNDO
SEDUNDO_D ; DEZENA DE SEGUNDO
MINUTO_U ; UNIDADE DE MINUTO
MINUTO_D ; DEZENA DE MINUTO
ENDC

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* VETOR DE RESET
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

ORG 0x00
GOTO INICIO

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* INTERRUPÇÕES
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

ORG 0x04 ;ENDEREÇO INICIAL DA INTERRUPÇÃO

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* SALVAMENTO DO CONTEXTO
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

MOVWF W_TEMP ; W -> W_TEMP


SWAPF STATUS,W ; TROCA NIBBLES STATUS -> W
MOVWF STATUS_TEMP ; W -> STATUS_TEMP
SWAPF PCLATH,W ; TROCA NIBBLES PCLATH -> W
MOVWF PCLATH_TEMP ; W -> PCLATH_TEMP
BCF STATUS,RP0 ; Assegura o BANCO 0 ativo

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* ROTINA DE INTERRUPÇÃO
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* TIMER 0
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#DEFINE FIM_MINUT .60
#DEFINE FIM_HORAS .24
#DEFINE FIM_DIAS .31

BCF INTCON,T0IF ; LIMPA O BIT SINALIZADOR

DECFSZ CONTADOR,F ; CONTADOR DO NÚMERO DE ESTOUROS DE 1 SEGUNDO


GOTO FIMINT
MOVLW .61 ; 61 ESTOUROS = 1 SEGUNDO
MOVWF CONTADOR

INCF SEGUNDO_U ; INCREMENTA UNIDADE DE SEGUNDO


MOVF SEGUNDO_U,W ; UNIDADE DE SEGUNDO = 10?
SUBLW .10
BTFSS STATUS,Z
GOTO FIMINT ; NÃO: TERMINA
CLRW ; SIM: ZERA UNIDADE DE SEGUNDO...
MOVWF SEGUNDO_U
INCF SEGUNDO_D ; ...E INCREMENTA DEZENA DE SEGUNDO
MOVF SEGUNDO_D,W ; DEZENA DE SEGUNDO = 6?
SUBLW .6
BTFSS STATUS,Z
GOTO FIMINT ; NÃO: TERMINA
CLRW ; SIM: ZERA DEZENA DE SEGUNDO...
MOVWF SEGUNDO_D
INCF MINUTO_U ; ...E INCREMENTA UNIDADE DE MINUTO
MOVF MINUTO_U,W ; UNIDADE DE MINUTO = 10?
SUBLW .10
BTFSS STATUS,Z
GOTO FIMINT ; NÃO: TERMINA
CLRW ; SIM: ZERA UNIDADE DE MINUTO...
MOVWF MINUTO_U
INCF MINUTO_D ;...E INCREMENTA DEZENA DE MINUTO
MOVF MINUTO_D,W ; DEZENA DE MINUTO = 6?
SUBLW .6
BTFSS STATUS,Z
GOTO FIMINT ; NÃO: TERMINA
CLRW ; SIM: ZERA DEZENA DE MINUTO...
MOVWF MINUTO_D

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* RESTAURAÇÃO DO CONTEXTO
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

FIMINT
SWAPF PCLATH_TEMP,W ; TROCA NIBBLES DE PCLATH_TEMP -> W
MOVWF PCLATH ; W -> PCLATH
SWAPF STATUS_TEMP,W ; TROCA NIBBLES DE STATUS_TEMP -> W
MOVWF STATUS ; W -> STATUS
SWAPF W_TEMP,F ; TROCA NIBBLES DE W_TEMP -> W_TEMP
SWAPF W_TEMP,W ; TROCA NIBBLES DE W_TEMP -> W
RETFIE ; FINALIZA A INTERRUPÇÃO

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* PROGRAMA PRINCIPAL
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

INICIO
BANK1
MOVLW B'00000110' ; PROGRAMA O TIMER 0 (DIVISOR 1:128)
MOVWF OPTION_REG
MOVLW B'10100000' ; HABILITA INTERRUPÇÃO DO TIMER 0
MOVWF INTCON
BANK0

MOVLW D'61' ; VALOR INICIAL PARA CONTADOR DE ESTOUROS


MOVWF CEST
CLRW ; ZERA OS DÍGITOS DE MINUTO E SEGUNDO
MOVWF SEGUNDO_U
MOVWF SEGUNDO_D
MOVWF MINUTO_U
MOVWF MINUTO_D

GOTO $ ; NÃO FAZ MAIS NADA, TODO O RESTO É FEITO...


; ...PELA INTERRUPÇÃO

Você também pode gostar