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:
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
Legal Stuff © 1997 Intel Corporation