Advanced Search

Click Here for
Advertising Info


Privacy Statement


EE Design Center

Link to Circuit Cellar


Digital Frequency Synthesis

by Tom Napier

Some of the best inventions happen by accident. At least, that’s how it is with Tom’s project. While merely intending to beef up his NCO generator, Tom found a way to embed a low-cost, accurate tunable sine-wave generator, using just a PIC.

Sometimes topics for articles crop up by happenstance. I was designing a minimum shift keyed (MSK) transmitter to drive a 25-kHz ultrasonic transducer, and for simplicity, I wanted to use a small PIC chip as the transmitting modem.

I figured out several ways to generate the two output frequencies but one method seemed simpler and more general than the others. The frequencies were set by two constants and there seemed to be little limit to what values could be used.

"Ah!" I said to myself, "This design would work for any frequency shift keying system, not just MSK." That’s when I realized that I’d just reinvented the numerically controlled oscillator (NCO).

Someone who read my two-part article about building an NCO generator ("Making Waves with an NCO," INK 89 and 90) asked if the PIC could emulate an NCO.

Well, the short answer is yes, providing you don’t want to generate too high a frequency. I didn’t give the matter any thought until I discovered that I had just created a design that was happily generating 25 kHz using a 6.144-MHz crystal.

I thought, if I give the PIC a higher crystal frequency—say, 20 MHz—and can get it to output an 8-bit sample every 20 instructions, it will behave like an NCO with a 250-kHz clock crystal. That should be good for an output frequency of getting on for 100 kHz, which is better than most audio generators can do.

I followed up this idea and ended up with not so much a construction project, but more a method of embedding a low-cost but accurate, tunable sine-wave generator into almost any product. This design doesn’t need a fancy NCO chip or a high-speed DAC. It uses an 18-pin PIC16C54 chip to drive a cheap, low-speed 8-bit DAC.

In a pinch, you could wire up a bunch of 1% resistors as an R-2R ladder and do without the DAC. The only other things you need are a low-pass filter and an output amplifier.



Let’s recap some theory. The idea behind the NCO is this: Select a number proportional to your desired output frequency, and then add this number to an accumulator at regular intervals.

The number in the accumulator represents the phase of the output cycle. If you take its more significant bits, do a sine conversion and feed them to a DAC, you get one sine wave each time the accumulator wraps around.

The output frequency is a linear function of the number you are adding. The frequency precision is as good as that of the crystal driving the addition, while the frequency resolution can be made as fine as you wish by using a long enough accumulator.

The output from the DAC consists of steps that occur at a fixed rate. If you select a small frequency control number, you get a low-frequency output made up of many small steps and it will look quite smooth. As you select larger numbers, the output frequency rises, the number of steps per output cycle falls, and the output begins to look jagged.

Appearances are misleading. The sine wave is still there, but it’s being distorted by the higher frequency aliases arising from the sampling process. With a good enough output filter, you get a clean sine wave at the specified frequency.

Nyquist’s Theorem says that, provided you don’t use fewer than two samples per cycle, a low-pass filter can take out the unwanted frequencies and leave a pure sine wave. Well, Nyquist was an optimist.

Two cycles is the theoretical minimum, and this assumes that you can build a brick-wall filter at half the sampling frequency. Three samples per cycle is a more realistic number.

In any case, Nyquist’s samples were infinitely narrow impulses, while the output of the DAC is a step waveform. Therefore, the output amplitude rolls off as the output frequency rises (see INK 89, p. 74, Figure 4).

The output frequency is equal to the step frequency multiplied by the number you set and then divided by the number of counts it takes to rollover the accumulator. For example, if you have a 16-bit accumulator, it takes 65,536 counts to roll it over.

If you add any number 65,536 times a second, each unit you add represents 1 Hz. To get a 10 kHz output, add 10,000 at each step. Each output cycle would have just over 6.5 steps in it.



Real NCOs have accumulators with 24, 32, or 48 bits and make an output step every 15 ns or so. It takes a fast and expensive DAC to keep up, but you can get output frequencies up to about 30 MHz.

If a ’16C54 really hustles, it can handle a 16-bit sum and a sine lookup in 19 instruction times. With a 20-MHz crystal, the step rate is limited to 263 kHz. Pretty shabby by NCO standards, but it means you can generate accurate frequencies up to about 90 kHz.

