Frequencímetro com atmega8

Software e Hardware para ATMEL

Moderadores: 51, guest2003, brasilma

Frequencímetro com atmega8

Mensagempor vohr56 » 31 Mai 2008 14:47

Olá!

Estou com algumas dúvidas relacionadas à programação de um frequencímetro utilizando o mega8.

No projeto que utilizarei, vou contar de 0a 220 Hz. Desejo que a frequência seja um número real, não um inteiro (ex: 14.905 Hz).

Acontece que da maneira que escrevi o código, conforme a frequência aumenta aparece um erro, tipo, se coloco 1KHz na entrada ele conta
1041.07 Hz. Se coloco 100 Hz ele conta 100.81 Hz.

o mínimo que ele conta é 0.25 Hz. o máximo está em torno de 2 KHz.

Segue o código, gerado no Codevision:


#include <mega8.h>
#include <stdio.h>
#include <lcd.h>



// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm



/*----------------------Rotina de detecção da frequência---------------------------------*/

float pulso;
float T,f;

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
pulso=TCNT1;
TCNT1=0;
T=pulso*0.000064; // T é o período e 0.000064 é o tempo gasto em cada incremento de TCNT1 1/( Tosc= 4Mhz/Prescaler=256)
f=1/T;

}

/*---------------------------------Fim da rotina-------------------------------------*/

char* lcd_buf[20];


void main(void)
{

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Rising Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x44;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x20;

// Global enable interrupts
#asm("sei")


// LCD module initialization
lcd_init(16);



while (1)
{
lcd_gotoxy(0,0);
sprintf(lcd_buf,"FREQ: %5.2f Hz",f); //exibe a frequência no LCD
lcd_puts(lcd_buf);

}
}



Essa é a melhor maneira de se construir um frequencímetro?
O que posso otimizar no código? O que estou fazendo de errado?

O projeto que fiz só que utilizando interrupções externas e o timer 0 gerando interrupcoes a cada 1 segundo funciona sem dar erros, mas o valor medido é sempre um inteiro.


Link para o programa com simulação no Proteus.
http://www.4shared.com/file/49642226/11 ... d=1b1a6207


Obrigado!

Abraços!!
vohr56
Bit
 
Mensagens: 22
Registrado em: 30 Nov 2006 10:36

Mensagempor RobL » 05 Jun 2008 19:54

A frequência é muito baixa para dar esse erro.
Sua base de tempo é a cristal, correto?
Qual a forma do sinal de entrada a medir?
Esse valor é o mesmo com várias medidas ou foi o de uma tomada somente?

Se houvesse erro (por software) no tempo de captura, o erro seria constante, no entanto o erro cresce com a frequência extamente a mesma ordem de grandeza com o aumento da frequência 10x.
Se a forma de onda medida não for bem comportada e tiver reatâncias nessa entrada, pode estar aí o problema.

Este método tem que funcionar, principalmente nesta faixa de frequência.
O que parece estar acontecendo é que o limiar da captura está variando.

Procure armazenar o valor de várias capturas seguidamente e comparar.
Isto deverá dar uma pista do que está ocorrendo.
Quero dizer, injete o sinal e sem retirá-lo faça várias medidas (capturas)e verifique.

Um outro método é contar por um timer disparado por certo tempo grande. Se puder ser tão lento como um segundo dá excelente precisão (repetibilidade).
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor vohr56 » 05 Jun 2008 23:09

RobL escreveu:A frequência é muito baixa para dar esse erro.
Sua base de tempo é a cristal, correto?
Qual a forma do sinal de entrada a medir?
Esse valor é o mesmo com várias medidas ou foi o de uma tomada somente?

Se houvesse erro (por software) no tempo de captura, o erro seria constante, no entanto o erro cresce com a frequência extamente a mesma ordem de grandeza com o aumento da frequência 10x.
Se a forma de onda medida não for bem comportada e tiver reatâncias nessa entrada, pode estar aí o problema.

Este método tem que funcionar, principalmente nesta faixa de frequência.
O que parece estar acontecendo é que o limiar da captura está variando.

Procure armazenar o valor de várias capturas seguidamente e comparar.
Isto deverá dar uma pista do que está ocorrendo.
Quero dizer, injete o sinal e sem retirá-lo faça várias medidas (capturas)e verifique.

Um outro método é contar por um timer disparado por certo tempo grande. Se puder ser tão lento como um segundo dá excelente precisão (repetibilidade).



Então Robl, no outro projeto que montei faço o seguinte: Jogo o sinal em uma porta que vai gerar uma interrupção, e na rotina dela somente incremento uma variável. Aí montei um dos timers para contar 1 segundo. Ai analiso o valor da variavel que era incrementada e tenho a frequencia, mas não com casas decimais. mas desta maneira não ocorre o erro.

Este projeto acima não cheguei a testar na prática, só no proteus, e lá que ocorre tal erro.
vohr56
Bit
 
Mensagens: 22
Registrado em: 30 Nov 2006 10:36


Voltar para AVR

Quem está online

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

x