Frequency meter Counter using ATmega16 or ATmega8
Frequency meter (Counter) using ATmega16 or ATmega8
In this tutorial we are going to build simple frequency meter (frequency counter) using ATmega16 and codevision avr compiler. This simple frequency meter (frequency counter) can measure frequency up to 4Mhz (theoretically) because we are using 8Mhz clock for the ATmega16 micro-controller. But you can use an external crystal oscillator of frequency 16Mhz and increase uo the range to 8Mhz.
How it works :
Frequency = i*2^16 + TCNT1
#includeMore details ) */
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include/* the reading is displayed on LCD */
#include
#include/* this library is used to display variables on lcd ( More details ) */
unsigned long int freq; /* to store value of frequency value */
unsigned int i=0,dur; /* i=number of overflows in one second */
/* dur to store the value of TCNT1 register */
char buffer[8];
/* array char to store the frequency value as a string to be displayed on lcd (
float freqf; /* used to display the fractions of frequency with the suitable unit as shown later */
// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
i++ ; // count the number of overflows in one second
}
void main(void)
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;
// LCD module initialization
lcd_init(16);
#asm("sei")
while (1)
{
TIMSK=0x04; // enable overflow interrupt of timer1
TCCR1B=0x07; /* start timer1 with external pulses (T1 rising edge) */
delay_ms(1000); // wait for one second
TCCR1B=0x00; //stop timer1
TIMSK=0x00; //disable interrupt
dur=TCNT1; /* store the number of counts in TCNT1 register */
freq = dur + i*65536; /* calculate the frequency as in previous equation */
TCNT1=0x0000; /* clear TCNT1 register for the next reading */
i=0; /* clear number of overflows in one second for the next reading */
//////////////////// display ////////////////////////
lcd_gotoxy(0,0);
lcd_putsf("freq=");
lcd_gotoxy(0,1);
if(freq>=1000000) /* if frequency more than or equal 1Mhz use "Mhz" on lcd */
{
freqf=(float)freq/1000000; //divide by 1Mhz scale
ftoa(freqf,3, buffer);
lcd_puts(buffer);
lcd_putsf("MHZ");
}
else if (freq>=1000) /* if frequency more than or equal 1khz use "Khz" on lcd */
{
freqf=(float)freq/1000;
ftoa(freqf,3, buffer);
lcd_puts(buffer);
lcd_putsf("KHZ");
}
else // if frequency less than 1khz use "hz" on lcd
{
ltoa(freq, buffer);
lcd_puts(buffer);
lcd_putsf("HZ");
}
};
}
Practical Results :
Actual Frequency
|
Measured Frequency
|
Relative error
|
10 hz
|
10 hz
|
0 %
|
100 hz
|
97 hz
|
3 %
|
1 khz
|
0.963 khz
|
3.7 %
|
10 Khz
|
9.62 Khz
|
3.8 %
|
100 khz
|
96.1 khz
|
3.9 %
|
1 Mhz
|
0.961 Mhz
|
3.9 %
|
3 Mhz
|
2.88 Mhz
|
4 %
|
Here is a short video showing the circuit working :
You can download the code and simulation file from the following link :
NEW : Here is the same cicuit of frequency meter but using ATmega8 microcontroller.
You can download the code and simulation files from the following link :
Download Here
You can download this tutorial in PDF from the following link :
Download Here