Dick Cappels' project pages http://www.projects.cappels.org

Return to HOME 
A Little More Serious Frequency Meter
This is design for a frequency meter based on AVR microcontrollers.
Maximum input frequency is specified to be 30 MHz in the multi-chip configuration, and in single-chip configuration, there are both 5 MHz and 10 Mhz versions operating with 10 and 20 MHz crystals, respectively. All versions have 9 1/2 digit resolution. I have  used multi-chip version at 40 Mhz, and depending upon the actual chips you use and your layout, it can work at much higher input frequencies.  The 10 MHz single-chip version using the ATtiny2313 is ideal for use with a X10 or X 100 prescaler.

Download the AVRStudio assembly source for 30 MHz (AT90S2313 or Tiny2313) version: ffmtr040916A.asm

Download the AVRStudio Hex (Intel Intellec 8/MDS format) file for the 30 MHz (AT90S2313 or Tiny2313) version: ffmtr040916A.hex

Donwload the AVRStudio assembly source for the 10 MHz (ATtiny2313) single-chip version: nfmtrT050524.asm

Download the AVRStudio Hex (Intel Intellec 8/MDS format) file for the 10 MHZ single-chip (ATtiny2313) version: nfmtrT050524.hex

Download the AVRStudio assembly source for the 5 MHz single-chip AT90S2313 or ATtiny2313 version: nfmtr040916A.asm

Also see the companion Preamp and 330+ MHz prescaler.

Left to right: AT90S2313-10 microcontroller with 5 volt regulator above and input connector below, 74HC4060 prescaler, and 74HC02 quad NOR gate. Along the top are the power connector (above the 5V regulator), In-System Programming connector, and the LCD display connector. Not much to it,


I decided that I needed a frequency meter with higher resolution and a higher maximum frequency than the one I built a couple of years ago. The idea for this meter has been around for a while,  though I've seen it done with a PIC, I don't remember seeing this particular implementation with an AVR before.

As for microcontroller choice, the requirements for this firmware are that the controller be an AVR with a 16 bit counter,  has a ram stack and UART or USART, and the ability to operate at 10 MHz. Some modification may be required to the code to accommodate a USART instead of a UART, a 16 bit stack pointer instead of the 8 bit pointer on the AT90S2313, and the specific controls of the 16 bit counter registers. I used an AT90S2313 because they are available to me and suitably small. For the 10 MHz input single-chip configuration, you need to use an AVR that can clock at 20 MHz. I used an ATtiny2313-20. When programming the ATtiny2313, remember to select a fuse setting for the internal clock oscillator. The AT90S2313 does not have clock fuse settings.

The first phase was to make a high resolution frequency meter/counter just using the AT90S2313 ot ATtiny2313, then to add the external prescaler. Without the prescaler, the maximum input frequency for the frequency meter is 5 MHz or 10 MHz, depending upon the chip you use and the firmware version you choose. With the multi-chip version that includes a prescaler, the maximum input frequency, according the the component specifications, is about 30 Mhz - this will vary with individual external prescaler chips and your circuit layout. To summarize, there are three versions of the code available at the top of this page: The 5 MHz single-chip version, which is basically an AT90S2313-10 clocked at 10 MHz and a serial interface, the 10 MHz single-chip versoin with is basically an ATtiny2313-20 clocked at 20 MHz with a serial interface, and the 30 MHz multi-chip version, which is the same circuit as the 5 and 10 MHz versions, but with the prescaler and quad NOR gate added.  In the 30 MHz version, the maximum input frequency for the counter mode (counts until reset via ASCII command) is 5 MHz.  The timebase selections between the two version differ as well. The 30 MHz version has timebases of 0.1, 1, 10,and 100 seconds. The 5 MHz version only has 1, 10, and 100 second timebases.

To summarize:

Design            Frequency Measurement Mode        Counting Mode         Timebases
30 MHz            30 MHz maximum                   5 MHz maximum         0.1, 1, 10, and 100 seconds
10 MHz            10 MHz maximum                  10 MHz maximum         1, 10, and 100 secondds
 5 MHz            5 MHz maximum                    5 MHz maximum         1, 10, and 100 seconds

The multi-chip meter has five modes of operation: 0.1 second time base, 1 second ,time base 10 second ttime base  100 second ttime base and counting mode. The single-chip versions have four modes of operations: 1 second ,time base 10 second ttime base  100 second ttime base and counting mode.You switch modes by sending any ASCII character  making the instrument cycle through the five modes over and over.

ASCII "R" ($52) is a special case. In the 0.1, 1, 10, and 100 second time base modes, it causes the instrument to cycle to the next mode. When in the counting mode, ASCII "R" causes the counter to reset to zero.

