Signal Generator (VFO) with Direct Digital Synthesis Version 3a April 21, 1999 This sig_gen code is a continuation of a project started by Curtis Preuss, WB2V, and described in his QEX article in July, 1997. Subsequently, Curt modified the code to add the calibrate and band select functions. This summary provides hints and information about how to extend the original project to the current version. -------------------------------------------------------------------------------- 1) Versions of Sig_Gen You need to choose between three major versions of code. Version 1 is Curt's original and dds_vfo. It works if with some LCDs, but not with some of the "cheapie" LCDs. Version 2 of dds_vfo was done by George Heron, N2APB. It has some timing improvements that make it work with the "cheapie" LCDs also. See dds_vfo2.txt on the Ham-Pic Web page for SPASM source code, dds_vfo4.txt for MPASM source code, and dds_vfo2.hex for the code to load into the PIC chip.) (Versions 1 and 2 work "as is", without any circuit board modifications.) Version 3 is an enhancement by Curt, WB2V. It is now called sig_gen. It has some significant new features, including calibrate mode and band selection. This version needs a circuit board modification. (See section 2 below.) Curt's SPASM version is available on the Ham-Pic Web page. Bruce, AA0ED, has an MPASM translation available as sig_gen2.asm.txt, sig_gen2.lst.txt, and sig_gen2.hex.txt. Version 3a is this version of sig_gen. The functionality remains the same as Version 3, but Bruce and I have added many fixes and modifications. FIXES: 1) Fix a bug which caused the frequency to jump to the maximum when going towards zero. 2) Fix several SMASM to MPASM translation bugs. - Code worked, but several cases of "hard coded" constants remained that should have been changed to labels to allow data tables to be moved and/or modified. This bug could cause a reference to a wrong variable. - PortB vs TRISB causing confusion. MODIFICATIONS/ADDITIONS: 1) The lower frequency is changed from 1Khz to zero. 2) Added band table entries of 0 Hz and 30 MHz. 3) Changed wait routine names for clarity. 4) Added comments throughout. 5) Subroutine headers added. - Inputs and Outputs specified 6) Changed some data labels for clarity. 7) Changed some routines for efficiency. - Improve path length and save memory NOTE: OUR GOAL was to make this code clear and easy to understand so that it can be used as a springboard for additional changes. By documenting subroutines as clearly as possible, we hope readers will be able to easily use the subroutines in other projects. =============================================================================== 2) Circuit Boards from Far Circuits Make sure you have the corrected version of the FAR Circuits' board. Far Circuits had an early version that had some errors in it; it had several missing traces. The easiest visual way to distinguish the two versions of the boards is to see if it has a diagonal trace in the lower left hand corner between the 10K pot and the mounting hole. If it has a diagonal trace, it is the new version. If it does not, then it is the older version and you have to make several wiring changes, including a couple in the area of the AD9850. I advise you to get the new version. Note that this new board is still for Version 1 and 2 of the PIC code. FAR Circuits does not have a board with the modifications for Version 3 code, as far as I know. You need to make a modification to the FAR Circuits' board to make it work with Version 3 or 3a code. This enhanced PIC code requires a hardware change to allow for the push button which is used to select the calibrate mode and to do band selection. The change removes the +5 volt connection to pin 2 of the PIC chip, and connects a 10K ohm pull-up resistor to pin 2. The push button is connected between pin 2 and ground, so that the pin is grounded when the button is pressed and held high when the button is released. In addition, instead of using the output of Pin 2 to power the LCD and control the LCD contrast, the LCD is connected directly to +5 volts. The change can be done as follows: 1. Locate the PC trace which connects pin 2 of the PIC chip to the LCD contrast control pot. This was originally used to power the LCD by setting bit 3 of Port A (pin 2) high. Drill a small hole (#60 - .040") through this trace as near as possible (1/16") to pin 2 of the PIC socket. 2. Near pin 2 of the PIC socket, cut the trace about 1/8" beyond the new hole. Using a 1/4" drill, remove the foil around the hole on the ground plane side of the board to avoid shorting pin 2 to ground when the resistor gets inserted in the hole (Step 4). 3. Locate the +5 volt trace that passes between pin 1 and pin 2 of the PIC socket. Drill a new hole through this trace in the place where it is close to pin 1. Remove the ground side foil from around this hole with a 1/4" drill to avoid shorting +5 v to ground when the resistor lead is inserted. 4. Install a 10K resistor in the new PC board holes. Mount it vertically, with the short resistor lead in the +5 v trace hole and the other end bent close to the resistor body and down into the hole near pin 2 of the PIC socket. Make the solder connection to the traces only, not to ground plane foil on the other side of the board. Make sure both sides of the +5 v trace are soldered to the resistor lead. 5. Connect a wire from one side of the push button to the pin 2 side of the new 10K resistor. This can be done by connecting the wire to the top of the vertically mounted resistor. Connect another wire from the other side of the push button to ground. 6. Using a bit of solid wire, connect the pin of the LCD contrast pot that used to be connected to pin 2 of the PIC socket to the +5 volt trace. This now supplies power to the LCD. =============================================================================== 3) Circuit Board Construction hints On this board you will notice that all components are mounted on the trace side of the board. The bottom side is a ground plane. You need to mount the PIC socket up off the board, so you can get your soldering iron underneath to solder each pin to its pad. Take your time. I would suggest mounting the chip socket first, so you have easy access to all the pins. If you are going to use headers for attaching the rotary encoder and/or LCD, this is also rather tricky. (I used headers for the encoder because it is an expensive part, but I wired a ribbon cable directly to my "cheapie" LCD.) I would suggest you build the "left side" of the board first, and get it going before you add the "right side" components (clock oscillator, AD9850, and filter). You will be able to see the LCD display work in response to turning the rotary encoder and push button(s). Make sure you put all the ground jumpers in. Some components need to be soldered on both sides of the board. In addition, there are several holes that need jumpers soldered on both sides. =============================================================================== 4) Clock Oscillators You can get clock oscillators from a variety of sources, but the higher speed ones (above 80 MHz) are a little more difficult to find. I got my 100 MHz oscillator from Jameco for $2.75 . Jameco's phone number is 1-800-831-4242 and their Website is http://www.jameco.com . There is one more thing that you need to be very careful of. With the faster oscillators, you have to make sure that pin 1 is NOT GROUNDED. You can either cut the trace on the board and grind off the ground plane connection on the back of the board, or else just clip pin 1 of the oscillator and let it hang by the 3 pins. In the Jameco catalog they mention that Pin 1 should not be connected. (Apparently some of the slower oscillators can/must be grounded, but the faster ones cannot.) When they are grounded the output voltage is dropped to a very low value. =============================================================================== 5) Setting Clock Oscillator values The current code has is set up to work with a 100 MHz clock oscillator. It is very easy to change it to use other clock values. Here is the table (also in the code symbolics) which you can refer to, or you can do your own calculations. The clock variables are set in variables ref_osc_3, ref_osc_2, ref_osc_1, and ref_osc_0. ref_osc represents the change in the frequency control word which results in a 1 Hz change in output frequency. It is interpreted as a fixed point integer in the format . The values for common oscillator frequencies are as follows: Frequency ref_osc_3 ref_osc_2 ref_osc_1 ref_osc_0 120.00 MHz 0x23 0xCA 0x98 0xCE 100.00 MHz 0x2A 0xF3 0x1D 0xC4 90.70 MHz 0x2F 0x5A 0x82 0x7A 66.66 MHz 0x40 0x6E 0x52 0xE7 66.00 MHz 0x41 0x13 0x44 0x5F 50.00 MHz 0x55 0xE6 0x3B 0x88 To calculate other values: ref_osc_3 = (2^32 / oscillator_freq_in_Hertz). ref_osc_2, ref_osc_1, and ref_osc_0 are the fractional part of (2^32 / oscillator_freq_in_Hertz) times 2^24. Note: 2^32 = 4294967296 and 2^24 = 16777216 For example, for a 120 MHz clock: ref_osc_3 is (2^32 / 120 x 10^6) = 35.791394133 truncated to 35 (0x23) ref_osc_2 is the high byte of (.791394133 x 2^24) = 13277390.32 13277390.32 = 0xCA98CE, so high byte is CA. ref_osc_1 is the next byte of 0xCA98CE, or 98 ref_osc_0 is the last byte of 0xCA98CE, or CE Then set the variables as follows for a 120 MHz clock: ref_osc_3 equ 0x23 ; Most significant osc byte ref_osc_2 equ 0xCA ; Next byte ref_osc_1 equ 0x98 ; Next byte ref_osc_0 equ 0xCE ; Least significant byte =============================================================================== 6) Upper Frequency Limit The original sig_gen code has an upper limit of 20 MHz. To allow operation all the way up through the 10 meter amateur band, we made some modifications to change the limit to 30 MHz. This requires a clock oscillator of at least 90 MHz and a redesign of the output low pass filter. Here are the values that I calculated for the 30 MHz filter. Part numbers are for DigiKey (1-800-DIGI-KEY or www.digikey.com ). C1 original: 180pf new: 100pf (PCC101CGCT-ND) C2 original: 150pf new: 100pf (PCC101CGCT-ND) C3 original: 10pf new: 10pf (PCC100CNCT-ND) C4 original: 33pf new: 33pf (PCC330CGCT-ND) C5 original: 270pf new: 150pf (PCC151CGCT-ND) L1 original: .47uh new: .39uh (DN10391CT-ND) L2 original: .39uh new: .33uh (DN10331CT-ND) =============================================================================== 7) Calibrate CALIBRATE MODE is entered if the external push button is pressed during power on. The display is set to "10,000.000 CAL" and remains fixed, even as adjustments are being made. If the push button is held pressed, then turning the shaft encoder will increase or decrease the value "osc" used to calculate the DDS control word. The basic calibrate adjustment rate is very low (on the order of a few cycles per turn of the encoder). A somewhat faster adjustment speed is available by pressing the encoder shaft down while turning. An external frequency counter on the DDS output is required to observe this adjustment. To exit calibrate mode, release the external push button and turn the shaft encoder one more time. The calibrated value of "osc" will then be stored in EEPROM memory. =============================================================================== 8) Start-up Frequency The current code is set up to start at 14.025 MHz. If you want to set it to start at another frequency, you can do it as follows. The variables default_3, default_2, default_1, and default_0 contain the default startup frequency as a 32 bit integer. It has the form of . Thus 14.025 MHz would be represented as decimal 14025000 and converted to hex value of 00D60128 . Thus, change the default variables in the symbolics as follows: default_3 equ 0x00 ; Most significant byte for 14.025 MHz default_2 equ 0xD6 ; Next byte default_1 equ 0x01 ; Next byte default_0 equ 0x28 ; Least significant byte =============================================================================== 9) Parallax SPASM vs Microchip MPASM assembler code The differences between Parallax SPASM and Microchip MPASM are quite extensive. The Parallax SPASM has some advantages, and in some ways may be easier to understand. In fact, many SPASM instructions are actually composites of several MPASM instructions. I.e. SPASM instructions may translate into 2 to 4 MPASM instructions. Therefore the Parallax code actually has fewer assembler instructions. Of course, the end result is the same number of machine instructions. We wanted to use MPASM for a variety of reasons. First, there is a lot of MPASM code available to look at. Microchip is the company that designs and manufactures the PIC microprocessors. Microchip has a free CD (available from their Web site) which bundles their assembler and a very good simulator along with an abundance of source code that is ready to use in projects. Another reason why we wanted to use MPASM code is because we have been reading the Easy PIC'n books by Dave Benson, available from Square One. These books are excellent, and give the reader a good working knowledge of PIC processors. These books use MPASM assembler symbolics. If you have any questions, we will be glad to help in any way we can. Good luck, and have fun! 73, - Craig, AA0ZZ ( AAØZZ@ARRL.NET ) - Bruce, AA0ED ( sbs1@visi.com )