Frequency Counter
-
- Posts: 8
- Joined: Sat Sep 15, 2007 10:45 am
Frequency Counter
I am new to PICs.I want to make a simple Frequency Counter and display it on a LCD using a PIC16F877A and a 4Mhz Crystal.I want to know how to use TMR0 to do this.Please post a Flowcode file so that I can have a idea.Also how can you create a Custom interrupt for a random pin like RC0.I don't mind other ways of counting.I thought of TMR0 because on the internet I saw someting about it in ASM.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hello
I happen to have an example of this that I will email to you.
It origionally was designed for a 19.6608MHz crystal as that gave precise frequencies.
With the 4MHz crystal the most accurate I can achieve is displayed freq * 1.07 Hz but as long as the accuracy is not too vital then this is not a problem.
For example if the displayed frequency is 4Khz then the error will be 8.54Hz.
I happen to have an example of this that I will email to you.
It origionally was designed for a 19.6608MHz crystal as that gave precise frequencies.
With the 4MHz crystal the most accurate I can achieve is displayed freq * 1.07 Hz but as long as the accuracy is not too vital then this is not a problem.
For example if the displayed frequency is 4Khz then the error will be 8.54Hz.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 8
- Joined: Sat Sep 15, 2007 10:45 am
Thank You.
But what should I do to count high frequencies.Also how can we create Interrupts for other pins .I am trying to control a Max038 with a PIC and count the value to get a good idea of PICs.My control system works but when the counter is in its loop.The buttons do not work.The Max038 generates frequencies in excess of 10Mhz.
But what should I do to count high frequencies.Also how can we create Interrupts for other pins .I am trying to control a Max038 with a PIC and count the value to get a good idea of PICs.My control system works but when the counter is in its loop.The buttons do not work.The Max038 generates frequencies in excess of 10Mhz.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hello
If you are using a 4MHz crystal to drive your PICmicro then it will have a operating frequency of 1MHz. The frequencies you are able to acheive will be much less then this. Even if you had a 20MHz crystal you would not be able to count the 10MHz signal as the operating frequency would be 5MHz.
To count higher frequencies you will need to use a faster crystal and you may be able to use the T0CKI pin. This will require some C code that configures the TMR0 module to use this pin as a counter input. Refer to the PICmicro datasheet for help with setting this up.
If you get stuck then let me know and I will point you in the right direction.
If you are using a 4MHz crystal to drive your PICmicro then it will have a operating frequency of 1MHz. The frequencies you are able to acheive will be much less then this. Even if you had a 20MHz crystal you would not be able to count the 10MHz signal as the operating frequency would be 5MHz.
To count higher frequencies you will need to use a faster crystal and you may be able to use the T0CKI pin. This will require some C code that configures the TMR0 module to use this pin as a counter input. Refer to the PICmicro datasheet for help with setting this up.
If you get stuck then let me know and I will point you in the right direction.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 8
- Joined: Sat Sep 15, 2007 10:45 am
what if I use a high speed precounter like 74HC4040.It can count until 90 Mhz.If I can just contol the gate through a Schmitt trigger and read the values .It should do my job.I want to know how to read the input from 12bits of the counter.The problem is that if the frequency is high the counter is reset.So I need to monitor the overflows of the counter that changes state in about 1/4096 of the frequency in 1 sec.Could you please give a flowcode file for this using any 12 pins.Also what is the max frequency that can be measured using the example you sent.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hello
Yes that would be a perfect solution.
To create the 12 bit variable first you will have to create two byte variables and an int variable in flowcode.
b1 - Byte
b2 - Byte
I1 - Int
Then if you read the 8 least significant bits into b1.
eg
Input icon
b1 = portB
Then you will need to read in the remaining 4 most significant bits into b2.
eg
Input icon
b2 = portA
Finally you will need to combine the two bytes into the integer variable I1.
eg
Calculation icon
I1 = b1
I1 = I1 + ( b2 << 8 )
The example I sent can probably count up to a few tens of KHz. It would be capable of more but is limited due to the 4MHz crystal.
Yes that would be a perfect solution.
To create the 12 bit variable first you will have to create two byte variables and an int variable in flowcode.
b1 - Byte
b2 - Byte
I1 - Int
Then if you read the 8 least significant bits into b1.
eg
Input icon
b1 = portB
Then you will need to read in the remaining 4 most significant bits into b2.
eg
Input icon
b2 = portA
Finally you will need to combine the two bytes into the integer variable I1.
eg
Calculation icon
I1 = b1
I1 = I1 + ( b2 << 8 )
The example I sent can probably count up to a few tens of KHz. It would be capable of more but is limited due to the 4MHz crystal.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
- mytekcontrols
- Posts: 95
- Joined: Sun Aug 19, 2007 6:38 pm
- Location: Santa Rosa, California
- Has thanked: 4 times
- Been thanked: 7 times
- Contact:
I took a slightly different approach, and used a precise crystal controlled gating signal of 1 second coming into RB0/INT (pin 33 on PIC16F877A), and the 16 bit Timer1 as a simple counter. With Timer 1's counters set to increment based on external pulses arriving at the TICK1 input (pin 15 on PIC16F877A).
For the gating signal I chose a DS1307 RTC chip, which will also obviously double as a realtime clock/calendar. Actually any hardware that can generate the precise 1 second gating pulse could be used.
The beauty of this system, is that there is hardly any overhead as far as the PIC is concerned, and it should be capable of 65 kHz, even with a relatively slow clock speed on the PIC.
Here are the RTC connections (if battery back-up not needed, then ground pin 3):

