September
2004, Issue 170
Multilab
Build
a Z8 Encore!-Based Multipurpose Test Instrument
DESIGNING
THE ARB
A
block diagram for a basic arbitrary function generator
is shown in Figure 3. The address counter accesses the
waveform memory sequentially, and the data in the waveform
memory array is fed to an 8-bit DAC. The DAC0801LCN
is a current-mode DAC. An op-amp converts this into
the required output voltage waveform.
|

(Click
here to enlarge)
|
Figure
3—As you study the different sections of the arbitrary
function generator, keep in mind that the green
blocks are handled by the Z8 Encore!. |
To
generate a waveform of a desired frequency, the address
counter must be incremented at this frequency multiplied
by the depth of the waveform memory array. The depth
of the array represents the number of data points used
to make up one complete cycle of the output waveform.
So, the greater the depth, the more accurately one can
simulate a particular waveform. For simple waveforms
such as square waves and triangle waves, this isn’t
too critical. But, it’s obvious that to generate complex
waveforms, the depth of the memory array must be commensurate
with the complexity of the waveform.
To
achieve adequate frequency resolution, the clock, which
increments the address counter, must be tuneable in
reasonably fine steps. So, for example, achieving a
1-Hz output waveform resolution with a waveform depth
of 256 data points requires the clock be tuneable in
256-Hz amounts.
There
are basically two ways to approach this. You can start
with an extremely high-frequency quartz crystal oscillator
(50 to 100 MHz) and use a variable modulus divider chip
to produce a clock signal in the desired range. This
approach can yield a reasonable resolution, but the
resolution will vary throughout any given range. A better
approach is to use a PLL (i.e., a VCO that’s phase-locked
to a reference signal). The reference frequency is set
equal to the desired frequency resolution multiplied
by the waveform memory array depth. The VCO can be fine-tuned
over an octave (or greater) frequency range, and Timer2
in the Z8 Encore! can divide this down to the correct
frequency needed to clock the waveform memory at the
correct rate.
I
chose the latter option (see Figure 3). My goal was
to use the Z8 Encore! for as much of the circuit as
possible. All I really needed to add externally were
a CMOS 74HC4046 VCO/phase detector chip and the DAC/output
buffer. To generate a reference signal for the PLL,
I could’ve used Timer1 in the Z8 Encore!. However, I
allocated Timer1 to handle the timing for the DC voltmeter
function to this project. Therefore, I used an MC14060
CMOS oscillator/divider chip and a 32,768-Hz watch crystal
to provide the 512-Hz reference for the PLL.
The
DMA function in the device is essential to make the
Z8 Encore! function as an arb. The Z8 Encore! contains
three DMA channels, one of which is dedicated to the
ADC. The other two channels can be independently programmed
to transfer data in or out of the Z8 Encore! RAM to
any Z8 Encore! port that you select.
I
connected the DAC to port B, so that is the destination
register that I programmed into DMA0. Any of the Z8
Encore!’s timer outputs can be used to trigger this
data transfer at the desired rate. As you can see in
Figure 3, the VCO output is fed into the Z8 Encore!’s
Timer2, which acts as a programmable divider, and triggers
DMA0 at the desired rate.
The
DMA controllers contain registers for RAM start and
end addresses, so it is easy to program in the desired
waveform depth by setting the RAM ending location accordingly.
The Z8 Encore! contains 4 KB of RAM, which is more than
enough to handle the waveform depths that I need.
The
DMA controller can operate in Single Block or Repetitive
mode. At this stage, my design is set up to produce
repetitive waveforms, but changing this mode bit, and
using an external trigger to initiate the generation
of a one-shot wave output, can change this.
When
the Z8 Encore!’s timers are clocked from an external
source, as is the case with Timer2, the maximum clock
rate is the system clock divided by four. I run the
Z8 Encore! at 16 MHz, which is convenient for the pulse
generator function, so the maximum VCO frequency shouldn’t
exceed 4 MHz. I chose the VCO’s RC tuning components
to produce frequencies in the 1- to 3-MHz range, which
is safely under the 4-MHz limit. Timer2 divides the
VCO frequency by N, so its output frequency range can
go up to 1.5 MHz.
The
Z8 Encore! datasheet does not specify how fast the DMA
channels can operate. Because the DMA controller must
steal the bus from the MCU to do the transfers, this
timing will vary somewhat depending on which instructions
the MCU is performing. With my code, I found that the
DMA controller could be counted on to transfer data
up to about a 2-MHz rate, so the 1.5-MHz maximum frequency
output of Timer2 is OK.
To
phase-lock the VCO at the necessary frequency in the
1- to 3-MHz range, its output must be divided down to
the PLL’s 512-Hz reference frequency (provided by the
MC14060 oscillator/divider chip). The Z8 Encore!’s Timer0
performs this task. I chose 512 Hz because it provides
adequate output frequency resolution and isn’t so low
as to be slow phase locking.
Table
1 shows the waveform depth and resolution for the
various frequency ranges. The higher frequencies must
use a smaller waveform depth because the maximum waveform
memory clock rate is about 1.5 MHz, as outlined previously.
With a fixed 512-Hz PLL reference frequency, as the
waveform depth becomes smaller, the resolution also
decreases but it is still reasonable.
The
arb generator works in two modes. For common waveforms—such
as sine, triangle, sawtooth, and square—the Z8 firmware
calculates the waveforms, using the C library’s floating
point routines, and loads them into RAM as needed. For
any other waveform (i.e., arbitrary), the RAM is loaded
with values that have been previously saved in a 24LC256
I2C flash memory chip.
For
simplicity, I broke the 32-KB flash memory space into
1-KB segments, allowing one to store up to 32 arbitrary
waveforms with a depth of 1,024 (or less). Generating
and downloading these waveforms are the only functions
performed without the Palm Pilot. Rather, they’re accomplished
using a PC application, which also can act as the device’s
front panel in lieu of the Palm Pilot.
There
is nothing written in stone that says the output of
the arb waveform memory must be limited to setting a
DAC and thus producing an analog waveform. I added an
eight-pin header to the board wired up to the eight
data input lines of the DAC. By loading an arb waveform
with the proper digital values, it’s possible to tap
into these lines and get up to eight synchronized digital
signals (of a repetitive nature). Along with the various
analog waveforms like sine and triangle, the firmware
also generates several stepper motor phase sequences
that can be selected.
I
was tempted to use the Z8 Encore! development board,
with its on-board Z8F6403, for this project. This Z8
device, which contains four timers, would have eliminated
the MC14060 circuitry that I used for the PLL reference
clock. It would have also provided more versatility.
However, I decided to save the development board for
future development work and instead use one of the Z8F6401
(40-pin DIP) chips included in the kit.