There are two ways to approach the frequency-setting problem. One is to choose the accumulator length and the update frequency such that the proportionality factor between the wanted frequency and the frequency setting number is a small integer. That way, all the frequencies you set come out exactly right.

In my MSK modem design, this factor was 300 Hz per unit. For lab use, 1 Hz per unit would be handy, since reading and processing the user’s input would only require a BCD-to-binary conversion.

Or, you can use such a long accumulator that any frequency can be set with reasonable accuracy regardless of the update rate. That buys you some design flexibility at the price of more input processing and an output frequency which is rarely, if ever, exactly right.

In both cases the proportionality factor, F, is equal to the update rate divided by the length of the accumulator. If the PIC is driven by a crystal of C Hz and the loop requires L instructions, the effective update rate is:

e057exa1.gif (1775 bytes)

The accumulator length, A, is a power of two, such as 65,536.



The maximum output frequency is limited by two things. One is the sheer processing speed of the chip. The highest frequency can’t be higher than about a third of the number of times the loop is executed in 1 s. This fact limits a ’16C54 to about a 90-kHz output.

The other limit is a function of the accumulator length and the resolution you want. The largest frequency control number that a 16-bit accumulator can support is about a third of 65,536.

Thus, if you want 1-Hz resolution, you can’t go higher than a 22-kHz output. With 2-Hz resolution, you could reach 44 kHz and so on.

In a fit of bravado, I tested a circuit that could generate up to 100 kHz in steps of 4 Hz. It worked, but it needs a pretty good filter to pass 100 kHz but stop the alias at 163 kHz.

I doubt if the program loop for a 16-bit accumulator can be shorter than 19 instruction cycles. Even that takes PIC trickery (see sidebar, "A PIC Trick"). The loop will be longer if you want phase or frequency modulation.

The crystal frequency can’t be higher than 20 MHz. Since C = 4ALF and A is a largish power of two, the crystal frequency has to be divisible by a power of two if the control factor is to be an integer. Ideally, it would be a stock value, but in a production environment, any oddball crystal frequency will work.

The other approach uses a 24-bit or higher accumulator. This technique obviously requires more instructions per loop, because in a three-byte addition you have to allow for the once-in-a-blue-moon occasion when adding the low bytes propagates a carry into both the middle byte and the high byte.

The update rate is going to be at most about 190 kHz, so you won’t be able to generate much over 60 kHz. On the other hand, the resolution will be better than 0.01 Hz, so any frequency you please can be set to that accuracy.

I stumbled on a good compromise: use a 20-MHz clock crystal and make the loop 31 instruction times long. If you multiply the wanted frequency by 104, you get a number that sets the output to within 180 ppm, which may be better than the error in the crystal frequency. Since the basic three-byte addition and table look-up takes 26 instruction times, you have five spare instructions to modulate the output if you want to.

You may be able to use a much shorter accumulator. If, as I did in my MSK modem, you want a limited number of frequencies that are closely related, you can use an 8-bit accumulator. This setup allows any frequency of the form:

e057exa2.gif (2028 bytes)

On the other hand, if you want to set a low frequency with very high resolution, you can make the accumulator 32 or 48 bits long.



Apart from initialization and the user input routine, the code consists of the sample loop and a sine look-up table. The table contains 65 entries and specifies one quadrant of a sine wave. If the two highest bits of the phase are both zero, the table is used directly. If the most significant bit is a one, the table output is inverted.

When the next to most significant phase bit is a one, the table index is subtracted from 64 to reverse the table end to end. That’s why the table has 65 entries, not 64. There needs to be an entry for the case where the index is zero and, when reversed, it becomes 64.

The DAC input is in offset binary—that is, 1 is negative full scale, 128 is zero, and 255 is positive full scale. The table entries are seven-bit numbers from 128 to 255, so the result of subtracting them from a register containing zero is the negation of the table entry. Two PIC registers are preloaded with constants since the 16C54 has no immediate subtraction instruction.

My 19-instruction-time loop using a 16-bit accumulator appears in Listing 1. It tests a bit of Port A, enabling the user to tell the PIC that it’s time to load a new frequency.

The output voltage stays fixed during this, but in many cases the effect isn’t noticeable. Reading a five-digit BCD frequency and converting it into binary takes only microseconds.

Listing 2 shows the more practical 31-instruction loop using a 24-bit accumulator. Listing 3 shows one method of incorporating biphase modulation via a bit of Port A. In all three listings, only the main loop is shown.