Here is a condensed look at my code:




Theory of Operation:
After initializing Timer1, the interrupt is set to call the Freq_Counter Macro each, and every time the DS1307's SQW line drops low which = 1 second (the DS1307 would have been previously enabled by the DS1307_Start_1HZoutput Macro --- use the download link below to view the FlowCode source). This captures the 16 bit count, stores it into an integer variable (count), increments a seconds counter (this can be used as part of realtime clock), and clears Timer1.
The "count" variable is processed in the Main Loop, converted to a decimal aligned string array (Decimalize Macro), and then printed to an LCD display.
The only thing missing in my sample code, is error correction for overflow conditions (and I'm sure there are perhaps a few other bugs that have escape me). Anyway, it should give someone a good start if they decide to take this approach.
Enjoy
Here is the FlowCode source (version 3): http://mytekcontrols.com/FlowCode/Frequency_Counter.fcf
For the gating signal I chose a DS1307 RTC chip, which will also obviously double as a realtime clock/calendar. Actually any hardware that can generate the precise 1 second gating pulse could be used.
The beauty of this system, is that there is hardly any overhead as far as the PIC is concerned, and it should be capable of 65 kHz, even with a relatively slow clock speed on the PIC.
Here are the RTC connections (if battery back-up not needed, then ground pin 3):

Here is a condensed look at my code:





Theory of Operation:
After initializing Timer1, the interrupt is set to call the Freq_Counter Macro each, and every time the DS1307's SQW line drops low which = 1 second (the DS1307 would have been previously enabled by the DS1307_Start_1HZoutput Macro --- use the download link below to view the FlowCode source). This captures the 16 bit count, stores it into an integer variable (count), increments a seconds counter (this can be used as part of realtime clock), and clears Timer1.
The "count" variable is processed in the Main Loop, converted to a decimal aligned string array (Decimalize Macro), and then printed to an LCD display.
The only thing missing in my sample code, is error correction for overflow conditions (and I'm sure there are perhaps a few other bugs that have escape me). Anyway, it should give someone a good start if they decide to take this approach.
Enjoy

Here is the FlowCode source (version 3): http://mytekcontrols.com/FlowCode/Frequency_Counter.fcf
Michael St. Pierre
FlowCode V3&V4 Pro Registered User
Manufacture: Heat Load Controllers,
and a variety of other widgets.
FlowCode V3&V4 Pro Registered User
Manufacture: Heat Load Controllers,
and a variety of other widgets.
-
- Posts: 8
- Joined: Sat Sep 15, 2007 10:45 am
Thanks everybody.
I have finished the counter using the 74HC4040 as a precounter.I need to know how i can take the value out of the 16bit counter.I connected the last pin to it so that I can count fast and set it to increment on transition of the signal.Also how do I create a custom interrupt for any pin in general.We can use any pin to interrupt can't we.
I have finished the counter using the 74HC4040 as a precounter.I need to know how i can take the value out of the 16bit counter.I connected the last pin to it so that I can count fast and set it to increment on transition of the signal.Also how do I create a custom interrupt for any pin in general.We can use any pin to interrupt can't we.
-
- Posts: 8
- Joined: Sat Sep 15, 2007 10:45 am
- Steve
- Matrix Staff
- Posts: 3433
- Joined: Tue Jan 03, 2006 3:59 pm
- Has thanked: 114 times
- Been thanked: 422 times
The timer1 value is split into 2 registers: tmr1l and tmr1h (for the low and high bytes). But take care when reading the value - the following is an excerpt from the 16F877A datasheet:
6.4.1 READING AND WRITING TIMER1 IN
ASYNCHRONOUS COUNTER MODE
Reading TMR1H or TMR1L while the timer is running
from an external asynchronous clock will ensure a valid
read (taken care of in hardware). However, the user
should keep in mind that reading the 16-bit timer in two
8-bit values itself, poses certain problems, since the
timer may overflow between the reads.
For writes, it is recommended that the user simply stop
the timer and write the desired values. A write contention
may occur by writing to the timer registers while the
register is incrementing. This may produce an
unpredictable value in the timer register.
Reading the 16-bit value requires some care.
Examples 12-2 and 12-3 in the PICmicroΒ® Mid-Range
MCU Family Reference Manual (DS33023) show how
to read and write Timer1 when it is running in
Asynchronous mode.