# Módulo Contador/Temporizador

O 8051 possui dois módulos temporizadores/contadores (Timer 0 e Timer 1) de 16 bits. Quando na função temporizador, o módulo utiliza um sinal de referência 12 vezes menor que a frequência do oscilador, isto é, na frequência do ciclo de máquina. Já na função contador, esse módulo utiliza um pino de entrada para contar pulsos.

Os pinos de entrada desses dois módulos são: P3.4 para o Timer0 e P3.5 para o Timer1. A configuração desses módulos é realizada pelos registradores TCON e TMOD. Além disso, esses módulos podem gerar interrupções quando a condição de overflow for detectada, isto é, quando o valor máximo de contagem for obtido.

### Registradores

Os dois temporizadores/contadores são controlados pelos registradores Timer Control (TCON) e Timer Mode (TMOD). O registrador TCON, ilustrado na Figura abaixo, pode ser endereçado bit a bit e está localizado no endereço 88H.

![Registrador TCON \[1\]](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_TCON.png)

* TF1: Timer 1 Overflow Flag – Seu valor é determinado pelo hardware.
  * 0: Quando o processador inicia a rotina de interrupção localizada no endereço 001BH.
  * 1: Quando ocorre overflow do timer 1.
* TR1: Timer 1 Run Control – Seu valor é determinado pelo programa.
  * 0: Desativa o timer 1.
  * 1: Ativa o timer 1.
* TF0: Equivalente ao timer 1 (para rotina localizada no endereço 000BH).
* TR0: Equivalente ao timer 1.

Já o registrador TMOD, ilustrado na Figura abaixo, está localizado no endereço 89H e não pode ser endereçado bit a bit. Os quatro bits menos significativos são usado para configuração do Timer 0 e os quatro mais significativos para o Timer 1.

![Registrador TMOD \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_TMOD-1.png)

* Gate:
  * 0: O módulo será habilitado se TR1 (TCON) é 1.
  * 1: O módulo Será habilitado se TR1 (TCON) é 1 e INT1 = 1.
* C/T: Counter/Timer Selector:
  * 0: Temporizador.
  * 1: Contador.
* M1/M0: Mode Selector:
  * 00: Modo 0 – Temporizador/Contador de 8 bits com divisor de frequência.
  * 01: Modo 1 – Temporizador/Contador de 16 bits.
  * 10: Modo 2 – Temporizador/Contador de 8 bits com recarga automática.
  * 11: Modo 3 – Temporizador/Contador de 8 bits. Timer 1 está desativado.

Os registradores contadores desses dois módulos são nomeados como TL e TH. Para o Timer 0, os registradores são referenciados como TL0 e TH0. Já para Timer 1, os registradores são referenciados como TL1 e TH1.

### Modos de Operação

#### Modo 0 - Temporizador/Contador de 8 bits com divisor de frequência

Conforme a Figura abaixo, nesse modo de operação os registradores TL0 e TL1 são utilizados como divisores de clock (apenas 5 bits), já os registradores TH0 e TH1 determinam o valor inicial (8 bits) da contagem. A contagem é crescente até o valor FFH, e cabe ressaltar que o contador é incrementado sempre que os pulsos contabilizados são equivalentes ao valor do divisor.

![Timer1 configurado no modo 0 \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/TimerM0.png)

#### Modo 1 - Temporizador/Contador de 16 bits

Esse modo é equivalente ao descrito anteriormente, contudo os 16 bits são utilizados para contagem, isto é, não há divisor de frequência. A contagem é crescente até o valor FFFFH.

#### Modo 2 - Temporizador/Contador de 8 bits com recarga automática

Conforme a Figura abaixo, nesse modo de operação os registradores TL0 e TL1 são utilizados como contadores. O valor de recarga é determinado pelos registradores TH0 e TH1. A contagem é crescente até o valor FFH, sendo que o processo de recarga ocorre após a condição de overflow ser detectada. No processo de recarga o registrador TLx tem seu valor inicializado de acordo com THx.

