Usually a frequency counter contains some functional blocks :

The input signal it is applied to a gate G and then to a counter, for a precisely period of time After this period of time , the input signal it is stopped for a while and then the cycle it is repeated. In the time of break the content of counter it is transferred in buffer memory and then it is displayed. After the load of buffer memory , the contains of counter is reset of reason to can begin a new count cycle. The successions of this signals are conform the follows diagram :

The signals COUNT , LE , RESET are generated from the base of time . A very simple base of time witch contains 2 ICs can be build using the folow schematic:

Unfortunately this schematics have a long time of cycle Tc = 2s. In order to make this time shorter we can modified only the times Tle and Treset . But that means to use more CIs or another solution is to use a microcontroller with the necessary software. I have used a PIC microcontroller type PIC16F84A because it is easy to programm and the power consumption is low. The program is written for the PIC16F84A but cheaper PICs (as PIC16C61) can be used.
;=======Timer.ASM=================================18/06/00==
; rb0 1s
; rb1,rb2 .75ms
; internal clock
; standard crystal 4 MHz XT
;------------------------------------------------------------
; configure programmer
list p=16f84A;f=inhx8m
_CP_OFF equ H'3FFF' ;code protect off
_PWRTE_ON equ H'3FFF' ;Power on timer on
_WDT_OFF equ H'3FFB' ;watch dog timer off
_XT_OSC equ H'3FFD' ;crystal oscillator
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
;------------------------------------------------------------
; cpu init
portb equ 06
count1 equ 0C
count2 equ 0D
count3 equ 0E
;------------------------------------------------------------
; bit init
w equ 0
f equ 1
;------------------------------------------------------------
org 0
;
;------------------------------------------------------------
init
movlw 0
tris portb ; set portb as output
movwf portb
start
bsf portb,0 ;rb0=1
call pause ;wait 1s
bcf portb,0 ;rb0=0
bsf portb,1 ;rb1=1
call pauza ;wait .75 ms
bcf portb,1 ;rb1=0
bsf portb,2 ;rb2=1
call pauza ;wait .75 ms
bcf portb,2 ;rb2=0
goto start
pause movlw .8 ; load count3 with decimal 8
movwf count3
d3 movlw .250 ; load count1 with decimal 250
movwf count1
d1 movlw .165 ; load count2 with decimal 165
movwf count2
nop ; compensation 1us
d2 decfsz count2,f ; decrement and skip next line if zero
goto d2 ; if not zero
decfsz count1 ; decrement count1 if count2 is zero
goto d1 ; do inside loop again if count1 nz
decfsz count3 ; decrement count3 if count1 is zero
goto d3 ; do inside loop again if count3 nz
retlw 00
pauza movlw .250
movwf count1
lop1 decfsz count1,f
goto lop1
retlw 00
;------------------------------------------------------------
end
;============================================================
The hex code can be download from here. For the counter I have used two specializated IC's type MMC22926, that works up to 6 Mhz, the National Semiconductor alternative to MMC22926 is 74C926. If a higher frequency is need to be processed, a ECL divider can be used at gate input.
Base of time schematics using a PIC16F84 microcontroller.
Counter schematics using two specializated IC's type MMC22926.
Display schematics