No sooner had I uploaded my General purpose DDS controller project to this site, than I became interested in a conversation on a radio related forum, where it was suggested that it might be useful to have a minimal parts count frequency generator to cover the medium wave broadcast band. I suggested that the LCD display could be eliminated, and frequency adjustment could be by means of a pair of hex coded DIP switches. One switch would set hundreds of kilohertz, and the other switch would set tens of kilohertz. This would give enough adjustment range to more than cover the North American MW band with 10 kHz channel spacing. I quickly breadboarded the circuit, and adapted program code from my general purpose DDS controller.
Here is the circuit diagram:
As with the previous DDS controller project, a 16F630 is used for the microcontroller. This is an older processor, which can be programmed by the PICkit2 and its clones which are available for as little as $8.00 (with free shipping) on various online sales sites. Note that on the DDS module, both Vcc lines are connected together, and so power feeds through to supply the PIC controller. Also, note that on the DDS module, D7 and DATA are the same signal. So pin 7 from the PIC can be connected to either one. The circuit was arranged to make wiring as simple as possible. There’s no need to make a circuit board; the circuit can be quickly built on Veroboard or perfboard. If the DDS module is one of the ones supplied with a 3.3 volt oscillator, then the entire circuit will run just fine at this lower voltage. The PIC is designed to operate at this lower voltage as well as at 5 volts.
The line coding of the hex DIP switches is indicated on the diagram: 1,2,4,8 and C for common. Other brands/models of switches may have a different pinout.
After experimenting with these DDS modules for some time, I’ve noticed that on rare occasions, the DDS module fails to start up properly, and it’s necessary to cycle the power to get it going. I suspect that the source of this problem is related to the DDS chip’s power on reset sequence. On my earlier project, I had initially connected one of the PIC outputs to the DDS reset line so that the PIC program would force a reset upon startup. I later deleted this in order to free up a needed I/O line, noting that most other DDS controller projects that I’d seen simply kept the reset line permanently grounded. For the current project, I decided to implement a reset function for better reliability. Rather than use a separate PIC I/O line, I added the simple timing network consisting of the diode, capacitor and resistor connected between the clock line and the reset line. When power is applied to the circuit, the PIC I/O lines are in high impedance state and with one side of the capacitor connected to +Vcc, the reset line is immediately pulled high, holding the DDS in reset. Once the PIC has initialized, it pulls the clock line low, and the capacitor discharges through the diode, pulling the reset line low. This causes the DDS to start normal operation. When the PIC sends data to the DDS, the positive clock pulses are too narrow to affect the reset line due to the long RC time constant. However, the PIC can reset the DDS whenever necessary, simply by raising the clock line to logic 1, and holding it there for a few milliseconds. If one wishes to keep the circuit extremely simple, then the resistor, capacitor and diode can be eliminated, and the reset line permanently connected to ground. However, the DDS may not always start up reliably.
For this project, I took the opportunity to simplify some of the code used in the general purpose DDS controller. The keyboard read routine was replaced with a routine to read the rotary switches, and all of the frequency sweeping code was deleted. Also, I got rid of the lookup tables used for frequency calculation. Since the table values were all simple multiples of the same base value, it made sense simply to store that single value and calculate the ten coefficients when needed. Multiplication by 2 though 9 is done by repeated additions which is fast enough for this application. Eliminating the lookup tables saves considerable program memory. This allows storing the FTW (frequency tuning word) base values for both 125 MHz and 180 MHz reference oscillator frequencies. When the circuit is powered up, the PIC checks the state of input Y and selects the correct base value accordingly. For 125 MHz operation, input Y should be connected to +Vcc, and for 180 MHz, it should be grounded.
A second option selection input is provided: input X which causes an additional frequency offset to be added to the DDS frequency setting. As currently programmed, the offset is 1600 kHz. Unlike option input Y which is only checked at startup, this input is monitored continuously. When this input is connected to ground, the offset is disabled. When connected to +Vcc, the offset is enabled. Since the rotary switches can select any frequency from 0 to 1590 kHz in 10 kHz steps, this offset feature doubles the frequency range, giving continuous coverage from 0 to 3190 kHz in 10 kHz steps. The offset value is stored in EERAM memory, and I may add a method in the future to allow the user to change the value. For example, it might be handy to have the offset value set to the receive IF frequency for a transceiver application. For now, the value can only be changed in the source code file, and the project reassembled.
A zip archive of the source code and hex file for the program is available for download here:
Note: There was a bug in an earlier version of the firmware that prevented it from working correctly with AD9850 DDS chips. It worked correctly with AD9851's. This current version works correctly with both AD9850 and AD9851. If you are unable to get an AD9850 up and running, you may have an older version of the firmware. Please download this current zip file.