Generating Sine Waves With 8051Fx's PWM Generator
Introduction
The 8051Fx family's Programmable Counter Array (PCA) includes
provisions for generating Pulse Width Modulator (PWM) outputs. With
suitable filtering, these PWM outputs can generate an analog voltage.
For a constant voltage, you can just set and forget. It is also
possible to generate a varying waveform by changing the PWM value with
each pulse.
This article details the hardware and software needed to generate sine
waves and even more complex waveforms with the PWM outputs. The sine
waves can be of any arbitrary frequency, and several sine waves of
different frequencies can be generated together. Several example
files are available in a zipped file,
SINGEN51.exe.
Some of the possible uses for this technique include annunciator or
alarm tone generation, DTMF tone generation for phone equipment, music
in three-part harmony, multi-phase motor drive, quadrature sine waves
for signal processing, or precision sine-wave generation.
Software
This technique is based on a frequency synthesis technique known as
Direct Digital Synthesis (DDS). In DDS, a counter is used to step
through a Sine look-up table, which is then fed into a DAC. However,
the counter can count by any arbitrary increment, including
fractional, and is called a phase accumulator.
In our program, the phase accumulator is a 16-bit variable called
PHASE_ACC. On each interrupt, it has the value in PHASE_INC added to
it, and the upper byte of the result is used as an index into the
256-byte sine table. This value is then output to the PWM channel,
which is updated on the next full cycle. The value can be optionally
multiplied by a gain factor for amplitude control, for instance to
achieve high-band pre-emphasis in a DTMF generator.
These variables can be regarded as having an integer portion and a
fractional portion thusly: iiiiiiii.ffffffff, where the integer
portion is in "degrees" of 1/256 of a cycle. This integer portion is
used to index into the sine table.
The sine table was generated by the program SINTAB.BAS which produced
the file SINTAB.A51, which was then merged into the source file.
Generating the periodic interrupt is a bit tricky, since the PCA
resources used for PWM generation conflict with those used for the
interrupt logic. Fortunately, another PCA channel can be used to
generate the interrupt. This is done by setting the other channel (we
used # 3) to compare mode to interrupt on count nn00, where nn is the
value in CCAP3H and is incremented on each interrupt. This causes the
next interrupt to occur 256 cycles later.
Hardware
To yield a sine wave, the PWM's pulse output must be lowpass filtered.
A simple R-C filter is generally not adequate for audio applications,
due to its gradual roll-off, so an active filter of order 4 or higher
is recommended. Figure 1 shows one possible second order filter
circuit. Two of these, cascaded, generally give adequate performance.
Another possible filter would be a monolithic switched-cap filter such
as one of the Maxim MAX290 family of 8th-order lowpass filters, or the
Intel 2912A switched-cap CODEC filter.
Generating sine waves of greater than about 1/4 of the sample
frequency is not practical, since large low-frequency modulation
components result, which are very difficult to filter out. Therefore
the corner frequency of the filter is set at 1/4 to 1/5 of the sample
frequency.
Due to the quasi-bidirectional nature of the PWM output port pins,
either the filter should have a high input impedance, or the PWM
output should be buffered first.
The DTMF program assumes a certain hardware configuration for the
keypad or pushbutton switches, and would have to be changed to fit the
actual hardware used.
This technique doesn't require an 80C51Fx with PWM, by the way. An
8-bit DAC added to any MCS® 51 microcontroller family part could be
used with the interrupt being provided by one of the timers, with very
little change in the code.
Specifications
The highest PWM frequency is Fxtal/1024, by setting PCA clock source
at Fxtal/4, so, for a 16-MHz crystal, the PWM frequency can be as high
as 15625 Hz. This can generate sines up to about 3 KHz, which is
adequate for telephony or other audio applications. For generating
low frequency sines, the PCA clock source can be Fxtal/12 or timer 2
overflow. These lower frequencies also reduce processor overhead in
the interrupt routine.
With a 16-MHz crystal, an interrupt occurs every 64 uS. The interrupt
routine takes 26.5 uS to calculate a single value, for about 41%
processor utilization. Much of this time is spent in normal interrupt
overhead, and it is possible to calculate up to four sine waves on
each interrupt. Higher crystal frequencies can generate higher sine
frequencies, but the percentage of processor time remains constant.
It is also possible to generate up to 3 sine waves on one channel,
with amplitude control for each one.
Some performance results are as follows:
Total Microseconds Per Interrupt = 64 uS at 16.000 MHz
Time spent in interrupt
PWM |
simplest single sine generator |
42.3% of total |
DTMF |
two tones without amplitude control |
53.7% |
DTMF |
with amplitude control for each tone |
74.3% |
3PART |
with amplitude control for each voice,
all on one channel |
89.2% |
4WAVE |
each on a separate channel, fixed amplitude. |
70.9% |
Examples
Several example files are included in the zipped file, SINGEN51.exe,
which is available in the MCS® 51/Tools category on the World Wide Web. These are:
PWM.A51 |
Single Sine wave generator. |
DTMF.A51 |
Two tone generator. |
3PART.A51 |
Three tones, with amplitude control. |
4WAVE.A51 |
Four sine waves, each on a different channel. |
SINTAB.BAS |
Program to generate full amplitude table. |
SINTAB2.BAS |
Program to generate half amplitude table. |
SINTAB3.BAS |
Program to generate 1/3 amplitude table. |
The following is a code fragment from PWM.A51 which demonstrates the
technique of generating a single sine wave.
U1 is an LM6482 or similar CMOS op-amp with rail-to-rail input and
output range on a single +5V power supply. This will allow a sine
wave output of 0.0 to 5.0V. For different corner frequencies, scale
the resistors and/or capacitors accordingly.
References
Intel Embedded Microcontroller Handbook, order number: 270645
|