Precise calculation of frequencies?
Oldbitcollector (Jeff)
Posts: 8,091
I've got a project I'm working on which requires some very
precise toggling of an I/O line. Naturally I've done delays with waitcnt, but never anything this accurate.
Here's what I'm playing with... (at 80mhz of course.)
Can someone guide me into how I to calculate pin toggling this precise?
Is this even possible?
Thanks!
OBC
precise toggling of an I/O line. Naturally I've done delays with waitcnt, but never anything this accurate.
Here's what I'm playing with... (at 80mhz of course.)
4.672 hertz 2.336 hertz 1.168 hertz .586 hertz .292 hertz .146 hertz .073 hertz
Can someone guide me into how I to calculate pin toggling this precise?
Is this even possible?
Thanks!
OBC
Comments
Jonathan
80,000,000 Hz/4.672 Hz = 17123287.67; round up to 17123288
80,000,000/17123288 = 4.6719999 Hz
Would that be too far off? And is this to be a square wave or just a pulse of some width?
# system clocks per toggle = (# system clocks per second / frequency in Hz) / 2
You'll need to do this on paper to keep as much precision as you can.
Since the Spin overhead per toggle is fixed, you could just use this number first, time some large number of toggles, and then adjust the # system clocks per toggle to adjust for the fixed overhead.
I have a very simple answer for you, provided the timing application can be run in assembler. With this approach you can precisely time pulses to 1 uSec granularity, and to 1 clock cycle accuracy.
I have another (again, assembler only) approach that will time any (reasonable) pulsewidth to 1 clock granularity as well as accuracy.
Your app code required is simply:
======================================
V1Pulser long uSecTicks <<9 + Pulser ,1 'two longs here
Pulser xor outa,#PortBit
jmp #KernelPause
======================================
and the kernel takes care of the rest.
This can also run concurrently with other kernel scheduled co-operative assembler programs in the same cog, such as serial I/O ar butto-push scanners.
Let me know if this is interesting to you, and I'll send you the kernel.
Cheers,
Peter (pjv)
In NCO mode the output frequency = (FRQA / 2^32) * system frequency, or the reverse:
FRQA = 2^32 * output frequency / system frequency.
The PLL modes require a FRQA frequency of 4-8MHz and the smallest multiplier is 1/8 FRQA. For 0.073Hz you'd need a 2^-25 multiplier, or 2^-22 beyond the PLL divisor. You could use the video generator, but you would need to periodically WAITVID to reload the pixel shifter.