Página 1 de 1

frequencia no timer0

MensagemEnviado: 09 Jun 2008 11:19
por lafourcade
Amigos
Estou querendo fazer um relogio mais ou menos preciso e com custo bem baixo. A precisão não precisa ser "o bixo" dando uns 30s de diferença por dia, tranquilo. Eu fiz alguma coisa com o 16f628 usando o CCS e ficou legal. Ultimamente eu estou usando o pic 16F916 e o compilador de c do hitech e não consigo ter os valores, que eu calculo para o timer, na prática.

é algo mais ou menos assim:


#include <pic.h>

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & CP & CPD & BOREN & FCMDIS);

typedef struct RELOGIO
{
signed int usegundo; signed int dsegundo; unsigned um_ds:1;
};
bank2 volatile struct RELOGIO relogio;

void main (void){

OSCTUNE = 0b00000000;
OSCCON = 0b01110100; // 8 Mhz com oscilador interno
OPTION = 0x82; // Preescaler TIMER0 8
TMR0 = 131;
T0IE = 1; // Habilita a IRQ de estouro do timer 0
PEIE = 1; // Habilita as IRQs dos periféricos internos do PIC
GIE = 1; // Habilita todas as IRQs programadas

while(1){

//display(relogio.dsegundo); //mostra no display o relogio em decimos

if (relogio.um_ds) {

relogio.dsegundo++; // contador de decimos de segundo
}
}
}


static void interrupt global(void)
{
// Testa se houve IRQ do timer0 FOSC/(4*PRESCALER*TAM_TIMER)
if((T0IF)&&(T0IE)) //Frequencia = 8MHz/(4*8*125)
{
T0IF = 0;
TMR0 = TMR0 + 131; // 256 - 125 = 131;

if (relogio.usegundo >= 200)
{
relogio.usegundo = 0;
relogio.um_ds = 1;
}
relogio.usegundo++;

}
}

não tenho outras interrupções no programa.
Eu carrego o valor atual do timer0 junto com o incremento para evitar de perder ciclos que ja ocorreram.
Ele da diferença. No próprio simulador do hitech onde deveria dar 100ms, exatamente, da 100.54, com a linha da rotina de escrita no display comentada, e no pic (físico) da diferença de uns dois segundos a cada 10.
Se eu coloco outras interrupções, junto, ai que a coisa fica uma bagunça, muda muito os valores de tempo.

Alguém poderia me ajudar?

MensagemEnviado: 09 Jun 2008 19:00
por Vonnilmam
Eu gostaria de sugerir para o colega que utilize um timer keeper para fazer o relogio em sí, além ser muito mais pratico voce terá precisão...

Veja que se voce utilizar o timer do pic tem que entender que voce terá sempre um erro de frequencia devido a latencia de recarga dos registradores e justamente essa latencia que produz os erros de tempo.

Se voce tiver erros de latencia, isso irá se acumular produzindo cada vez mais erros de tempo de contador do relogio....

Boa sorte,

Von

MensagemEnviado: 09 Jun 2008 19:00
por Vonnilmam
Eu gostaria de sugerir para o colega que utilize um timer keeper para fazer o relogio em sí, além ser muito mais pratico voce terá precisão...

Veja que se voce utilizar o timer do pic tem que entender que voce terá sempre um erro de frequencia devido a latencia de recarga dos registradores e justamente essa latencia que produz os erros de tempo.

Se voce tiver erros de latencia, isso irá se acumular produzindo cada vez mais erros de tempo de contador do relogio....

Boa sorte,

Von

MensagemEnviado: 09 Jun 2008 23:02
por gilbert_SS
Cara, uma dica simples.
Vc quer fazer um relógio, certo? Como é o teu circuito? Ele precisa ser isolado?
Caso não seja necessário este ser isolado, dá uma olhada nas interrupções por mudança de estado do PORTB. Depois faz um circuito para ler zero-cross(sinal da rede elétrica). A rede oscila a 60Hz. Por mudança de estado dá 120 interrupções por segundo, isto se vc considerar as duas bordas, caso considerar apenas uma borda vc terá 60 por segundo.

daí vc tem sua base de tempo!

Pra ajudar mais ainda...
Se vc usar 4 displays, ou quatro digitos, vc presica 4 fases. Ao ler o sinal de uma das bordas de Zero -Cross chavei o display 1, dai programa um timer (ex Timer0) para 4100us quando este estourar chaveia display 2, aguarda nova mudanca de estado, quando ocorrer chaveia display 3, programa mais uma vez o teu timer, quando estourar chaveia display 4, aguarda novamente mudanca estado (Zero - Cross) e inicia tudo denovo.

Isto por fase vc tera uns 4100us para fazer muita coisa e sobra tempo adoidado!!!!

Pra ti facilitar, usa um osciloscópio.
Teu relógio vai ter uma boa precisão e não terá estes erros pro recarregar teus registradores.

MensagemEnviado: 18 Jun 2008 22:52
por Budweiser
Usa logo um DS1307! Facin de fazer e é um chip relógio/calendário...
Tem doido vendendo este CI a R$7,00 no M.L.

MensagemEnviado: 18 Jun 2008 23:38
por Maurício
Vixe!!!!

HT1380 não custa nem 1 dólar, na Cika.

[]'s

MensagemEnviado: 19 Jun 2008 13:04
por lafourcade
Ok Obrigado a todos

MensagemEnviado: 19 Jun 2008 13:52
por guest2003
Ola amigo,

Não sei se vc postou o codigo completo... mas veja o seguinte:

if (relogio.usegundo >= 200)
{
relogio.usegundo = 0;
relogio.um_ds = 1;
}
relogio.usegundo++;


Aqui na Int vc liga um flag... relogio.um_ds para usar no Main... no while(1)

Porem la voce nao desliga o danado... :)

Entonsis... a coisa corre como louca !! eheh

[]'s

MensagemEnviado: 19 Jun 2008 17:12
por lafourcade
Ola

É que eu desligo a flag quando leio no main. Ma mesmo assim obrigado.

MensagemEnviado: 19 Jun 2008 17:18
por guest2003
q estranho...

teoricamente deveria desligar o flag dentro da rotina que o testa... porem no codigo postado nao tem isso... mas blz, no seu original deve ter.

[]'s