When you need an analog output from a microcontroller that does not have a digital-to-analog converter (DAC), you can connect an external DAC chip. But for a cheaper solution, use a pulse-width modulated (PWM) output and add a low-pass filter (LPF) to extract its average value, which equals the duty cycle of the PWM signal (Figure 1).
The RC filter removes the non-DC components; what remains is the average signal UOUT. If the period T of the PWM signal equals 63 clocks, the signal UOUT can have one of 64 discrete DC values (0 to 63, six-bit resolution).
The time constant t of the low-pass RC filter must be big enough to smooth the output signal UOUT. The ripple, ∆UOUT, should be less than one least significant bit (LSB). The worst case occurs with a duty cycle of 50% (Figure 2). If t is much bigger than the period T then the capacitor charging current IC and the change ∆UOUT can be approximated as:
For a 6-bit DAC, ∆UOUT should be less than VCC/64, requiring a filter of t = RC ≥ 16×T.
Some practical numbers: low-power microprocessors often use a crystal oscillator of 32768 Hz, and this clock signal is used for the PWM block. With 6-bit PWM, the period T is 64/32768 ≈ 2 ms, necessitating a time constant of 32 ms. One has to wait 5t (160 ms) for a 6-bit converter to settle. Slow. This Design Idea explains how you can speed things up.
PWM blocks in microcontrollers can usually generate more than one PWM signal. Consider summing outputs from two PWM based 3-bit DACs (DACH and DACL), where the output of DACL is reduced to one-eighth amplitude before adding. The resulting signal acts as a 6-bit DAC, with an important advantage over the simple version: the period T is only eight clock periods for the same resolution, and the required time constant t is 1/8 of the previous, speeding up settling time by factor of eight. Such an arrangement is easy to implement with resistors in the RC filter for two PWM signals (PWMH, PWML) (Figure 3).
The output signal UOUT is given by:
Listing 1. Code to initialize & write to a 6-bit (3+3) PWM-based DAC.
// configure PWM - 32 kHz / 8 = 4 kHz :: 6 bit in two PWMs, done only once on power-up
A 7-bit DAC (Figure 5) can be implemented using 1% resistors. This time, two PWM signals are used to make two three-bit DACs, totaling six bits, and the MSB is simply set to 0 or 1 at P3.7 (Listing 2).
Listing 2. Code to initialize & write to a 7-bit (3+3+1) PWM-based DAC.
// configure PWM - 32 kHz / 8 = 4 kHz :: 7 bit in two PWMs and one digital pin, done only once on power-up
The speed improvement here is even greater. A simple PWM DAC would have a period of 128 clock periods (128/32768 s-1 = 3.9 ms), resulting in t of 32·T = 125 ms and a settling time of 5×125 ms = 625 ms. Figure 6 settles in 40 ms — 16× faster. A higher-order LPF would also help to reduce settling time.
Materials on the topic
News on theme: