Bit-banging a digital-to-analog converter
Many times in designing an embedded system, you'll need a simple analog output from the microcontroller but won't have access to a hardware resource that can effect the digital-to-analog (D/A) conversion. Perhaps your system doesn't have a converter built in or it's too expensive to add one. In such a case, you can use a port pin and bit bang using pulse-width modulation (PWM) to accomplish the D/A output.
A simple timer resource produces an analog output from an embedded controller. I'll demonstrate some things that may be done using very little resources and the timer service as I described in a previous blog.
Bit-banging a D/A converter has distinct advantages and disadvantages:
- A bit banging PWM converter is very cheap. The only cost to implement this in hardware is a spare port pin and a simple single pole resistor–capacitor (RC) filter.
- The implementation of a simple PWM is relatively straightforward. The actual code to do a PWM bit-bang interface requires a timer service interrupt and very little other code and resources.
- Using object-oriented techniques; we can instance many bit-banging PWM instances. The limit is set by the number of available port pins on the microcontroller.
- The bit-banging PWM may not be accurate because the output voltage of the converter depends on the actual logic level of the port pin. Of course, we could use the port pin to modulate a field-effect transister (FET), which in turn is connected to a band-gap reference. However, this may defeat the "cheapness" of the bit-bang PWM.
- You'll either need to really amp up the sampling rate for the timer service, (several 100s of kilohertz), have a very large RC filter, or add more poles to the filter using op-amp circuitry. Again, this will also defeat the relative cheapness of the bit-bang structure.
So let us start by describing the basics of the PWM, or pulse width modulation. This won't take long. I am doing this merely as a starting point so you and I have a common reference as I explain things.
Figure 1 shows the basics of a PWM and the idea of how to implement one. The basic idea is to start with the desired digital output, (in this case a digital sine wave value), and to convert it via a triangle wave, (in this case a timer-based counter). We use this to generate the desired PWM signal. We add a low-pass filter this signal to get the resultant analog output, (sine wave) that we desire.
Click on image to enlarge.
Figure 1: PWM signal generation.