# High Frequency Counter with a 10Mhz PIC

Joined Aug 17, 2013
858
Hi,

I'm trying to make a Frequency Counter with a PIC running at 10 Mhz, but I can't get it to pass the 700 KHz. I found a couple of websites that claim to have achieved up to 80 Mhz with the same type of MCU, but they don't offer the source code to see how they've done it.

I would appreciate any help, advice or suggestions; or if anyone could direct me towards or explain the technique that I need to use it would be great.

In my code I'm already using interrupts and as few lines as possible; with Timer 0 tracking the time between the signal pulses through Timer 1.

Code:
void interrupt myISR() // Called on any interrupt
{
//      TMRxIE Overflow Interrupt enable
//      TMRxIF Overflow Flag bit
if(INTCONbits.TMR0IE && INTCONbits.TMR0IF)
{
count+=256;
INTCONbits.TMR0IF = 0; // clear the flag
}

if(PIE1bits.TMR1IE && PIR1bits.TMR1IF)
{
frequency=(count+TMR0)*4;
count=TMR0=0;

PIR1bits.TMR1IF = 0; // clear the flag
}
}

Last edited:

#### atferrari

Joined Jan 6, 2004
4,629
Go to PIClist. There is a design there which is a classic.

Search also something like "PIC" "MONDO". Hay muchos .

#### Art

Joined Sep 10, 2007
806
You can prescale the signal coming in with decade counters, I don't see how it's possible to read a faster freq than the pic is running when you think about it.

#### MrChips

Joined Oct 2, 2009
26,470
You need to say which PIC. Does the PIC timer module have a direct pulse counting input?

#### NorthGuy

Joined Jun 28, 2014
611
Your code isn't important much because it only runs once per 256 pulses. Some of the timers might be run in 16-bit mode, or you can use pre-scaler.

The counter is synchronous. I think it samples twice per instruction cycle - at 5MHz, so you should be able to get reasonable results up to 1.5-2MHz. But it can be only once, then your limit is 0.7-1MHz.

80MHz is absolutely out of the reach unless external dividers are used.

#### jjw

Joined Dec 24, 2013
775
You can prescale the signal coming in with decade counters, I don't see how it's possible to read a faster freq than the pic is running when you think about it.
50Mhz frequency counter has been done with 4Mhz PIC16F84.
Input to timer0, that has fast ~50Mhz prescaler.
Microchip AN592
http://f6csx.free.fr/PROJETS/Fmetre/AN592.pdf

Joined Aug 17, 2013
858
I'm using a PIC16F88 with the prescaler at 1:8; which is the maximum for Timer 1. I can't use the 1:256 from Timer 0 because I have its interrupt tracking the input pulses directly through the ToCKI pin.

I'm also running the PIC at 8 Mhz, which is the maximum I can get from the internal clock, as I don't have a single extra I/O pin to free and attach a 20 Mhz crystal.

#### NorthGuy

Joined Jun 28, 2014
611
I was wrong. The built-in pre-scaler is asynchronous, so you can get to higher frequncies. However, data sheet for your PIC states that the shortest detectable period for Timer0 is 20 ns (assuming 50% duty cycle), which translates to 50MHz. If duty cycle is not 50%, then it's less than 50MHz.

However, the timer's sampling rate is 4MHz if you run your PIC at 8MHz (2MIPS), so at the very best you can detect after-prescaler frequencies up to 2MHz (in practice it's about 1.2MHz or so). Multipled by 8 (1:8 prescaler), this gives you about 10MHz. To get full theoretical 50MHz you will need at least 1:64 prescaler.

Joined Aug 17, 2013
858
I'm looking for a way to change the input pulse to Timer 1 and use Timer 0 as the timer; since Timer 1 only has a 1:8 prescaler and Timer 0 can go up to 1:256. But this is proving more difficult than I thought, since I have all the I/O pins already allocated to some other function.

I have some doubts whether or not increasing the prescaler will achieve better results. The reason I'm saying this is because if I change the prescaler down -tried 1:4 and 1:2 instead of 1:8- I don't see any difference; I still get up to 700Khz when in theory I should get worse results. The only noticeable change is a worse resolution at lower frequencies.

What did improve the counter was increasing the clock from 4Mhz to 8Mhz. At the beginning with 4Mhz I could only read up to 400Khz; now with 8Mhz the top is around 750Khz.

#### Art

Joined Sep 10, 2007
806
Nice
I have an issue now where it would be nice to count faster than the pic is running.
but it's to keep track of hardware PWM but I'm probably already out of timers.

#### atferrari

Joined Jan 6, 2004
4,629
I'm also running the PIC at 8 Mhz, which is the maximum I can get from the internal clock, as I don't have a single extra I/O pin to free and attach a 20 Mhz crystal.
What precission does it ensure?

#### takao21203

