Then you fire up one of the timers...
Say it runs at a base frequency of 1Mhz (4Mhz OSC / 4 ), each tick is 1us.
Clear the timer...
Wait for a rising edge of the input and start the timer.
Wait for the next rising edge of the input and stop the timer.
Subtract the few cycles it takes to start and stop the timer.
Since you want a frequency of 4Khz, the timer should have a count of 250 in it (after the necessary subtractions).
If the count is 249, then your input freq is 4016 Hz, if 251, then 3984 Hz.
But you want sub-Hz resolution...
So kick up the PIC to 40Mhz, and the timer runs at 10Mhz, each tick is .1us.
Using the same logic as above, the timer should have a count of 2500 in it between the 2 rising edges (after the subtraction).
If the count is 2499, the freq is 4001.6 Hz, count = 2501 then freq = 3998.4 Hz...
But that's still not quite sub-Hz resolution...Sooo....
Instead of counting one rising, you go for the max resolution, wait for the next 25 rising edges. After that 25th rising edge, the timer should have a count of 62,500.
If it's 62,499, your input frequency average over the last 25 cycles was 4000.0640010240163842621481943711 Hz.
If the timer reads 62,501, the input frequency average over the last 25 cycles was 3999.9360010239836162621398057631 Hz.
Problem is...it takes 25 cycles to get that number, which might not be fast enough for you. The only way to increase this is to increase the speed of the timer, hence the CPU. With a PIC18F, you aren't going to get much better than .1us accuracy at 40Mhz.
And since you want to do this in the background, that's easy enough by applying your input signal to, say, the RB0 interrupt, and having the interrupt routine do the timer starting/stopping, clearing, count saving and so on. And your main loop handles the hard math...
Bookmarks