Ir ao conteúdo
  • Cadastre-se

Dúvida Fórmula Timer0


cezar.opaleiro

Posts recomendados

Ae galera!

Com com uma dúvida aqui...alguém sabe me dizer qual dessas fórmulas é a correta, para cálcular o tempo no timer0?

(1) Tempo = Freq. OSC / 4 * 256 * (256-TMR0) * Prescaler

(2) Tempo = Freq. OSC / [4 * Prescaler * (256 - TMR0)]

Eu preciso do tempo de 500ms, então fiz o seguinte cálculo considerando a fórmula (1).

Tempo = 4000000/4 *256*244*8 = 0,499712 ~500ms

Alguém poderia me ajudar?

Abrs!

Link para o comentário
Compartilhar em outros sites

Ambas estão corretas (lembre - se a ordem dos fatores não altera o produto).

mas eu usaria a de cima que está escrita matematicamente correta, com o parenteses / colchetes para garantir que o calculo não saira errado.

abs.

Ae Felipão!

valeu pela dica...mas note que uma das fórmulas tem um 256 a mais...

Abrs!

Link para o comentário
Compartilhar em outros sites

Pessoal, tem um erro na fórmula apresentada acima.

Primeiro, temos de entender como o TIMER0 funciona, pelo menos nas linhas 12f e 16f.

O timer0 é um contador de 8 bits, portanto ele pode contar de 0 até 255, e quando ele passaria para 256, ocorre um estouro, o qual pode gerar uma interrupção, e o valor do contador passa a ser zero.

Na grande maioria dos PIC's, temos um PRESCALER, que é um divisor programável colocado entre uma base de clock ( geralmente ligada no próprio clock do PIC ), com valores variando de 1 até 256.

Resumindo, se programarmos o Prescaler em 256, quando ocorrerem 256 pulsos de clock, ele irá fornecer um pulso ao TIMER0, que irá aumentar seu valor de 1 .

Nos PIC's, podemos generalizar que o clock interno dos timers é a frequência do oscilador dividido por 4.

Assim, juntando isso tudo temos a seguinte fórmula para TIMER0 :

tempo = prescaler/1000 X 4/fclock x (256-contagem inicial )

Nessa fórmula, tempo está em milisegundos, e fclock está em Megahertz.

Por exemplo, usando Fclock de 4 Mhz, prescaler = 256 e contagem inicial de 156, temos :

tempo = 256/1000 * 4/4 * ( 256-156 ) = 25,6 milisegundos.

Se aumentarmos o clock para 8 Mhz, teremos tempo = 12,8 milisegundos.

Se usarmos clock de 4 Mhz, prescaler de 256, e contagem inicial = 0 , teremos o maior tempo possível, que é de 65,536 milisegundos.

Apenas como curiosidade, a fórmula para uso no TIMER1 é bem semelhante, basta apenas lembrarmos que ele é um contador de 16 bits, e pode contar até 65536 :

tempo = prescaler/1000 * 4/fclock * (65536-contagem inicial)

Como exemplo, supondo fclock = 4 Mhz, prescaler = 8 e contagem inicial = 0 temos o maior tempo possível que é de 524,288 milisegundos.

Para termos uma interrupção bem precisa, ou seja, para obtermos numeros INTEIROS de milisegundos, sugiro sempre o uso do Timer1.

Por exemplo, para termos uma interrupcão a cada exatos 500 milisegundos, usando clock de 4 Mhz, basta usarmos Prescaler = 8 e contagem inicial = 3036.

Paulo

Link para o comentário
Compartilhar em outros sites

Pessoal, tem um erro na fórmula apresentada acima.

Primeiro, temos de entender como o TIMER0 funciona, pelo menos nas linhas 12f e 16f.

O timer0 é um contador de 8 bits, portanto ele pode contar de 0 até 255, e quando ele passaria para 256, ocorre um estouro, o qual pode gerar uma interrupção, e o valor do contador passa a ser zero.

Na grande maioria dos PIC's, temos um PRESCALER, que é um divisor programável colocado entre uma base de clock ( geralmente ligada no próprio clock do PIC ), com valores variando de 1 até 256.

Resumindo, se programarmos o Prescaler em 256, quando ocorrerem 256 pulsos de clock, ele irá fornecer um pulso ao TIMER0, que irá aumentar seu valor de 1 .

Nos PIC's, podemos generalizar que o clock é a frequência do oscilador dividido por 4.

