il mio primo Frequenzimetro
Salve ho scritto il mio primo codice per un frequenzimetro fatto con ATmega32 (per ora l ho solo simulato e tutto sembra funzionare.) vi posto il codice che ho scritto, potete dirmi se c e da migliorare qualcosa?
sono alle prime armi e non sono ancora molto esperto...
Cio che mi disturba di piu e' che devo contare gli impulsi del segnale da misurare con il registro a 8bit perche la finestra temporale di 1s non potrei proprio farla con il registro a 8bit neanche con il prescaler massimo 1024.
prima di postarvi il codice vorrei farvi un paio di domande:
- quale' la frequenza massima che posso inviare dentro il microcontrollore?
- il pin T0 mi conta gli impulsi del segnale da misurare, ma che tensione deve avere il segnale di ingresso per poter essere contato?
- mi conviene usare un oscillatore al quarzo a 16Mhz? oppure uno piu lento magari da 4Mhz?
ecco il codice ben commentato:
sono alle prime armi e non sono ancora molto esperto...
Cio che mi disturba di piu e' che devo contare gli impulsi del segnale da misurare con il registro a 8bit perche la finestra temporale di 1s non potrei proprio farla con il registro a 8bit neanche con il prescaler massimo 1024.
prima di postarvi il codice vorrei farvi un paio di domande:
- quale' la frequenza massima che posso inviare dentro il microcontrollore?
- il pin T0 mi conta gli impulsi del segnale da misurare, ma che tensione deve avere il segnale di ingresso per poter essere contato?
- mi conviene usare un oscillatore al quarzo a 16Mhz? oppure uno piu lento magari da 4Mhz?
ecco il codice ben commentato:
- Codice: Seleziona tutto
#undef F_CPU
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "lcd_stefano.h"
static volatile int signal_overflow = 0; //variabile da usare nell'ISR che rappresenta il numero di overflow del Timer/Counter0 (ovvero 256 impulsi del segnale da misurare)
static volatile int frequenza = 0;
int main()
{
LCD8_Initialization();
DDRB &= ~(1<<PINB1);
TCCR0 |= 1<<CS00 | 1<<CS01 | 1<<CS02; //imposto la modalita "External clock source on T0 pin" il TCNT0(8 bits: 0-255) tiene conto degli impulsi del segnale da misurare
TCCR1B |= 1<<CS10 | 1<<CS11; //imposto il prescaler del Timer/Counter1 a 64
TCCR1B |= 1<<WGM12; //attivo il mode CTC ovvero "Clear to Compare". Questo azzera il contatore TCNT1 quando viene raggiunto l' OCR1A
TIMSK |= 1<<TOIE0; //ablito l'interrupt per overflow del Timer/Counter0 perche contero gli impulsi della frequenza da misurare con il TCNT0 che arriva fino a 255 e contero il numero di overflow in 100ms per sapere la frequenza
TIMSK |= 1<<OCIE1A; //abilito l'interrupt per compare match con l'OCR1A del Timer/Counter1. Quando il TCNT1 raggiunge l'OCR1 vuol dire che e' passata la finestra temporale scelta in cui contare gli impulsi del segnale e dare la frequenza.
OCR1A = 25000; //Il TCNT1 arriva a 25000 dopo 100ms perche siamo a 16MHz con prescaler 64 quindi: 16.000.000/64 = 250.000 impulsi in 1 secondo => 25.000 ogni 100ms
SendString("frequenza");
SetCursorPosition(1,8); SendString("Hz");
sei();
while (1)
{
}
return 0;
}
ISR(TIMER0_OVF_vect)//interrupt routine quando abbiamo un evento di overflow del TCNT0 (Timer/Counter0) ovvero quando sono stati contati 256 impulsi del segnale da misurare
{
signal_overflow++;
}
ISR(TIMER1_COMPA_vect)//interrupt routine per compare match, quando il contatore TCNT1 diventa uguale all'OCR1A. (ovvero quando sono passati 100ms)
{
frequenza = (signal_overflow*256+TCNT0)*10;
TCNT0 = 0; //quindi azzero il contatore TCNT0 e la variabile che tiene conto degli overflow
signal_overflow = 0; //azzero tutto cio che riguarda la vecchia misura di frequenza
SetCursorPosition(1,0); //scrivo su LCD
SendInteger(frequenza,6);
}