[time-nuts] 32768 Hz from 10 MHz
dave.martindale at gmail.com
Fri Feb 3 04:03:46 UTC 2012
On Thu, Feb 2, 2012 at 12:21, Tom Van Baak <tvb at leapsecond.com> wrote:
> It's possible to use Bresenham with two integers 10,000,000 and
> 32,768 but I found no way to perform all the 24-bit calculations
> on an 8-bit PIC quick enough. Removing the GCD often helps
> but in this case the accumulator remains 3-bytes wide.
In this particular case, the divisor your want is 2^15 / 10^7. You
can remove a common factor of 2^7, giving 2^8 / 5^7, or 256 / 78125.
If you only want a square wave output, you should be able to do this
with a 17-bit binary counter and some logic. In concept, it looks
- initialize register to 0
- every input clock, add 256 to the register
- when the register is greater than or equal to 78125, set overflow
bit and subtract 78125 from the register.
In practice, you'd probably set the register to 78125 and count down
to zero, using the "borrow" output from the subtract of 256 as
overflow. Then you don't need to compare the register to 78125.
Essentially, you've built a special-purpose DDS whose frequency
resolution is 128 Hz , and the output frequency you want is exactly
256*128 Hz. The average frequency is exact, and the output waveform
repeats every 1/128 sec.
> I'm curious how a 10 MHz-driven high-end DDS would generate
> 32 kHz with the lowest possible jitter?
You should be able to use a AD9913 to do the same 256/78125 division
described above, with exact output frequency, and sine wave output to
boot. If I've understood the datasheet correctly, you would program
the main DDS frequency tuning word to 14073748, which gets you as
close to 32768 Hz as possible without exceeding it. Using variable
modulus mode, you program the FTW and modulus of the secondary DDS to
65276 and 78125.
Every input clock, the main FTW of 14073748 is added to the main
32-bit register. At the same time, 65276 is added to the secondary
register. If the secondary register exceeds 78125 (which will happen
on most clocks with these values), the main register is incremented by
1 and the secondary register has 78125 subtracted. So over the course
of 78125 input clocks (1/128 second), the secondary register has
65276*78125 counts total added, which causes it to overflow 65276
times. The main register has 78125*14073748 added to it directly,
plus 65276 extra counts from the secondary register overflows. The
sum of those two values is exactly 2^40, meaning the main register
overflows 2^8 times in 78125 clocks.
After 78125 input clocks, both the main and secondary register have
returned to zero, so the sequence repeats exactly every 1/128 second.
In effect, the secondary register is acting as a variable-modulus DDS
that changes the FTW of the primary fixed-modulus DDS by only one
count, just often enough to make the division ratio exact. And
because the primary DDS is still fixed-modulus, you can still use the
top k bits of the accumulator to index into a sine lookup table, and
produce a sine wave output.
More information about the time-nuts