Assim, juntando isso tudo temos a seguinte fórmula para TIMER0 :

tempo = prescaler/1000 X 4/fclock x (256-contagem inicial )

Nessa fórmula, tempo está em milisegundos, e fclock está em Megahertz.

Por exemplo, usando Fclock de 4 Mhz, prescaler = 256 e contagem inicial de 156, temos :

tempo = 256/1000 * 4/4 * ( 256-156 ) = 25,6 milisegundos.

Se aumentarmos o clock para 8 Mhz, teremos tempo = 12,8 milisegundos.

Se usarmos clock de 4 Mhz, prescaler de 256, e contagem inicial = 0 , teremos o maior tempo possível, que é de 65,536 milisegundos.

Apenas como curiosidade, a fórmula para uso no TIMER1 é bem semelhante, basta apenas lembrarmos que ele é um contador de 16 bits, e pode contar até 65536 :

tempo = prescaler/1000 * 4/fclock * (65536-contagem inicial)

Como exemplo, supondo fclock = 4 Mhz, prescaler = 8 e contagem inicial = 0 temos o maior tempo possível que é de 524,288 milisegundos.

Para termos uma interrupção bem precisa, ou seja, para obtermos numeros INTEIROS de milisegundos, sugiro sempre o uso do Timer1.

Por exemplo, para termos uma interrupcão a cada exatos 500 milisegundos, usando clock de 4 Mhz, basta usarmos Prescaler = 8 e contagem inicial = 3036.

Paulo

Olá Paulão!

Posso fazer assim?

Meu Preescaler tá com 8:1 e o valor inicial do Timer0 como 12.

8/1000 *1*244 = 1,952ms (cada interrupção)

1,952x = 500

x = ~256,1

No código:


void interrupt(){ //interrupção
counter++; // Incrementa valor de counter a cada Interrupção.
if(PORTA.f1 == 0 && counter <= 256){
pulso++; //incrementa o pulso
}
TMR0 = 12; // Valor Inicial de TMR0 (256 - 12 = 244).
INTCON = 0b00100000; // Seta T0IE (bit 5) e Limpa T0IF (bit 2).

}// fim interrupção

Na verdade eu quero 499ms deixando 1ms para o tempo aproximado que o PIC leva para executar as outras funções até chegar a amostragem no LCD.

Posso fazer dessa forma?

Abrs!

Link para o comentário
Compartilhar em outros sites

  • 2 anos depois...

tempo = prescaler/1000 * 4/fclock * (65536-contagem inicial)

to tentando trabalhar com o TIMER1 mas sem sucesso... minhas duvidas são com os calculos..

a "fclock", deve ser substituida por "4" ou por "4.000.000" , se eu estiver usando um cristal de 4MHz

digamos que quero chamar a interrupção a cada 10 segundos, como calcular o tempo inicial do timer1 ?? e como devo substituir o "tempo" da formula, devo colocar 10 seg, 10.000 miliseg ou devo colocar em microsegundos??

depois a questão dos bits

TMR1L = bits de 0 a 7 ,

TMR1H = bits de 8 a 15, isso ta certo ???

programo em C, no MICKROC...

Link para o comentário
Compartilhar em outros sites

CIS,

Não tem aquele prescaler/1000 não, fica somente prescaler.

Antes eu utilizava a fórmula, hoje prefiro fazer a conta no braço mesmo. Mais fácil.....

Copiando de outro tópico que respondi:

você usa um cristal de 20Mhz. Então o PIC trabalha internamente a 5Mhz.

Imaginando que vamos utilizar o TIMER1 com prescaler de 8, então fica:

O TIMER1 irá correr a 5Mhz/8=625000hz

Temos a frequência, para ter o período, calculamos o inverso da mesma, sendo 1/625000.

Isso nos dá o valor de 1.6uS (micro-segundos).

Ou seja, esse tempo é o gasto para cada incremento do TIMER1.

Sabemos que o TIMER 1 é um contador de 16bits, ou seja, ele conta de 0 até 65536. Dessa forma, vamos calcular qual o tempo máximo que o TIMER1 gera com clock de 20Mhz.

Temos a seguinte regra de três:

1 incremento----------------->1.6uS ou 0.0000016 segundos

65536 incrementos-----------> X

Isolando o X, temos que X=65536 * 0.0000016

Portanto, o TIMER1 consegue gerar um tempo máximo de 0.104 segundos.

Mas e se eu quiser 1 segundo? Simples, veja:

