Frequency multiplier

Frequency counter circuit

Simple Frequency Counter

You might have come across various projects like Frequency counter, Digital Frequency Counter, and similar ones across different websites. Here, I’m presenting another project of the same category, employing an AVR microcontroller, specifically the Atmega8, in one of its variations. This circuit serves as an excellent microcontroller project for educational purposes, particularly in engineering classes.

The fundamental principle behind this project is measuring the frequency of a periodic signal, which represents the number of cycles it completes in one second. Therefore, by counting the cycles within a second, we can determine the frequency. Hence, we are building a frequency counter circuit, often referred to as a frequency meter.

To create this frequency meter, we require the following components:

  1. A signal whose frequency needs to be measured.
  2. The AVR Atmega8 microcontroller.
  3. An LCD display to showcase the counted frequency.

I assume that you are familiar with programming the AVR Atmega8 and know how to establish connections with an LCD.

Now, let’s delve into the core of the project – the Simple Frequency Counter, also known as a Frequency Meter. Please review the circuit diagram provided below, along with the program code available at the end of this post.

Frequency counter circuit

Description of circuit:-

So, let me explain the procedure I followed: I initially reset the counter to zero, then waited for 1 second, and finally, I read the counter’s value. It’s important to note that you should retrieve the value immediately after the delay loop concludes. This process is quite straightforward – you can simply create a variable and assign the count to it. The variable’s data type is typically an unsigned integer, although you can also opt for the floating-point data type. In the latter case, you’ll need to perform typecasting. That’s all there is to it! If you want to delve deeper into AVR’s floating-point conversion, I recommend reading this article attentively: Avr String Formatting.

Additionally, it’s advisable to employ a conditioned signal for frequency counting, such as a square wave or pulse trace. You can implement various signal conditioning circuits to achieve this, including comparators, Schmitt triggers, or sine wave to square wave converters. If your signal has low power, a conditioning circuit is particularly useful. You can explore a range of signal conditioning circuits on this website – Signal Conditioner Circuits.

Here are the technical specifications for my project. I hope that putting this together won’t pose too much difficulty for you.

The program [Embedded C, AVR Studio]:

#define F_CPU 1000000
#define SMP 1

int main(void)
{ unsigned int i;


{ TCNT1 =0;
return 0;

The internal code of the Header file “ATmega8LCDcfg1.h

Note: the Location of the Headr file is: “C:\Program Files \Atmel\AVR Tools\AVR Toolchain\avr\include\user”

#ifdef _LCD_CFG_H
#warning "LCD configuration file already loaded. ATmega8LCDcfg.h inclusion skipped."

#ifndef _LCD_CFG_H
#define _LCD_CFG_H 1

#ifndef _AVR_IO_H_

#ifndef _UTIL_DELAY_H_

#ifndef _STDIO_H_

#define DEL1 10
#define DEL2 40

#ifndef DPORT

#ifndef CPORT

#ifndef DPDDR
#define DPDDR DDRB

#ifndef CPDDR
#define CPDDR DDRD

#ifndef RS
#define RS PD6

#ifndef EN
#define EN PD7

int LCD(char ch, FILE *fp);
// Function To send a single char. to LCD

void LCDcmd(char ch);
void initLCD();

// Above: A stream is set up to give a formatted output
// to LCD using a macro FDEV_SETUP_STREAM(). The stream
// includes the function ‘LCD()’ that describes how a
// single character is sent to LCD. But the function
// prototype of ‘LCD()’ must be as per demand by the macro
// ‘FDEV_SETUP_STREAM()’. See the prototype defined. This
// prototype is fixed. If this prototype differs. The program
// will not get complied.
// In the argument Field of ‘FDEV_SETUP_STREAM(A,B,C)’. First
// field(A) holds the name of the function/routine that is to be
// used for sending a single character. Next field defines
// function to receive characters. The next one defines if
// the stream to be set up can be used for reading characters,
// writing characters or both.
// to know more, visit:

void LCDcmd(char ch)
{ DPORT = ch;
CPORT = (1<<EN);
CPORT = (0<<EN);

int LCD(char ch, FILE *fp)
{ DPORT =ch;
CPORT = (1<<EN)|(1<<RS);
CPORT = (0<<EN)|(0<<RS);
return 0;

void initLCD()
{ CPDDR = (1<<EN)|(1<<RS);
DPDDR = 0xff;

#endif // _LCD_CFG_H

Related Articles

Leave a Reply

Your email address will not be published.

Back to top button