The hardware consists of the PIC, an 8-bit DAC, a low-pass filter, an output amplifier, and some method of loading the desired frequency into the PIC. Figure 1 shows a typical system.

Some applications won’t need all of it. My ultrasonic modem used a port bit to select one of two preset frequencies. It didn’t need the low-pass filter since the frequencies being generated were both within the pass-band of the transducer and the alias frequencies were well outside it.

If you only want audio frequencies, the filter needs to be little more than a capacitor across the DAC’s output resistors out to get a clean output. In the 50-kHz range, you need a filter that cuts off sharply above 50 kHz.

Figure 1 shows a four-pole quasi-Butterworth filter with a cutoff at 70 kHz. This filter approximates a Butterworth filter by combining a single-pole filter (the capacitor across the DAC output) with a three-pole Sallen and Key–style filter.

The two sections need to be isolated from each other, either by buffering the DAC output or, as shown, by making the resistors in the three-pole section about ten times larger than the DAC load resistor. The output amplifier doesn’t need to be anything fancy because it only has to provide unity gain up to perhaps 500 kHz.

To set the frequency, I wired a five-digit thumbwheel switch to three 8-bit shift register chips as shown in Figure 2. The switches are ignored until the user presses the update button. Feedback from the output stage of the shift register debounces the button.

One bit from the PIC port keeps the shift register in Load mode. When the update button is pressed, the PIC puts the shift register into its Shift state. The bit that was sampling the button then becomes the serial data input pin.

A third port pin supplies the clock to the shift registers to read all five switches. (The fourth pin of the 4-bit Port A provides a modulation input.)

Since the highest BCD digit takes values from 0 to 5, only 19 bits are read in. Three 19-byte look-up tables store the three-byte weight of each bit.

When a one bit appears at the input, the corresponding three-byte weight is looked up and added to the frequency register. If you embed this "NCO" in a larger system, you may be able to arrange this computation to be done elsewhere.

If you build this configuration, it is worth setting the frequency to 40,330 Hz, which gives a frequency setting number that’s close to a power of two so the DAC output is almost stationary. Compare the filtered output to the raw output on pin 2 of the DAC to see how good a job the filter is doing.

The DAC-08 is a former PMI part now made by Analog Devices. The DAC0800 from National Semiconductor is a direct replacement.

The DAC’s outputs sink current to the negative supply. The currents vary in opposite directions as the input code changes. Both have full-scale values equal to the reference current (nominally 2 mA). If the reference current flowing into pin 14 changes, the output amplitude and its DC level change, too. This circuit’s output is about 1.5 Vp-p.

The DAC-08 does need a negative supply—ideally, –15 V. If you can accept a limited output swing, –5 V will work.



The spare instructions in the 31-cycle loop let you add input tests to select either of two preset frequencies and generate FSK signals. The upper two bits of the accumulator determine which quadrant of the waveform is used, so you can generate quadratic phase modulation by modifying these bits.

A 28-pin PIC would give you an extra 8-bit port. The number applied to it could be added to the phase register or to the frequency register to generate virtually continuous phase or frequency modulation.

The DAC output is proportional to its reference current. Modulating this current produces amplitude modulation of the output.

These techniques are a convenient way of generating low-frequency communication signals, and they can also be applied in the musical field.



My earlier article described how a PIC, a specialized NCO chip, and a fast DAC could generate up to 10 MHz in a benchtop unit. But if you need lower frequencies, this article may give you food for thought. With a parts cost under $10, a PIC and a DAC may be just the answer when you need a high-precision adjustable-frequency sine wave below 50 kHz.

Tom Napier has worked as a rocket scientist, health physicist, and engineering manager. He has spent the last nine years developing spacecraft communications equipment but is now a consultant and writer. In his free time, he develops neat test instruments, debunks pseudoscience, and writes in Forth on an Amiga 3000.


Microchip Technology, Inc.
(602) 786-7200
Fax: (602) 786-7277

Analog Devices
(617) 329-4700
Fax: (617) 329-1241

National Semiconductor
(408) 721-5000
Fax: (408) 739-9803

Circuit Cellar INK provides up to date information for engineers, for more information and additional articles.
©Circuit Cellar INK, the Computer Applications Journal. Posted with permission. For subscription information, call (860) 875-2199 or


Embedded Systems Home | Back to Applications menu

Sponsor Links

All material on this site Copyright © 2001 CMP Media Inc. All rights reserved.
EDTN Home Register for EDTN Privacy Statement Feedback e-cyclopedia