A grande jogada dos timer's, em um microcontrolador, é que você não precisa manter o processador travado em delay aguardando o momento de realizar uma função. Em alguns casos, sem o uso de timer's, seria quase que impossível de realizar determinadas tarefas em conjunto (controle de servo motores por exemplo).
A ineficiência do delay, em alguns casos, pode ser comparada a uma pessoa que tem compromissos durante o dia só que, ao invés de olhar no relógio ou usar um despertador, a pessoa fica parada só contando os segundos até chegar o momento dela realizar determinada tarefa (almoçar, trabalhar, etc.) desperdiçando tempo que poderia ser gasto com outras tarefas.
Os timer's são registradores que servem como contadores em que, a cada pulso de clock, ele realiza um incremento nesse registrador (timer = timer + 1 ou timer++). Após o timer incrementar até o seu valor limite (que depende da quantidade de bits do timer que você esta utilizando) ocorre o que chamamos de "estouro de contagem", este então é zerado e é acionada a interrupção.
TIMER0
O timer0 é um timer de 8 bits, logo, ele pode armazenar até o numero 256.
O timer0 vai começar a incrementar a partir do zero (ou valor que você programar) e quando ele estiver com o valor 256 e passar para 257 (valor que não cabe em 8 bits) ocorre um "estouro" de contagem. Após isso, o flag de interrupção do timer0 é setado e o timer é zerado, começando assim um novo ciclo de contagem.
TIMER 1
O timer1 é um timer de 16 bits, logo, ele pode armazenar até o numero 65.536.
O timer1 vai começar a incrementar a partir do zero (ou valor que você programar) e quando ele estiver com o valor 65.536 e passar para 65.537 (valor que não cabe em 16 bits) ocorre um "estouro" de contagem. Após isso, o flag de interrupção do timer1 é setado e o timer é zerado, começando assim um novo ciclo de contagem.
A entrada de clock utilizada para incremento do timer pode ser configurada da seguinte forma.
Interno:
O clock do oscilador ( cristal ) utilizado no microcontrolador é dividido automaticamente por 4, ou seja, se o oscilador utilizado pelo seu microcontrolador for de 4 MHz o clock utilizado para a contagem do timer será de 1MHz ( 4.000.000 / 4 = 1.000.000).
Externo:
O clock é gerado a cada mudança de estado do sinal externo(proveniente dos pinos para essa finalidade). O incremento pode ser configurado para a borda de subida ou borda de descida.
Em seguida, esse clock passa por um prescaler programável antes de chegar aos timer.
O prescaler funciona como um divisor de frequência de 8 bits em que o valor que você carregar nele, que deve ser multiplos de 2, funcionará como o fator de divisão, ou seja, você pode dividir o sinal de entrada no prescaler em até 256 vezes.
Exemplo:
Sinal de entrada ou Oscilador utilizado = 8.000.000 (8 MHz)
Clock que chega ao prescaler = 4.000.000 (4MHz) // valor do cristal dividido por 4
Valor programado no prescaler = 128 // valor que foi escolhido
Frequência que sai do prescaler = 31.250 ( 31,250 KHz) // ou um pulso a cada 32 microsegundos
E finalmente, o sinal que sai do prescaler, chega ao seu registrador contador que, no caso, é o próprio timer.
O timer sera incrementado conforme a frequência do clock que chega até ele e, quando ocorre o estouro, ele será zerado e gerará uma interrupção.
Exemplo:
Oscilador utilizado = 4.000.000 ( 4MHz)
Clock que chega ao prescaler = 1.000.000 (1MHz) // valor do cristal dividido por 4
Valor programado no prescaler = 64 // valor que foi escolhido
Frequência que sai do prescaler = 15.625 (15,625KHz) // ou um incremento a cada 64 microsegundos
Tamanho do timer = 256 ( 8bits ) // valor máximo que o contador suporta
Valor carregado no timer = 0 // valor que foi escolhido
Tempo das interrupções = 16,384 milisegundos (16,384 ms) // a cada 16,384 ms ocorre uma interrupção
O valor que esta presente no registrador pode ser alterado por você durante a execução do programa. Por exemplo, se o timer suporta até o numero 256 e você escrever um valor aleatório (porém menor que 256) nesse registrado, o contador passará a incrementar a partir do valor que você carregou nele. Assim você adiantará a interrupção, tornando-a mais rápida.
Se você precisa de um tempo maior para realizar determinada tarefa(1 segundo por exemplo), o método é criar um sistema via software que imite um relógio. Por exemplo: a cada interrupção faça o incremento de uma variável x, se x for igual a y faça determinada tarefa.
Agorá que você entendeu ( pelo menos espero que sim ^^" ) o que é e como funciona o timer, vamos aos códigos .
O exemplo abaixo utiliza um pic 16f628a e faz um led ligado ao pino a0 piscar a 1Hz utilizando o timer0 :
__________________________________________
#include <16f628a.h> // Microcontrolador utilizado
#use delay(clock = 4000000) // Cristal de 4MHz utilizado
#fuses intrc_io, nowdt, nomclr, put,nolvp // Fusiveis
#int_timer0 // é para cá que o seu programa será desviado quando ocorrer a interrupção
void trata_timer0 () // método para tratamento da interrupção
{
int1 teste; // variável de 1 bit com nome led
int x; // variável de 8 bits com nome de x
set_timer0(131+get_timer0()); //escreve o numero 131 + o que se passou no timer0
x++; // incrementa x
if (x == 62) // se x for igual a 62 , ou seja, se já tiverem passado 500ms
{
x = 0; // x será igual a zero
teste = !teste; // inverte o estado de teste (se for 1 será igual a 0 e vice versa)
output_bit (pin_a0, teste); //coloca o valor de teste no pino a0
}
}
void main ()
{
setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_64 ); // timer0 com clock interno e dividido por 64
set_timer0(131); // carrega o valor 131 no registrador do timer
enable_interrupts (global | int_timer0); // habilita interrupções e libera o timer0
while (true); // loop infinito aguardando a interrupção para trata-la
}
__________________________________________Timer0 :
#int_timer0
setup_timer_0 ( RTCC_"INTERNAL ou EXTERNAL" | RTCC_DIV_ xx ) ;
enable_interrupts ( global | int_timer0) ;
set_timer0 ( "valor") ;
get_timer0 ( ) ;
Timer1:
#int_timer1
setup_timer_1 ( T1_"INTERNAL ou EXTERNAL" | T1_DIV_BY_xx ) ;
enable_interrupts ( global | int_timer1 ) ;
set_timer1 ("valor") ;
get_timer1 ( );
Vale ressaltar que os timers também têm outras funções alem de servirem como temporizadores, mas isso veremos em um outro post.
io solo conde vitorio terra nova
ResponderExcluirNão entendi muito xD, mas obrigado pelo comentário :)
Excluir