June 12, 2010:
Revised: v2.0

ZL2PD LED Frequency Counter

A 5-digit microprocessor-based frequency counter which
operates to over 35 MHz. Expansion of this basic design to cover higher frequencies is easy.


This 5-digit frequency counter project is one of a series of 8051 based frequency counters which I designed over a period of about two years for a variety of applications. In this particular case, I wanted a compact counter for use in a receiver project, and this was one of the early versions I developed.

In an attempt to use the smallest possible LED display, this counter uses a very small National Semiconductors 8 digit LED display which came from an old calculator. (For those interested, the display part number is NSA1488) I figured out the connections for the display with a bit of patient probing with my multimeter, identifying the display common and each of the segment pin connections for the display.

Any modern common cathode LED display can be used instead of this display. It doesn't need to be as small as this display that I used. I also ended up using larger common-cathode LED displays in a later similar versions of this same counter design. I originally thought that this ex-calculator display would be ideal for the compact receiver I was building, but, as events transpired, the display ended up being a few millimeters too large for the final receiver chassis, so I had to keep looking for a set of even smaller LED displays.

The Microprocessor

The counter uses a Philips 87C751 microprocessor. This is an EPROM member of the 8051 family. It was, for a number of years, the smallest 8051 chip equipped with an I2C interface, although that feature was not used in this project. It also came with 2k of EPROM and 64 bytes of RAM. This may appear limited, but it's actually plenty of memory for this sort of application.

Just a warning: The 87C751 chip is quite hard to find now, as is a suitable programmer. However, I've described this project here because I imagine that some probably exist in junkboxes here and there. I still have a couple floating about in my junkbox, left over from earlier projects. I'll get around to using them on something else one day, and this may be just the project for someone to resurrect their 87C751 from the junkbox.

The Design

The preamplifier circuit is a copy of a circuit commonly found in simple frequency counters, and also operates from the 5V supply rail. It uses a commonly available FET (I used an MPF102 but almost anything will do here, such as a J310 etc) and a pair of RF transistors. I used MPHS11 devices, but in other versions I built, I used the more commonly available 2N2222 transistors.

The preamplifier feeds a 74HC4040 divider, which divides the input frequency by 64 to ensure the maximum frequency limitations of the 8051 family are not exceeded. The maximum input frequency is defined as 1/24th of the oscillator frequency. So, with a clock of 14.3 MHz, the maximum input frequency is 600 kHz. Since the 4040 stage divides the input by 64, the maximum frequency which can be counted is 38.4 MHz.

The 87C751 clock crystal is the reference for the counter, and the code allows fine tuning to ensure reasonable accuracy. Comments in the source code (below) describe all of the details. I used a 14.3 MHz crystal taken from an old 8086 PC motherboard, but the code can be modified for use with other crystals.


One feature of the chip to watch out for is its unusual timer/counter arrangement - Well, it's a bit unusual for the 8051 family. The 87C751 has two timer/counters; one is a standard 16 bit timer/counter, the other is a 10 bit timer. The 16 bit timer/counter is configured in an auto-reload mode. Here, the 16-bit counter is used in the main frequency counting routine.

The 10-bit timer is normally dedicated to the I2C interface, but here it is used as a fixed rate background timer. Combined with interrupts, it drives the display digit multiplexing. One digit is displayed each time the 10 bit background counter rolls over. This occurs once every 860 uS, and the same routine triggers the capture of new counter data every 128 mS.

The supply current for the counter is minimised by multiplexing the displays. That means a pair of ports are used to drive each of the eight displays one by one. One port outputs the LED segment data for each display while the other port selects the required display. This requires a little more care when writing the code.

This multiplexed display method does generate some clock noise, and the counter may need to be mounted in a shielded box for some applications. I ended up using another version of this counter in the receiver so this one was put to use around the bench for some time, and the multiplexer noise was rarely noted.    


I built the counter on prototype board using point to point wiring. This design was never intended for mass production and so a PCB was not developed. Besides, most prototypes and one-off designs are faster and easier to build this way. I used a mixture of regular hookup wire, wire-wrap wire and solder-through wire. The latter wire is very thin and quite hard to see in the photos (It's only used on the underside of the board). Made a number of years ago by Vero in England, it is coated with a thin but surprisingly tough layer of insulation which acts as a solder flux when the wire is soldered into place. Fantastic stuff!

The counter display is wired in at one end of the board and supported by a pair of triangular shaped scraps of PCB. These LED displays need a fairly high drive current to light up the LEDs brightly. Unfortunately, the 87C751 cannot drive these directly. As a result, there are a number of discrete transistors which are required for display drivers. However, they are cheap, so it's not all bad.

The display driver transistors are all general purpose NPN and PNP devices. Examples include BC547 (NPN) and BC557 (PNP) devices.

Note that two pullup resistors are required on the I2C port lines on the 87C751.


There are a couple of test points which might just be able to be seen on the counter board. These were used during code debugging to show when sections of the code were exited. I connected an oscilloscope to these points and this allowed me to monitor how far the code was getting. I don't have an in-circuit emulator for the 87C751, so the development was all done using the well proven (but tedious) "crash and burn" method.

For those readers unfamiliar with this process, the term refers to the experience encountered during the often highly repetitive code development cycle. The designer writes some code, programs (burns) the code into the EPROM in the chip, then watches the new code crash in some spectacularly new and novel manner when yet another error is encountered in the program. Fortunately, this project wasn't too bad in that regard.

When the counter is powered up, the display will briefly show "HF2000A". This was the model number I gave to my new receiver. Feel free to change the source code so your version of the counter either displays something more appropriate. The data for this sign-on display is located, along with other display related data, towards the very end of the source code. And
Although the display has 8 digits available, the software I wrote was limited to displaying 5 digits because I only wanted to display the receiver's frequency to the nearest kHz.

Aside from the numeric frequency information, the display may also show "BadCount". BadCount indicates the counter is attempting to display a frequency in excess of 65,535 MHz. It is held briefly to show the over-range count before the normal frequency counting routine continues again.

The counter is powered directly from a 5V supply, and needs less than 100mA. It covers frequencies from 500 Hz to above 30 MHz.


Intel HEX file - Clicking on this link will allow you to download a zipped HEX format file (1 kB) for programming an 87C751 chip for use in this counter    

Source File - Clicking on this link will allow you to download a zipped Metalink compatible ASCII TEXT format source file (5 kB) for this counter. This will allow the asembler code to be modified by experienced 8051 programmers who may wish to use the code with another type of 8051 chip or to add more features.    

Want to go back to the main page? Click here to return directly.