Become a subscriber (Free)

Join 29,000 other subscribers to receive subscriber sale discounts and other free resources.
Don't worry -- your e-mail address is totally secure. I promise to use it only to send you MicroZine.

A PIC frequency counter operating up to about 50 MHz.

This PIC frequency counter project uses an LCD to display the frequency and PIC timer 1 to measure the input signal and Timer0 to measure the timing period.

It uses Timer 1 in 16 bit counter mode to count the input signal edges and overflows of the counter are accumulated to give the total count in multiples of 65536.Adding the current value of the counter at the end gives the total count.

The crystal oscillator is chosen to be 4MHz (Fosc) so that the processor internal clock is 1MHz (Fosc/4). All you do is count 1e6 processor clocks (Timer0) to give a 1second count period.

Since the measurement time is 1 second the final count is actually the frequency of the input signal.

PIC frequency counter block diagram


Using the 1 second measurement time also gives a frequency resolution of 1 Hz.


Min frequency 1Hz
Max frequency ~50MHz (limited by input pin characteristics).

(Tested using TTL oscillator at 20MHz).

Input signal level TTL

Note: The exact maximum operating frequency is determined by the PIC input pin characteristic.

Compiler Mikroelectronika MikroC Compiler Free!
Target 16F877A (retargetable to other PICs that have TMR1)
Software level Advanced.
Software notes Interrupt Driven counting and time measurement.
Hardware level Easy.
Hardware notes None
Project version 1.03
Project files Enter your details to get the Download Link
and get the microcontroller newsletter:

Please Enter your Details in one of
the forms at the top or Bottom of
this page to get the Free Source code

(Note: Your email is safe it will never be sold or rented).
You will get All theC source code and hex file.

Note: Check your email for the project code download link.

For the general theory of operation of this circuit and notes on frequency counting of this pic frequency counter click here.

PIC frequency counter schematic using LCD and TMR0 and TMR1.
(Click diagram to open a pdf.)

PIC frequency counter schematic using LCD and TMR0 & TMR1.

Pic frequency counter Hardware

The hardware is simple and the main blocks are shown in the diagram below.

pic frequency counter

The LCD is used in 4 bit mode interface so you only need 4 data lines and three control lines and it then fits into a single 8 bit port.

The crystal oscillator is simply a crystal and two capacitors connected to the PIC oscillator port at OSC1 and OSC2. The capacitors can both be fixed at the same value unless you want to tune it using a frequency reference. If you don't have an accurate reference then use fixed capacitors.

The PIC micro can be any type that has Timer 0 and Timer 1 hardware modules and and has enough memory to hold the program ~1.6k words.

The LED is toggled to indicate that the processor is alive - so if there is no input signal you can tell that the software is working. Also if there is no input signal the the LCD displays a flashing zero.

You can program the PIC in circuit through the ICSP connector in circuit.


To time a 1 second count Timer0 is used. Since the main clock is running at 4MHz then the processor clock (Fosc/4) is 1MHz which is the rate that Timer0 is set-up to use i.e. the internal clock. Therefore we need to get a 1 second count using that timer. Since the timer is only 8 bits long you can use the fact that an interrupt is generated when it overflows - you can then count these overflows to get near to 1e6 counts.

Since the overflow occurs every time that the counter passes 256 we need to count 1e6/256 overflows

1e6/256 = 3906.25

We can only count integer overflows so must manipulate the last count to get the exact time. So we need the modulus of 1e6 and 256:

1e6 % 256 is 64 (0.25*256 is 64).

The interrupt routine starts off after being zeroed by counting 3906 overflows, it then controls a flag variable (do_TMR0_end_count) that indicates this is the last overflow for which the Timer0 value is set to overflow after 64 Fosc/4 cycles:

TMR0 = 256-64+2; // 2 cycles lost when writing to TMR0 so add 2.

At the end of the last overflow the values of Timer1 are captured to:




An LCD update request is sent from the interrupt routine to the main routine by setting a flag (update_LCD) and the main routine then uses ltoa to calculate and output the frequency measurement to then display on LCD.

PIC frequency counter Software

Project files for the PIC frequency counter

Compiler project files

This is the main project file.

There are other files since MikroC version 6.0.4 seems to need a lot more than V5! just keep them in your project folder.

C Source files.

Header files.

Output files

For a tutorial on compiling these files click here.

You only need to recompile the pic frequency counter files if you want to change the source code or examine how the code works using the built in simulator since the hex file to program the chip is included in the download.

Brief description

  • frequency_counter...c : contains the code start point (in routine 'main') and the interrupt routine.
  • ltoa.c contains a long to ascii converter used for display of the frequency count.
  • bit.h : contains macros for bit manipulation.

All other header files contain prototypes.

PIC frequency counter code operation.

The code uses the built in LCD driver routines which are automatically included by the compiler. Note automatic include is unusual but it seems to work well in mikroC.

Interrupts are not used only the flags that can be polled (timer overflow) are activated.


This file contains the port initialization, interrupt and main routine.

After initialization the code enters an endless loop where it continuously performs a measurement and display operation. After an accurate 1 second delay the counter result is processed and displayed on the LCD.

The main operation of this code is within the interrupt routine that both counts the input edges and obtains an accurate 1s time by counting the edges of the internal oscillator clock (Fosc/4).


The most important part of this counter is the interrupt() routine. This is where all the action and decisions are made.

The interrupt code for Timer1 is very simple and all it does is increment a long variable for counting multiple input events.

The more tricky interrupt code, for Timer 0, counts time as described above. It counts 3906 overflows followed by a single 64 cycle count to reach a time of 1 second after which it captures the event count and then triggers an update to the LCD to calculate and display the frequency. The update triggers the actions in main().


This contains macros for bit manipulation which should be compiler independent.

New! Comments

Have your say about what you just read! Leave me a comment in the box below.

Jump from pic frequency counter page to
to Best Microcontroller Projects Home Page.

Privacy Policy | Contact | About Me

Site Map | Terms of Use

Visit our Facebook Page:

   Click Here

Recent Articles

  1. Easily make an IR Pulse Rate Sensor with one opamp, an Arduino, and a matched Infrared phototransistor and LED pair.

    How to make a Pulse Rate Sensor using a simple single opamp circuit with an Arduino and a few other components.

    Read more

  2. 74HC595

    74HC595 : How to add nearly unlimited outputs to any microcontoller.

    Read more

  3. Using the MAX6675 or How to easily measure Extreme temperatures

    How to use the MAX6675 and an Arduino to measure temperatures from 0°C to 1024°C with two components: A chip - the MAX6675, and a Sensor: - a type-K thermocouple.

    Read more

Readers Comments

"I wanted to thank
you so so so much
for all the information
you have provided in
your site it's


- Ranish Pottath

"This site really is
the best and my favorite.
I find here many useful
projects and tips."

- Milan


"Awesome site,
very, very easy and nice
to navigate!"

- Matt

Learn Microcontrollers

"Interested in

Sign up for The
Free 7 day guide:


"I am a newbie to PIC
and I wanted to say
 how great your
site has been for me."

- Dave


"Your site is a great
and perfect work.

- Suresh


"I couldn't find the correct
words to define
yourweb site.

Very useful, uncovered,
honest and clear.

Thanks so much for
your time and works.

- Anon