Sei sulla pagina 1di 4

Estudo do Timer e Interrupção

TIMER 0

O Timer 0 é um contador interno e pode contar estímulos externos ou


contar internamente, utilizando o oscilador. Ele possui um prescaler de até
1:256 e tem 8 bits, ou seja, para um prescaler de 1:1, haverá um overflow
(estouro) a cada 256 contagens (0 à 255). Mas este tipo de PIC o prescaler
começa em 1:2. Para o controle do Timer 0, vamos utilizar os registros
especiais OPTION_REG e INTCON, como segue:

OPTION_REG

Nome /RBPU INTEDG TOCS TOSE PSA PS2 PS1 PS0


Bit 7 6 5 4 3 2 1 0

/RBPU = 0: Habilita os pull-ups nos pinos do PORTB configurados como


entrada.
/RBPU = 1: Desabilita pull-ups.

INTEDG = 0: A interrupção externa (RB0) ocorrerá na borda de descida


INTEDG = 1: A interrupção externa (RB0) ocorrerá na borda de subida.

TOCS = 1: Incremento a cada transição no pino RA4/T0CKI.


TOCS = 0: Incremento a cada ciclo de máquina.

TOSE = 1: Incremento na borda de descida.


TOSE = 0: Incremento na borda de subida.

PSA = 1: Prescaler (divisor de freqüência) aplicado ao WDT.


PSA = 0: Prescaler (divisor de freqüência) aplicado ao TMR0.

PS2 PS1 PS0 TMR0 WDT


0 0 0 1:2 1:1
0 0 1 1:4 1:2
0 1 0 1:8 1:4
0 1 1 1:16 1:8
1 0 0 1:32 1:16
1 0 1 1:64 1:32
1 1 0 1:128 1:64
1 1 1 1:256 1:128
Para utilizarmos a interrupção TMR0, devemos configurar o registro
INTCON.T0IE e também o registro INTCON.GIE (interrupção geral). Deste
modo, toda vez que houver um estouro do TMR0, o sinalizador (flag)
INTCON.T0IF será configurado, devendo ser limpo.
INTCON

INTCON, geralmente, é o registrador que controla as interrupções.

Nome GIE PEIE T0IE INTE RBIE T0IF INTF RBIF


Bit 7 6 5 4 3 2 1 0

GIE (Global Interrupt Enable – Habilitação Global de Interrupções), é


responsável pelo controle geral das interrupções. Se o bit GIE estiver em nível
lógico “1”, podem ocorrer interrupções. Se o bit GIE estiver em nível lógico “0”,
não podem ocorrer interrupções.

T0IE é responsável pela autorização de retorno a zero do timer. Se o bit


T0IE estiver em nível lógico “1”, habilita a interrupção que deixa o timer ser
zerado. Se o bit T0IE estiver em nível lógico “0”, o timer não pode ser zerado.

T0IF é o flag de sinalização que faz o timer retornar a zero. Para zerar o
timer, coloque nível lógico “0” no bit T0IF.

Contando um tempo com o Timer 0

Vamos supor que queremos contar um tempo com o timer0, tempo será
de 100us e o prescaler (divisor de freqüência) será de 1:2.
Neste caso, só teremos a opção 1:2, no prescaler, quando
configurarmos zero no PS2, PS1 e PS0.
Quando fazemos o prescaler igual a 1:1, estamos fazendo com que o
TMR0 incremente seu valor em 1 a cada ciclo de máquina, ou seja, para um
cristal de 4MHz, o incremento se dará a cada 1us. Mas como neste PIC o valor
mínimo de prescaler é de 1:2, deve-se multiplicar este tempo por 2.
O estouro do timer0 ocorre quando o TMR0 chega a contagem 256,
portanto, no nosso caso, haverá um estouro a cada 256us, mas o que
queremos é 100us.
Basta, então inicializarmos o TMR0 com o valor de 255 – 100 = 155.

Exemplo
PROJETO 23 – Façamos um LED piscar a cada 1 segundo utilizando o
Timer 0.

Com o TMR0 começando a contar do 155 até o 255. Lembrando que o


prescaler é de 1:2, então o calculo fica assim:

Valor inicial do TMR0 = 255 – 100 = 155


Calculando è tempo do timer0 x prescaler = tempo do estouro do timer0
Tempo do timer0 = 100
prescaler = 2
Tempo do estouro do timer0 = 100 x 2 = 200us
Valor do cont = (1s/ 200us) = (1000000us/200us) = 5000
cont = 5000

int cont = 0; //criando uma variável de tipo inteira chamada cont de valor zero

void interrupt ( ) //rotina de interrupção


{
cont++; //incrementa o valor de cont a cada interrupção
TMR0 = 155; //Valor inicial para o Timer0, conta de 155 a 255
INTCON = 0xA0; //Configura T0IE e limpa T0IF, em bin 0b10100000
}

void main ( )
{
OPTION_REG = 0x80; //Atribui prescaler de 1:2 ao TMR0, em bin 0b10000000
TMR0 = 155; //Valor inicial para o Timer0
INTCON = 0xA0; //Habilita a interrupção do TMR0, configura os registros GIE e T0IE
//0b10100000
TRISB = 0b0; //configura o pino B0 como saída
PORTB = 0b0; //desliga o pino D0, LED apagado

cont = 0;

while(1)
{
if(cont >= 5000) //se cont for maior ou igual a 5000
{
portb.f0 = ~ portb.f0; //inverte o estado do pino B0
cont = 0; //zera a variável
}
}
}

Ajustando alguns valores:


Seguindo o exemplo acima, vamos ajustar os valores para um prescaler de
1:32, então ficará assim:

Valor inicial do TMR0 = 255 – 156 = 99


Calculando è tempo do timer0 x prescaler = tempo do estouro do timer0

Tempo do timer0 = 156


prescaler = 32
Tempo do estouro do timer0 = 156 x 32 = 4992us
Tempo do estouro do timer0 = 4992us

Valor do cont = (1s/ 4992us) = (1000000us/4992us) = aproximadamente 200


cont deve ser igual a 200
int cont = 0;

void interrupt ( )
{
cont++; //incrementa o valor de cont a cada interrupção
TMR0 = 99; //Valor inicial para o Timer0, conta de 156 a 255
INTCON = 0xA0; //Configura T0IE e limpa T0IF
}

void main ( )
{
OPTION_REG = 0x84; //Atribui prescaler de 1:32 ao TMR0
TMR0 = 99; //Valor inicial para o Timer0
INTCON = 0xA0; //Habilita a interrupção do TMR0, configura os registros GIE e T0IE

TRISB = 0b0; //configura o pino B0 como saída


PORTB = 0b0; //desliga o pino D0, LED apagado

cont = 0;

while(1)
{
if(cont == 200)
{
portb.f0 = ~ portb.f0; //inverte o estado do pino B0
cont = 0;
}
}
}

Potrebbero piacerti anche