Assuming a 50% duty cycle on the input signal, COUNT might work well for you. There are a few tricks a person could use to fool the compiler into giving you a result that would be 'sub-hertz'.
Assuming a 50% duty cycle on the input signal, COUNT might work well for you. There are a few tricks a person could use to fool the compiler into giving you a result that would be 'sub-hertz'.
Thanks for the suggestions, but at the moment I think I am getting quite a bit more resolution since essentially my time increment is 1/5MHz or 200nsec and then this is applied over a longer period of time in regards to only measuring over only 1 cycle, there is an extended resolution due to the fact that it is over 200 cycles rather than just one. It would be nice to use the hardware timers as I would like to do this in the background more on an interrupt basis rather than taking using CPU time to make the measurement, but I do appreciate the ideas.
T
The minimum period for COUNT is 1mS but I've never tested it to see how accurate that is. You might try it and compare it to your current method for accuracy. It counts low to high transitions so duty cycle is really immaterial. I'm not sure why the manual even mentions duty cycle. If you use 1mS, then the result x 1000 will give the frequency. It's certainly simpler than what you do now.
Last edited by dhouston; - 3rd June 2008 at 00:58.
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...
yes....resolution and overhead
use ccp (capture/compare) module in capture mode....
count at 10MHZ,(Fosc/4 from 40MHZ) set for every 16th rise or fall edge to get counts directly, at 4000.0 hz, count is 40000
-at 3999 hz count is 40010
-at 4001 hz count is 39990
freq then = (40,000 +/- difference)/10 hz down to .1HZ
i think?
don
actual hz calculation........
HZ = 16x10^7/count (from ccp) within range of 2500hz to 10MHZ ?
for ccp @ every 16 edges.
don f
skimask your last description is exactly what I am trying to do. My code essentially does just that over a 200 cycle period but not very gracefully as written, the start and stop of Timer1 I don't thinks is well done as I am using software to do it rather than hardware. In my attempt to measure the frequency fast, the physics of the problem limits how fast the measurement can be done for a given accuracy, but when comparing to a frequency counter approach I would need a 10 second period for 0.1Hz resolution, where by measuring the period as you point out can provide great resolution fast relative to a frequency counter, I guess I should have been more clear in my original posting, because my target is ~100 msecs for the measurement time. After doing more research it looks like the approach of using the capture/compare module with Timer1 as you point out Don is the way to go. I have not used the capture mode in the PIC's in an interrupt mode, are there any good code examples.
Terry
As they say, you can have 2 of 3 things...fast,good,cheap...
You can have it fast, you can have it good, it won't be cheap.
You can have it good, and you can have it cheap, but it won't be fast.
You can have it cheap, and you can have it fast, but it won't be good
I think you're method will work, and I wouldn't doubt that what you are using right now could work well enough. Why not 'remember' the last bunch of readings, say the last 10 readings, then average them out, discard the oldest, plug in the newest...a moving average if you will. You won't necessarily gain resolution, well, yes you will since you've increased the effective sampling time. You can keep your 100ms measurement time, and still get fairly decent resolution.
Bookmarks