Summary: This module introduces Direct Digital Synthesis with prepared code that transmits arbitrary input as an FM radio signal. The module then explains how to program the DDS hardware and concludes with a simple Frequency Shift Keying exercise.
![]() Figure 1: Direct digital synthesis (DDS) (Couch) |
FM.asm (downloadable here) and mod.asm from the
v:\ece320\54x\dds\ directory. Assemble and run
the frequency modulation (FM) program FM.asm.
Next, plug an audio source into one of the two DSP input
channels that you've been using all semester. If you have a
CD on you, pop it into the computer and use that. If not, use
a music web site on the Internet as your audio source.
Connect the computer to the DSP by using a male-male audio
cable and an audio-to-BNC converter box (little blue box),
both of which are in the lab. The computer has three audio
outputs on the back; use the middle jack. Ask your TA if you
can't find the cable and/or box or don't see how to make the
connection. Next, connect a dipole antenna to the output of
the DDS (port \#1 on the back of the DDS board). A crude but
effective dipole antenna can be formed by connecting together
a few BNC and banana cables in the shape of a T.
There should be one or two of these concoctions in the
lab. Once the connections are made, turn on the black receiver
in the lab, and tune it to 104.9 MHz (wide band FM). You
should be able to hear your audio source! radioinit subroutine. This routine sets the
DDS to single-tone mode and turns off an inverse-sinc filter
to conserve power. Following radioinit, the
setcarrier subroutine is called. This routine
sets the frequency of the DDS output by writing to the two
most significant 8-bit frequency registers of the 48-bit
frequency-tuning word on the DDS1. Although the
frequency-tuning word on the DDS has 48 bits of resolution,
the upper 16 bits provide us with enough resolution for the
purposes of this lab, and so we will only be writing to the
two most significant registers. See page 26 in
the DDS data sheet for a layout of the frequency-tuning
word.
406D 3A06
D3D4h. But since we only write to the two most
significant registers of the frequency-tuning word, we only
need the first 4 hexadecimal numbers of this result,
i.e. 406Dh. The first two of those,
40h, need to get written to the most
significant 8-bit frequency register, while the second two
hex numbers, 6Dh, need to get written to the
second-most significant 8-bit frequency register. This is
where the 40h and 6Dh in the
setcarrier subroutine of the FM code come from.
portw instruction. To write to the frequency
or phase registers on the DDS, the second operand of the
portw instruction must be
10xxxxxx, where the lower six bits are the
address of the specific register to be written to. The
address of the most significant frequency register on the
DDS is 04h, and the address of the second most
significant frequency register on the DDS is
05h (see page 26 in the data
sheet). It is important to note that the way our DDS boards
were built, you will not be allowed to make two consecutive
writes. To solve this problem, a subroutine called
nullop is called to waste some CPU time between
writes. nullop does this by simply repeating
the nop instruction 128 times.
setcarrier
subroutine, it enters an infinite loop in which it waits for
a serial interrupt to occur. The serial interrupt occurs
every time a new sample is acquired from one of the two
input channels and is transmitted to the DSP via the serial
port. When the interrupt occurs, an interrupt service
routine called ANALOG_IFC (see
core_mod.asm executes and calls the
handle_sample subroutine. The
handle_sample subroutine reads in the acquired
sample from the serial port and scales that sample so that
it can be "mapped" to a frequency in the range of ±75
kHz2. The scaled sample therefore
determines the frequency deviation and is added to
6Dh. The last step is to write the result to
the second most significant frequency register so that the
frequency of the DDS output can be updated.
00h, and
the lower 8 bits have address 01h. The phase
word can be calculated using Equation 2:
portw instruction as before.
Just make sure you use the correct address for the phase
register.
nullop subroutine and calling it between writes
to the DDS. The second nullop subroutine should
waste approximately 725μs worth of time.