Wednesday, August 20, 2014

Frequency counter with PIC16F628A

Some time ago I made an audio oscillator with frequency counter which worked very well, but I sold it, and now I am making a new one. The oscillator itself will be mostly the same and when I finish the whole project there will be a separate article. Here I will show the frequency counter module I made for the project.

The previous frequency counter was made with CMOS logic ICs, but as I already own a PIC programmer, this one is designed with PIC microcontroller. As usual I searched the web for inspiration. The original idea came from this project: LCD frequency counter. As you can see - very simple and yet elegant schematic. But I wanted to use 7-segment LED display, not LCD, so I found a second useful project: Simple 100MHz frequency counter which uses 6 digit LED display.

Combining two projects into one wasn't very easy.  First of all I wanted a PIC microcontroller to do the whole job without any additional ICs. Also I wanted to use the the familiar 16F628A, but because one of the portA pins (RA5) can be used only as input I was short of outputs to do the job. Driving 6 digit 7-segment multiplexed display requires 7 + 6 = 13 outputs. The 16F628A has 16 IO pins, two of which are used for the crystal oscillator, one is for the signal input and other one can be used only for input, that leaves us with only 12 useful IO pins. The solution was to drive one of the common cathodes with a transistor, which opens when all other digits are switched off.

Here is the final schematic:

7-segment displays used here are 3 digit multiplexed common cathode type (BC56-12SRWA). Digits 2..5 are switched on when respective pins are set low. When all these pins are high, the transistor Q1 opens and switches on the first digit. The current for each segment is about 6-7mA.

I must mention that pins connected to common cathodes theoretically may sink up to 50mA if all segments are light up (7x7mA).  This is way above max specifications of the microcontroller. But as every digit is switched on for very brief moment I think it is safe. The whole schematic consumes around 30-40mA in average and the microcontroller is not heating at all, so everything seems OK.

The microcontroller uses its internal 4MHz oscillator for the CPU clock. Timer1 uses external crystal oscillator with frequency 32768Hz for setting the 1 second time interval. Timer0 is used to count the input signal at pin RA4. And finally, Timer2 is used for cycling and refreshing the digits.
As the input signal will be 5Vpp square wave there isn't any preamp or buffer in the front.
The counter can measure up to 920-930kHz which is more than enough for my project. The reason why it can't go higher is because driving all these digits consumes lots of CPU cycles. I suppose, the program code can be optimized or even written in assembler and then the counter can reach 999999 Hz.

The crystals for 32768Hz are sold in two sizes : 2x6mm and 3x8mm. I recommend 2x6mm because it fits perfectly below the left display. The other size also can be used but it will lift a little the left display.

Anyway, this is the finished module:


So, if anyone has a burning desire to test this project himself, here are the project files: FreqC(16F628A)
Use them on your own responsibility!
The PCB in the archive is a little different from the pictures above, because I made some optimizations. 
I am open for suggestions about program code and how it can be optimized.

UPDATE: 26.01.2019
Refined PCB, different voltage regulator, slightly smaller board. Archive include Eagle files, HEX and C file and also zipped Gerber files.
FreqC (PIC16F628A, v2)


  1. I looked very much a frequency meter for low frequencies.
    What should I do to display from 50Hz?

    I'm a beginner...

  2. Hi,
    Can this Counter read very low frequency in the range of 0 to 9 Hz?
    Thank you.

    1. Yes, it can, but the accuracy will be very low, especially towards the 0 Hz. For lower frequencies it is better to be implemented different method - reciprocal frequency counting. Instead of counting the input signal for 1 second, the microcontroller must measure the length of the input signal period T and then calculate the frequency with the formula f = 1/T. This method will give you much better accuracy for lower frequencies.

    2. Thank you very much, Christo.
      I try to build your system, then I let you know how is working.
      Thanks again.

  3. Excuse me but why you use the in put only pin (RA5) as frequency input and gain an I/O Port instead of only input port and use it for the 6th Digit

  4. excuse me what software do u draw?
    can u tell me please
    thank u😘

  5. Can it measure crystals?Such as the 10.000mhz crystals?Thank you.:)

    1. If the crystal is connected in active oscillator circuit - yes it can.