UTILIZANDO OS TIMERS INTERNOS

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

UTILIZANDO OS TIMERS INTERNOS

Mensagempor __JEREK__ » 14 Out 2006 20:13

Esse post eu gostar de salvar do forun antigo.

Citando o livro de Fábio Perreira (Microcontroldores PIC - Programação em C, pag 258) + informações da Net + as formulas cedidas por Away

UTILIZANDO OS TIMERS INTERNOS

Uma técnica muito interessante para implementar bases de tempo precisas com com
o timer interno dos PICs é a chamada acúmulo de erros.

Essa técnica consiste em implementar um contador de software que decrementado a
cada ciclo de interrupções, e uma vez que o seu valor atinja um determinado limite,
se subtrai-se a frequência de entrada, mantendo-se o resto no reistrador.

Vejamos um exemplo prático:
suponhamos que seja necessário implementar uma base de tempo de 1 segundo utilizando
o timer 0 (zero) num PIC com clock do cristal = 4Mhz.

O primeiro passo é selecionar o maior fator de divisão do prescaler que resulte
em uma frequência interira. No nosso caso, o maior fator de divisão é 64, resultando
em uma frequência de 15625 Hz (na saída).

Fosc é um sinal gerado internamnte no PIC pelo circuito de clock e é igual a
frequência de clock dividida por quatro (exemplo 4Mhz/4 = fosc 1.000.000).

Ou seja, o valor do Fosc / prescale ( 1000000 / 64 = 15625 )

Imagem

O fator de divisão é diferente para cada timer, veja tabela:


Imagem

(Alguem pode me dizer se o Timer2 e 3 são 16Bits????)

Este valor (15625) será carregado em uma variável de contagem e a cada ciclo de
interrupção, subtrai-se 256 dessa variável. O valor 256 é utilizado pois consiste
no fator de divisão natural do Timer0, que nos PICs da série 16 é sempre de 8 bits.
ou seja 8bits (11111111) = 256

Se o valor dela for igual ou menor que zero, soma-se 15625 à variável, executan-se
os comandos relativos ao evento de passagem de 1 segundo e o processo reinicia.

Observe que o resto presente na variável de contagem (erro residual da divisão) é
acumulado durante a contagem, reduzindo o erro total a praticamente zero.

O incoveniente dessa técnica é que o intervalo de tempo entre cada evento (no caso
de 1 segundo) não é constante, o que en alguns casos pode ser inaceitavel.

vejamos um exemplo para piscar um led conectado ao pino RC2 a uma frequência de 1Hz.

FORMULA

Dados necessários:
Cristal = 4000000 (4Mhz)
Prescale = 64
Frequência procurada (em segundos) = 1seg / 1Hz = 1

Fórmula geral:
TCY * PS * V = tempo em segundos

//---------------------------


Fórmula TCY:
TCY = 1seg / Fosc
1 / (4000000 / 4)
1 / 1000000
TCY = 0,000001

//---------------------------

PS = Prescale selecionado para o timer, nesse caso 64
PS = 64

//----------------------------

Fórmula V:

V = Valor
V = Frequencia procurada em segundos / ( TCY * Prescale selecionado para o timer, nesse caso 64 )
V = (1seg / 1Hz) / (0,000001 * 64)
V = 1 / (0,000001 * 64)
V = 1 / (0,000064)
V = 15625

//-----------------------------

TCY * PS * V = tempo em segundos

0,000001 * 64 * 15625 = 1seg

Frequência = 1 / tempo em segundos
Frequência = 1 / 1
Frequência = 1Hz


Agora, vamos fazer o calculo para achar o valor que vamos colocar no set_timer, esse é o valor que realmente
interessa para agente.

Valor set_timer = Valor máximo do timer selecionado - V
Valor set_timer = 256 - 15625
Valor set_timer = -15369

*Obs.: Se o valor der negativo como nesse exemplo, teremos que usar IF para poder chegar
na frequência que queremos.

- Vamos achar o valor para colocar no IF

Valor do IF = Raiz quadrada de Valor
Valor do IF = Raiz quadrada de 15625 (o simbolo não quis aparecer)
Valor do IF = 125
*Obs.: Não sei como vocês fazem, mas eu vou no Excel e digito em uma célula =SQRT(15625) e ele mostra o valor da raiz quadrada

- Agora, o valor do set_timer
Valor set_timer = Valor máximo do timer selecionado - raiz quadrada de V
Valor set_timer = 256 - 125
Valor set_timer = 131

USANDO NA PRATICA

Código: Selecionar todos
#include <16f628a.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,PUT,NOLVP

#int_timer0
void trata_t0 ()
{
   static boolean led;
   static int conta;   set_timer0(131+get_timer0());   // reinicia o timer 0 em 131 mais a contagem que já passou


   conta++;   

   if (conta == 125)       // se já ocorreram 125 interrupções
   {
      conta=0;
      led = !led;       // inverte o led
      output_bit (pin_b0,led);
   }
}

main()
{

   // configura o timer 0 para clock interno e prescaler dividindo por 64
   setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_64 );
   set_timer0(131);        // inicia o timer 0 em 131

   // habilita interrupções
   enable_interrupts (global | int_timer0);
   while (true);        // espera interrupção (loop infinit)
}


TESTE NO PROTEUS

Imagem

Configuração do Clock
Imagem
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x