Joined Apr 28, 2012
3,702
I was wrong. The built-in pre-scaler is asynchronous, so you can get to higher frequncies. However, data sheet for your PIC states that the shortest detectable period for Timer0 is 20 ns (assuming 50% duty cycle), which translates to 50MHz. If duty cycle is not 50%, then it's less than 50MHz.

However, the timer's sampling rate is 4MHz if you run your PIC at 8MHz (2MIPS), so at the very best you can detect after-prescaler frequencies up to 2MHz (in practice it's about 1.2MHz or so). Multipled by 8 (1:8 prescaler), this gives you about 10MHz. To get full theoretical 50MHz you will need at least 1:64 prescaler.
some years ago I have done a counter with a 16F54- clocked with an IF transformer coils, so maybe 1MHz.

Then I used 18.0 Mhz CXO as reference, and turned the screw until the display matched.

Its easy, cheap and works with almost all PICs. Most PICs have an interrupt which you can use to detect overflow. Even easier. Some 18F PICs can run at 40 MHz, some 8bit PICs at 32, PIC 32 run at 50, 80, 100 or 200 MHz, but of course its a problem to route signals with more than 30 MHz.

#### NorthGuy

Joined Jun 28, 2014
611
If the pre-scaler is asynchronous then its operations should be independent of the CPU clock.

What kind of signal do you get? Is it regular? What duty cycle?

Joined Aug 17, 2013
858
Just reached 2Mhz!!!

I tried switching Timer0 and Timer1 (using the first as timer and the second as input for the signal), and on top of getting a really bad resolution at low frequencies, I was back again to the 400Khz barrier.

However, when I mounted it back to the original configuration -with Timer0 for the signal input and Timer1 as timer- I misplaced a 100k resistor and used it in series between the signal and the T0CKI pin; which prevented me from passing 500Khz. Tried without resistor, as I didn't even remember what that resistor was even doing there, and same result. Then I remember that in the original design I used it as a pull-down resistor. So, I began trying with different resistors and found that with 10k I can get up to 2Mhz.

From this point I'm not sure the signal will be clear enough; as I have it all on a breadboard and I always had problems when passing over 2Mhz (e.g. the amplitud begins to drop, the square wave begins to curve, and so on).

If the pre-scaler is asynchronous then its operations should be independent of the CPU clock.

What kind of signal do you get? Is it regular? What duty cycle?
I'm using the PDO output of the MAX038, which is a +5v 50% duty cycle square wave.

Last edited:

#### takao21203

Joined Apr 28, 2012
3,702
Code:
if(INTCONbits.TMR0IE && INTCONbits.TMR0IF)
{
count+=256;
INTCONbits.TMR0IF = 0; // clear the flag
}
Code:
if(TMR0IF){count++;TMR0IF=0;}
later

Code:
if(count==0xff){count_2++;count=0;}
if(count_2==0xff){count_3++;count_2=0;}
you can increase resolution with changing the prescaler, but using other than 8 bit variables in the interrupt routine isnt adviseable. You dont need to check the IE bit, as IF is raised anyway; just no INT is caused.

#### NorthGuy

Joined Jun 28, 2014
611
I'm using the PDO output of the MAX038, which is a +5v 50% duty cycle square wave.
Must be something circuit related - stray iductivity, capacitance, noise, that sort of thing. Stick them both next to each other.

Joined Aug 17, 2013
858
I think I found the problem...

As you increase the frequency, the quality of the PDO output from the MAX038 drops. I took some pictures to explain it more accurately:

This is a picture of the outputs at 100Khz and without drop down resistor. The top signal is from the regular output, and the one on the bottom is from the PDO. Notice how the falling edge begins to curve (it was meant to be a square wave exactly like the one on the top).

And this one is at 1Mhz, also without drop down resistor. At this frequency it already looks more like a triangular wave than a square wave.

However if I add a drop down resistor up to a minimum of 10k I can sort of stretch it as in this picture. The higher the resistor value the less effective.

But if I go under 10k this is what I get. It won't reach 5v, so the PIC will not detect the signal.

I can't use the normal output because that one is not a DC digital 5v, it's an AC 2v peak to peak. So I was wondering: is there anything I can do to improve the quality of the PDO square wave?

Edit: I took those pictures with just the oscilloscope connected to the PDO.

Last edited:

#### NorthGuy

Joined Jun 28, 2014
611
You rise time is around 2us, and the fall time is even worse. Looks like you have some sort of capacitive load (parallel strips of breadboard?) or series inductance (long winding wires?).

#### takao21203

Joined Apr 28, 2012
3,702
The statement breadboard rows and long wires can cause 2uS rise time is quite a stretch.

You'd see some effects starting to kick in above 30 MHz.

10 MHz - 100nS
30 MHz - 33nS

How about a schematic / picture of the whole circuit?

#### NorthGuy

Joined Jun 28, 2014
611
The statement breadboard rows and long wires can cause 2uS rise time is quite a stretch.
Yes, this is a long stretch

You would need 100K resistor followed by two parallel breadoard strips (10pF) to damage transitions like that. Must be something else.