Page 1 of 1

Frequency Counter

Posted: Wed Sep 19, 2007 10:32 am
by maheshkuruganti
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.

Posted: Wed Sep 19, 2007 2:43 pm
by Benj
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.

Posted: Thu Sep 20, 2007 7:48 am
by maheshkuruganti
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.

Posted: Thu Sep 20, 2007 9:59 am
by Benj
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.

Posted: Thu Sep 20, 2007 1:07 pm
by maheshkuruganti
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.

Posted: Thu Sep 20, 2007 1:53 pm
by Benj
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.

Posted: Thu Sep 20, 2007 5:28 pm
by mytekcontrols
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):
Image

Here is a condensed look at my code:
Image Image

ImageImageImage

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

Posted: Fri Sep 21, 2007 9:32 am
by maheshkuruganti
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.

Posted: Fri Sep 21, 2007 10:28 am
by Steve
Depending on the PICmicro used, there are only a limited number of pin interrupts. See the datasheet for the particular device you are using.

Posted: Fri Sep 21, 2007 10:39 am
by maheshkuruganti
How do I take the value from timer1. and how do I reset it to zero.for timer0 if say tmr0 = 0; in C code it is working.But tmr1 is showing up as an error.

Posted: Fri Sep 21, 2007 10:45 am
by Steve
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.