![Timer1 configurado no modo 2](https://www.embarcados.com.br/wp-content/uploads/2016/10/TimerM2.png)

#### Modo 3 - Temporizador/Contador de 8 bits

Nesse modo de operação, o registrador TL0 é um temporizador/contador controlado pelo bit TR0 (TCON) e o registrador TH0 é um temporizador/contador controlado pelo bit TR1 (TCON). Além disso, TH0 poderá contar somente os pulsos de clock, isto é, pode operar somente na função de temporizador. Esse modo de operação é ilustrado na Figura abaixo.

A condição de overflow para esses dois temporizadores ativa as seguintes flags:

* TL0: O evento de overflow aciona a flag TF0.
* TF0: O evento de overflow aciona a flag TF1.

Cabe ressaltar que os registradores TL1 e TH1 não são utilizados.

![Timer1 configurado no modo 3 \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/TimerM3.png)

### Aplicações

Neste exemplo considerou-se a frequência do oscilador igual a 11,0592 MHz. Portanto, O ciclo de máquina tem frequência de 0,9216 MHz, isto é, a frequência do oscilador divido por doze. Para realizar o atraso de aproximadamente 1 segundo, o procedimento será realizado 16 vezes, logo cada passo deve gerar um atraso de 0,0625 segundos. Como a frequência de contagem do timer é de 921600 Hz, então serão necessários 921600x0,0625 pulsos para obter o delay desejado. O resultado dessa operação é 57600, sendo que esse valor deve ser subtraído de 65536, isto é, do valor que gera o sinal de estouro do timer. Logo, o valor inicial de contagem é 7936 (65536 - 57600), que em hexadecimal é representado por 1F00H.

```
        ORG 0H ; endereço inicial do programa
        MOV TMOD, #10H ; contador 1 no modo 1 (16 bits), clock = fosc/12
        MOV TCON, #00H ; zera flags
VOLTA:
        MOV P1, #00H ; move valor 00H para P1 (LEDs)
        LCALL DELAY ; chama sub-rotina delay
        MOV P1,#0FFH ; move valor 0FFH para P1 (LEDs)
        LCALL DELAY ; chama sub-rotina delay
        LJMP VOLTA ; vai para VOLTA

; Sub-rotina de delay
DELAY:
        MOV R0, #16 ; sub-rotina delay (1 segundo)
REP: 
        MOV TH1, #1FH ; move valor 1FH para parte alta do contador 1
        MOV TL1, #00H ; move valor 00H para parte baixa do contador 1
        SETB TR1 ; inicia a contagem (TR1 = 1)
        JNB TF1, $ ; fica nesta linha se flag de overflow for zero (TF1 = 0)
        CLR TF1 ; zera flag de overflow do timer
        DJNZ R0, REP ; decrementa R0 e vai para REP se R0 != 0
        CLR TR1 ; para a contagem
        RET ; retorno de sub-rotina

        END ; fim do programa
```

&#x20;Neste exemplo a frequência do oscilador também é igual a 11,0592 MHz, logo o período de contagem é de 1/921600, ou 1,085 us. No entanto, o valor inicial de contagem é zero. Assim, o timer irá gerar uma interrupção a cada 65536x1,085 us, isto é, aproximadamente 71,1 ms.

```
       ORG 0 ; endereço inicial do programa
       SJMP INICIO ; salta para INICIO
       ORG 1BH ; endereço reservado (interrupção por overflow do Timer 1)
       SJMP ROTINA ; salta para ROTINA
 
INICIO:
       MOV TMOD, #10H ; Timer 1, modo 1 (contador de 16 bits)
       MOV TCON, #40H ; liga Timer 1
       MOV IE, #88H ; habilita interrupção por overflow do Timer 1)
       SJMP $ ; espera (LOOP)
 
; Rotina de interrupção
ROTINA:
       CPL P1.0 ; complementa estado do bit 0 do PORT 1
       RETI ; retorno da rotina interrupção
 
       END ; fim do programa
```