Como o TIMER 1 está gerando um tempo "quebrado", vamos calcular quantos incrementos ele leva para gerar 0.1 segundos. Fica:

1 incremento ----------------> 0.0000016 segundos

X incrementos---------------> 0.1 segundos

Isolando o X, temos que X = 62500 incrementos.

Ou seja, o PIC precisa incrementar o TIMER 1 62500 vezes para gerar 0.1 segundos.

Como o TIMER 1 vai até 65536, subtraímos o valor anterior desse, assim:

Timer 1 começa a contar em 65536-62500, ou em 3036!

Esse valor é o preload.

Certo, já fizemos as contas para gerar 0.1 segundos. Ora, se ele gera 0.1 segundos, para gerar 1 segundo, apenas deve gerar 0.1 segundos 10 vezes!!!!! Ou seja, 10*0.1=1! Uau!!!!

Mas como tudo isso fica no PIC?

Fiz um exemplo, para o CCS e não MikroC:

Circuito:

teste_timer_1.png

Código:

#include <16F877A.h>            //O PIC utilizado, obrigatório!

#FUSES NOWDT //Sem Watch dog, evitando reset
#FUSES HS //Crystal de oscilação > QUE 4mhz
#FUSES PUT //Tempo de início do PIC
#FUSES NOPROTECT //Codigo sem proteção de leitura, software livre!
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection


#use delay(clock=20000000) // Definição do clock utilizado. Obrigatório!

int16 q=0; //Variável que incrementa a cada 0.1s dentro da interupção do timer1.

#int_TIMER1 //Interrupção do Timer1
void temp1s(void) //Funcão. O que deverá ser feiro a cada interrupão.
{
q++; //Variável q incrementada a cada estouro do Timer1
if (q==10)
{
q=0;
output_toggle (PIN_B0);
}
set_timer1 (3036); //Preload do Timer1
}

void main()
{
output_low (PIN_B0);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configuração do Timer1 para clock interno = 1E6 dividido por 8
set_timer1 (3036); //Preload do Timer1
enable_interrupts(INT_TIMER1); //Habilita interrupção timer1
enable_interrupts(global); //habilita interrupcão global

while(TRUE);
}

O led deve piscar em intervalos de 1 segundo.

Fica como exercício descobrir como fazer o atraso de 10 segundos!

Falou

Link para o comentário
Compartilhar em outros sites

  • 3 meses depois...
Como o TIMER 1 está gerando um tempo "quebrado", vamos calcular quantos incrementos ele leva para gerar 0.1 segundos. Fica:

1 incremento ----------------> 0.0000016 segundos

X incrementos---------------> 0.1 segundos

Isolando o X, temos que X = 62500 incrementos.

MatheusLPS de onde veio esse 62500 ?

pode deixar, ja to acompanhando o raciocínio.

seria 0,1/0,0000016.

Link para o comentário
Compartilhar em outros sites

  • 3 meses depois...
CIS,

Não tem aquele prescaler/1000 não, fica somente prescaler.

Antes eu utilizava a fórmula, hoje prefiro fazer a conta no braço mesmo. Mais fácil.....

Copiando de outro tópico que respondi:

você usa um cristal de 20Mhz. Então o PIC trabalha internamente a 5Mhz.

Imaginando que vamos utilizar o TIMER1 com prescaler de 8, então fica:

O TIMER1 irá correr a 5Mhz/8=625000hz

Temos a frequência, para ter o período, calculamos o inverso da mesma, sendo 1/625000.

Isso nos dá o valor de 1.6uS (micro-segundos).

Ou seja, esse tempo é o gasto para cada incremento do TIMER1.

Sabemos que o TIMER 1 é um contador de 16bits, ou seja, ele conta de 0 até 65536. Dessa forma, vamos calcular qual o tempo máximo que o TIMER1 gera com clock de 20Mhz.

Temos a seguinte regra de três:

1 incremento----------------->1.6uS ou 0.0000016 segundos

65536 incrementos-----------> X

Isolando o X, temos que X=65536 * 0.0000016

Portanto, o TIMER1 consegue gerar um tempo máximo de 0.104 segundos.

Mas e se eu quiser 1 segundo? Simples, veja:

Como o TIMER 1 está gerando um tempo "quebrado", vamos calcular quantos incrementos ele leva para gerar 0.1 segundos. Fica:

1 incremento ----------------> 0.0000016 segundos

