Advertisements

Archive for April 10th, 2017

DDS Musings: AD9850 and AD9851

The general idea is to build a specialized sine-wave source as part of a test fixture to measure quartz crystal / tuning fork resonators in the 10 kHz to 100 kHz band. AD9850 / AD9851 DDS modules are cheap & readily available, albeit with crappy two-layer PCB layouts and no attention to signal integrity:

AD8950 DDS module

AD8950 DDS module

Documentation seems scanty, at best. The Elecfreaks page may be as good as it gets, with a summary:

Serial mode just need connect GND,D7 WCLK, FQUP, REST, VCC, I-R

More doodling will be required.

Because the AD9850 has an upper clock limit of 125 MHz, of course those boards sport a 125 MHz oscillator-in-a-can. The AD9851 has a 180 MHz limit and an internal 6× multiplier, so it gets a more reasonable 30 MHz oscillator and can run at either 30 MHz or 180 MHz.

The included 70 MHz (?) reconstruction filter won’t do much to improve a 60 kHz signal. A much much lower outboard lowpass filter will be in order.

As far as the AD9850 goes, the output frequency comes from a 32 bit value determining the phase increment:

f = Δφ · osc / 232

Where

  • f = output frequency
  • Δφ = phase increment
  • osc = oscillator frequency (30, 125, or 180 MHz)
  • 232 = DDS phase counter width

The smallest frequency difference between successive phase increments is thus osc/232, which is 0.029 103 83 Hz at 125 MHz. Obviously, you can’t get nice round frequencies like 60.000 kHz, except by accident, but you can get close.

Alas, the resolution conflicts with tuning fork characterization, where you (well, I) want to step the frequency in nice round 0.1 Hz units across a 2 Hz range around 60.000 kHz. Because the crystal characterization requires closely spaced frequencies, where the difference between the test frequencies matters, you shouldn’t work from the nicely rounded frequencies on a display.

For example, successive values of Δφ produce these frequencies near 60 kHz:

  • 2 061 580 → 59.999 874 793
  • 2 061 581 → 59.999 903 897
  • 2 061 582 → 59.999 933 006
  • 2 061 583 → 59.999 962 104
  • 2 061 584 → 59.999 991 208
  • 2 061 585 → 60.000 020 312
  • 2 061 586 → 60.000 049 416
  • 2 061 587 → 60.000 078 520

In an ideal world, you could pick an oscillator frequency to produce nice increments. For, oh, say, 0.025 Hz increments, all you need is osc = 0.025 × 232 = 107.374 182 MHz. Riiiight.

The computations require more numeric resolution than built-in Arduino data types and math operations can provide. Floating point numbers have 6-ish significant digits (double is the same as float), which cannot represent the Δφ values or frequencies. Unsigned integers top out at 32 bits (unsigned long long int is not a thing), enough for 9 significant digits that can hold the Δφ values, but integer multiplication and division do not produce 64 bit results and overflow / underflow without warning.

Other than that, an Arduino would be just about ideal: the generator needs a small display, a knob, and a few buttons.

Perhaps storing precomputed Δφ values for specific frequencies in a table, then computing nearby frequencies as offsets from that value would suffice. This will require doodling some absurd significant figures.

Advertisements

11 Comments