Schematics and C code for a PIC
frequency counter circuit operating up to about 50 MHz.
A PIC
Frequency counter circuit using an
Eight digit multiplexed 7 segment
display...
This PIC frequency counter circuit uses a multiplexed seven segment display
and uses timer 1 to count edges of
the input signal.
It uses the simpler method of direct frequency
measurement which is easy to do but means that the number
of digits
displayed depends on the input frequency.
Note:
If you want to display all digits all the time there is a technique
called reciprocal counting
- but this requires floating point (maybe fixed point) routines and
would be difficult to implement with this hardware since it needs constant time routines
to count accurately.
In the same way as the LCD
project this frequency counter circuit uses TMR1 in 16 bit counter mode
to count the input signal edges. Counter overflows 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.
Get a frequency counter now
Here's a selection of
frequency counters that you can buy on Ebay (if you don't want to make
up your own then you can get a bargain
here - and it will have all the front end circuitry made for you).
Just click on
the Counter you want and
start bidding.
The major difference in this
project is that the display must be continuously refreshed so that your
eye is fooled into thinking that display as is not flickering
(persistence of vision).
For this frequency counter
circuit project the display is refreshed every millisecond which is
excessive - but does work. This refresh rate was chosen due to the
timing period of the gate loop (999us) and allows easier constant time
operation. Your eye only needs a refresh rate of about 50Hz or 20ms.
Pushing the refresh rate
higher also shows you how to split the processing of a machine code
algorithm, in the C environment, into several pieces so that the
display can be refreshed at an approximate 1ms rate.
Just as in the LCD project the
measurement time is 1 second the final count is actually the frequency
of the input signal and again using the 1 second measurement time gives
a frequency resolution of 1 Hz.
Note: The exact
maximum operating frequency is determined by the PIC input pin
characteristic.
Compiler
Mikroelectronika
C compiler V5.0.0.3 Free!
Target
16F877A
(retargetable to other PICs that have TMR1)
Software
level
Advanced.
Software
notes
Constant
time code.
Hardware
level
Intermediate
Hardware
notes
LCD
will work with LVP (if PGM pin is pulled high). Seven segment
multiplexing.
Project
version
1.01
Project
files
Enter
your details to get the Download
Link
and get the microcontroller newsletter:
Test wiring 1 :
Outputs constant digits to the display and reads "12345678"
from left to right. You can use this test to see if PORTD and
each transistor driver is connected correctly.
Test wiring 2 : Outputs a shifted digit set from 1-8 to test PORTD
connections to each 7 segment. Just observe each digit and
make sure it goes through each number 1 to 8.
Compilation
For a tutorial on compiling
these files click
here.
You can recompile the frequency counter circuit
files if you want examine code operation (using the built in simulator)
or change the source code. Note the hex file is contained in the
download.
The main circuit blocks of the
frequency counter circuit are shown in
the diagram below.
The 8 seven segment displays
are multiplexed using a Johnson counter (4017) that activates a single
output after each clock pulse. Port A drives the reset line and clock
signal to the 4017 and transistors at the outputs of the 4017 are
connected to the common cathode of each seven segment display. This
lets the micro turn on each display sequentially. Port D drives the
segment enable lines to control the character displayed.
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 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 a Timer 1 hardware and and has enough memory to hold the
program and enough ports to drive the 4017 and the segment enable lines
(8 bits).
The LED is toggled at the end
of every gate time to indicate that the processor is alive - so if
there is no input signal you can tell that the software is working.
You can program the PIC in
circuit through the ICSP
connector.
Frequency_counter...c : contains the code start
point (in routine 'main').
bcd.c : machine code to convert a long to a bcd.
delay.c : code to create fixed delay times.
sevensegment.c : Constant time seven segment
refresh update routines.
gate.c : Accurate 1 second time delay while
calling 7seg refresh.
bit.h : macros for bit manipulation.
def.h : control for simulation help.
All other header files contain
prototypes.
PIC frequency counter circuit 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.
Frequency_counter_4MHz_7seg_tmr1.c
This file contains the port
initialization and main routine.
After initialization the code
enters an endless loop where it continuously performs a measurement and
display operation. Throughout the loop the display refresh routine is
called (approx every millisecond). Also in main the gate_loop routine
is called.
The gate loop is tuned to just
below a millisecond so that the caller (in main) can adjust the exact
delay taking account of any delays caused by calling the gate loop
routine itself.
Note that the timer overflow
is polled within the gate loop and the seven segment display is
refreshed . Extra statements in the else part of if statements allow
constant execution time whether the conditions are true or false. This
allows the loop time to be accurately calculated since it always has
the same execution time.
gate.c
This file contains the gate
loop time measurement routines - the loop time is tuned to 999us so
that the caller can calibrate the 1 second delay time (accounting for
compiler optimisation and return from call instructions).
The gate_loop routine calls
the constant time seven segment display update and also checks (in
constant time) the timer 1 overflow counter.
sevensegment.c
This file has the 8 digit
seven segment display driver.
The first output from the 4017
is not connected so this acts as the reset state. At every call the
next digit is output on port D and the 4017 is advanced one bit by
strobing the clock. In this way after each call the next digit is
displayed.
All the routines here are made
into constant time routines so that the gate loop (the calling routine)
can make an accurate 1 second time measurement.
delay.c
Delay routines were created
using machine code so that they have a fixed execution time i.e. they
do not change as the compiler re-optimizes the code. They are also
fixed in memory location to avoid bank change problems.
bcd.c
This routine was created in
machine code to save space on the smaller chips and it also results in
faster code than using the built in routines for long multiply and
divide.
It uses the Add 3 method to
convert the unsigned long into an ASCII value that can be displayed on
the LCD.
For this project the routine
is split into separate processing functions
ulong2bcd_p1(df);
ulong2bcd_process(void);
The second routine is called 8
times so that the seven segment display can be updated every
millisecond (approx). This is true at 4MHz - obviously using a faster
crystal would allow less calls e.g. for a 20MHz crystal you could get
away with two calls. Using a faster crystal makes timing slightly more
difficult since for a 20MHz clock the instruction cycle is 200ns not
1us.
The bcd conversion is not the
fastest around but it is faster than letting the compiler using long
divide or multiply and this does show how to use machine code in the C
source code. It also shows how to split processing time up for the
machine code program.
def.h
Contains a control to let the
simulator update variables where needed.
bit.h
This contains macros for bit
manipulation which should be compiler independent.
End of code description for
the frequency counter circuit.