I added two push-buttons to one of the 2 line x 16 character LCD display boards that I built (See "Serial Interface for Truly MTC-C162DPLY-2N, 2 line X 16 char LCD display" elsewhere on this site.). One button is used to send an ASCII carriage return ($0D) and the other is used to send an ASCII "R" ($52), so they can be used to advance the operating mode, and reset the counter, when in the counting mode, respectively.

All 10 digits are shown in this 100 second measurement of a 30 MHz signal with .01 Hz resolution. The measurement drifted about 30 Hz within a few seconds from the warmth of my thumb on the 10 MHz crystal can. Do not confuse resolution with accuracy.

The binary-to-BCD conversion is 32 bits wide, so the largest number that can be displayed is 4,294,967.295. At 5 MHz, it takes nearly 15 minutes to overflow. It will not overflow in the frequency meter mode - even at 30 MHz, it takes about 143 seconds to reach this count, in excess of the longest time base available,  100 seconds. When the counter exceeds 32 bits, whether in frequency meter or counter mode, an overflow indicator displayed  in the form of a plus sign (+) immediately to the right of the right-most digit.

The counter counts as long as the input signal crosses the input thresholds of the 74HC02. See the 74HC02 data sheet for your particular 74HC02 for details.

An outboard preamp/precaler, which extends the frequency measurement capabilities to beyond 300 MHz was designed after this project. Click here to see the outboard preamp/prescaler.

 Circuit and Firmware Description

The 5 Mhz and 10 MHz single-chip verions only needs inverters for the serial interface, the microcontroller, and a few passive components. Be sure to use a 20 MHz crystal and an ATtiny2313-20 for the 10 MHz version, and a 10 MHz crystal for the 5 Mhz single-chip version. Use this hex file for the 10 MHz single chip version: nfmtrT050524.hex.

The 5 MHz and 10 MHz frequency meter versions takes their inputs directly on pin 9 of the AT90S2313. The 74HC4060 and 74HC02 and their associated circuitry are omitted. This version of the serial interface only drives from +5 volts to ground. Use this version of the code for the 30 MHz circuit ffmtr040916A.asm , ffmtr040916A.hex.  If you use this circuit with the 300 MHz Preamp/Prescaler, omit the 2.2k resistor on the input and connect the input directly to pin 12 of teh 74HC02.

Frequency measurement is treated differently from counting.

Frequency measurement is performed by clocking the 74HC4060, which is capable of being clocked at over 30 MHz, and then counting the overflow pulses from the 8th flip-flop in the 74HC4060's signal path using the AT90S2313-10's on-chip 16 bit counter, which is limited to a maximum input clock rate of 5 MHz 30 MHz/256= 117 kHz). At the end of a frequency measurement period, the input to the 74HC4060 is gated off by turning the bi-directional I/O port, D3, on the AT90S2313-10 from a high impedance input to an output set high. This results in the input signal is then dropped across the 2.2k resistor between pin 13 of the 74HC02 and the clock input of the 74HC4060. I borrowed this technique from Chris Krah's LC frequency meter design in which he used this method to gate the input to a counter using an AT90S1200's I/O pin. After moving the contents of the AT90S2313-10's on-chip 16 bit counter to working registers, the AT90S2313-10 toggles the clock pin on the 74HC4060 while decrementing an internal register from $FF until the of the 74HC4060 toggles again. That way, the contents of the prescaler is transferred to an register internal to the AT90S2313-10.

So far, that accounts for three bytes: The 8 bits of the 74HC4060 and the 16 bit on-chip counter. Overflow from the 16 bit on-chip counter causes an interrupt, during which a fourth byte is incremented. If incrementing this fourth byte results in the byte becoming equal to zero, an internal overflow flag bit is set so that overflows will be denoted in the display. The resulting 32 bits are converted to 9 1/2 decimal digits and sent via the UART to a terminal or display.

In the counting mode, the instrument needs to be able to display the current total count several times per second, so the display appears to be a continuous display or the running total. While displaying the total count, it cannot miss an incoming pulse, and since the prescaler would have to be emptied for each measurement to read out its contents, and while reading out its contents, some pulses could be missed, it is necessary to bypass the prescaler and count directly using the AT90S2313-10's on-chip 16 bit counter. Overflows from the counter cause interrupts which then causes a virtual 16 bit internal register (ZH,ZL) to be incremented, checking for overflow of the Z register, thus giving a 32 bit count. The maximum clock rate for the on-chip 16 bit counter is 5 MHz

The version of the code that does not use a prescaler (nfmtr040916A.asm) and uses the same set of registers as the counting mode for the prescaler version of the code - it just uses the 16 bit on-chip counter and overflows to the Z register.