X incrementos---------------> 0.1 segundos

Isolando o X, temos que X = 62500 incrementos.

Ou seja, o PIC precisa incrementar o TIMER 1 62500 vezes para gerar 0.1 segundos.

Como o TIMER 1 vai até 65536, subtraímos o valor anterior desse, assim:

Timer 1 começa a contar em 65536-62500, ou em 3036!

Esse valor é o preload.

Certo, já fizemos as contas para gerar 0.1 segundos. Ora, se ele gera 0.1 segundos, para gerar 1 segundo, apenas deve gerar 0.1 segundos 10 vezes!!!!! Ou seja, 10*0.1=1! Uau!!!!

Mas como tudo isso fica no PIC?

Fiz um exemplo, para o CCS e não MikroC:

Circuito:

teste_timer_1.png

Código:

#include <16F877A.h>            //O PIC utilizado, obrigatório!

#FUSES NOWDT //Sem Watch dog, evitando reset
#FUSES HS //Crystal de oscilação > QUE 4mhz
#FUSES PUT //Tempo de início do PIC
#FUSES NOPROTECT //Codigo sem proteção de leitura, software livre!
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection


#use delay(clock=20000000) // Definição do clock utilizado. Obrigatório!

int16 q=0; //Variável que incrementa a cada 0.1s dentro da interupção do timer1.

#int_TIMER1 //Interrupção do Timer1
void temp1s(void) //Funcão. O que deverá ser feiro a cada interrupão.
{
q++; //Variável q incrementada a cada estouro do Timer1
if (q==10)
{
q=0;
output_toggle (PIN_B0);
}
set_timer1 (3036); //Preload do Timer1
}

void main()
{
output_low (PIN_B0);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configuração do Timer1 para clock interno = 1E6 dividido por 8
set_timer1 (3036); //Preload do Timer1
enable_interrupts(INT_TIMER1); //Habilita interrupção timer1
enable_interrupts(global); //habilita interrupcão global

while(TRUE);
}

O led deve piscar em intervalos de 1 segundo.

Fica como exercício descobrir como fazer o atraso de 10 segundos!

Falou

Alguem poderia fazer com um cristal de 4MHz e pre scale de 64 ?

Link para o comentário
Compartilhar em outros sites

Alguem poderia fazer com um cristal de 4MHz e pre scale de 64 ?

Bom, o TIMER1 não possui prescaler igual a 64. As únicas opções disponíveis são 1, 2, 4 e 8.

Mas o TIMER0 sim possui prescaler de 64. Mas veja que esse é um péssimo valor para se escolher como base de tempo. Só gera tempo quebrado.

Vamos lá. Reescrevendo o que eu disse anteriormente para o caso do TIMER0, também conhecido como RTCC:

Suponha que você usa um cristal de 4Mhz. Então o PIC trabalha internamente a 1Mhz. Ou seja, Fosc/4.

Imaginando que vamos utilizar o TIMER0 com prescaler de 64, então fica:

O TIMER0 irá correr a 1Mhz/64=15625hz

Temos a frequência, para ter o período, calculamos o inverso da mesma, sendo 1/15625.

Isso nos dá o valor de 64uS (micro-segundos).

Ou seja, esse tempo é o gasto para cada incremento do TIMER0.

Sabemos que o TIMER0 é um contador de 8bits, ou seja, ele conta de 0 até 255. Dessa forma, vamos calcular qual o tempo máximo que o TIMER0 gera com clock de 4Mhz.

Temos a seguinte regra de três:

1 incremento----------------->64uS ou 0.000064 segundos

255 incrementos-----------> X

Isolando o X, temos que X=255 * 0.000064

Portanto, o TIMER0 consegue gerar um tempo máximo de 0.01632 segundos.

Mas e se eu quiser 1 segundo?

Com esse prescaler, não dá. O mesmo gera tempos quebrados.

O que pode ser feito seria setar o mesmo com um prescaler de 99.

Com esse valor geraremos um tempo de:

255-99 = 156

156*0.000064 = 9,984mS (mili segundos). Quase 10 mS.

Com esse tempo não conseguimos gerar um tempo correto. No máximo 998,4mS, contando 100 vezes.

Com isso, a cada segundo temos um erro de 1,6 ms. Ou seja, a cada 625 segundos, pouco mais de 10 minutos, teremos 1 segundo de atraso.

Portanto, para uma base de tempo inteira, 64 não é um bom prescaler.

Falou

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!