The fist gate that the input signal sees, a 74HC02, is an inverting buffer. It drives both the 74HC4060, which is the 30 MHz prescaler, and the other sections of the 74HC02, which act as a multiplexer to drive the AT90S2313-10's on-chip 16 bit counter with either the output of the prescaler in frequency measurement modes or directly from the output of the buffer in the counting mode.  Without the buffer, pulses from the gating of the input of the 74HC4060 would appear on the input. The version of the code that does not use a prescaler does not require the buffer or multiplexer - the input signal drives D5 (pin 9) of the AT90S2313-10 directly.

One thing I should point out, is that the firmware provides slightly longer sampling times than is displayed. The reason for this is that the crystal in my prototype ran a littel fast. Since I am not going to make more than one or two of these, trimming the delays in the code is a suitable method of triming the timebase.  For example, the 1 second sampling  period is 1.0003509 seconds, which is 350 parts per million longer than ideal. Not terribly far off. The 1, 10, and 100 second sampling periods are generated by the routine  named "Delay1Second:". The 100 millisecond samping period is set by the routine named "Delay100ms:".

Both "Delay1Second:". and  "Delay100ms:" generate their long delays by calling the routine "Delay:" twice with registers "delayreload0" "delayreload1", and "delayreload2" preloaded with different delay values each time "Delay:" is called.. The Delay routine is a set of three nested count-down loops, so the longest delay the routine is capable of generating occurs when the routine is called with all  three delay reload values equal to zero. In this case, the delay is 5.05 seconds. The shortest delay occurs when all three reload values are set to 1. This produces a total delay of a few microseconds. The dealy is roughly proportional to the product of the three reload values, though because of where each is used in the nested loops, each reload value has a slightly different effect on the delay, and this may be used to fine-trim the delay. While coarse adjustment of the delay time can be systrematic, I find myself performing cut-and-try experiments to make the fine adjustments.

The reason I used firmware timing routines instead of using the on-chip hardware timer is that I found on a previous project that the total count exhibited a little less jitter when its done this way. I really like it when that last digit is stable.

To make this an even more serious frequency meter, a stabilized oscillator can be used to drive the clock input of the AT90S2313-10. I recommend not using the on-chip calibrated oscillators on the ATMega and ATtiny controllers, as they would require either temperature compensation or stabilization.


As you might be able to tell from the photograph at the top of this page, I did not use a groundplane board. I just tried to keep the wiring short and to make sure there was a fairly direct ground return for each high frequency signal (those are limited to the 74HC02 and 74HC60, besides the decoupling on the AT90S2313-10. In a couple of places, I added extra ground wires (#30 tinned copper) more or less in parallel with the high frequncy singal lines.

Each of the 74HC chips has a 1000 pf ceramic power supply decoupling capacitor. The decoupling capacitor for the AT90S2313-10 and ATiny21313-20 is tantalum. You should be able to get by with a small ceramic capacitor, but if you do, make sure you have a large enough capcitor on the output of the 5 volt regulator to stabilize it.

HOME (more projects)

Contents ©2004 and 2005 Richard Cappels All Rights Reserved. http://www.projects.cappels.org/
First posted in September, 2004

You can send  email to me at projects(at)cappels.org. Replace "(at)" with "@" before mailing.

 Use of information presented on this page is for personal, nonprofit educational and noncommercial use only. This material (including object files) is copyrighted by Richard Cappels and may not be republished or used directly for commercial purposes. For commercial license, click here.

Liability Disclaimer and intellectual property notice
(Summary: No warranties, use these pages at your own risk. You may use the information provided here for personal and educational purposes but you may not republish or use this information for any commercial purpose without explicit permission.) I neither express nor imply any warranty for the quality, fitness for any particular purpose or  user, or freedom from patents or other restrictions on the rights of use of any software, firmware, hardware, design, service,information, or advice provided, mentioned,or made reference to in these pages. By utilizing or relying on software, firmware, hardware, design, service,information, or advice provided, mentioned, or made reference to in these pages, the user takes responsibility to assume all risk and associated with said activity and hold Richard Cappels harmless in the event of any loss or expense associated with said activity. The contents of this web site, unless otherwise noted, is copyrighted by Richard Cappels. Use of information presented on this site for personal, nonprofit educational and noncommercial use is encouraged, but unless explicitly stated with respect to particular material, the material itself may not be republished or used directly for commercial purposes. For the purposes of this notice, copying binary data resulting from program files, including assembly source code and object (hex) files into semiconductor memories for personal, nonprofit educational or other noncommercial use is not considered republishing. Entities desiring to use any material published in this pages for commercial purposes should contact the respective copyright holder(s). 

Key phrases for search engines: AVR frequency meter. Frequency meter AVR, frequency meter circuit, VHF frequency meter.