Microcontroller's Single I/O-Port Line Drives a Bar-Graph Display
Instrument designs featuring a digital display may benefit from a secondary display that provides an analog version of the displayed parameter. A bar-graph display provides an easily interpreted graphical indicator that allows comparison with its full-scale value, but a conventional microcontroller-based design uses at least one eight-line I/O port to drive an eight-segment-bar-graph LED display.
As an alternative, some microcontrollers include a PWM (pulse-width-modulated) output. You can minimize the number of required I/O lines by using the PWM output to drive National Semiconductor's LM3914 bar-graph-display-driver circuit or an equivalent. In operation, the microcontroller's program adjusts the PWM output's pulse width such that the average voltage that feeds to the LM3914 circuit illuminates the required number of bars in the display.
The design in Figure 1 obviates the shortcomings of these approaches and uses only one port line to drive an eight-segment bar graph. This design does not use a PWM output and hence can apply to any microcontroller. Referring to the timing diagram in Figure 2, whenever the bar-graph display requires an update, the microcontroller's software delivers a pulse train through its output port. The first pulse comprises a pulse of width T1 that's longer than the width of the pulse T2, which triggering monostable IC1, a 74123 or equivalent, produces. You apply both pulses to IC3, a 7400 or equivalent NAND gate, which together with IC1 forms a long-pulse detector. Use the equation in IC1's data sheet to select values for C1 and R1 that yield a value of approximately 1.5 msec for T2's output pulse. Typical widths for T1 and T3 are 3 and 1 msec, respectively.
The output pulse from IC3 goes low for a duration of T1–T2, and this pulse clears IC2, an 8-bit serial-in parallel-out shift register, which forces all of IC2's outputs to go low and lights all segments of the bar-graph array (LED1 to LED8).
To light N segments of the bar-graph array, the microcontroller immediately sends a serial train of (8–N) pulses of width T3 through the output-port line. Because the width of these pulses is less than T2, NAND gate IC3's output always remains high and thus does not clear the shift register. The rising edge of each of the microcontroller's output pulses loads a high to one of IC2's outputs.
Note that shift register IC2's QA output connects to the bar graph's most significant segment. Hence, the first pulse switches off the most significant segment. Starting with the most significant segment, for (8–N) pulses, 8–N segments switch off, and N segments beginning with the least significant segment remain lighted. Using this reverse logic takes advantage of the shift register's outputs' ability to sink more current than they can source—8 versus 0.4 mA, respectively, and thus produce a brighter bar-graph display without adding output buffers. Figure 2 shows a sample timing diagram that lights five of eight display segments.
If a second output-port line is available, you can omit using monostable multivibrator IC1 and NAND gate IC3 and use the second port to clear the shift register by outputting a zero whenever the bar graph requires an update. To obtain finer resolution, you can add segments to the bar graph by cascading additional shift registers. To light N segments of a display that is M segments long, the first output port sends M–N pulses to the shift register's clock input.
This design lends itself well to situations in which unused I/O-port lines are at a premium, as is the case for microcontrollers with reduced pin counts, or if you need to retrofit a bar-graph display by adding a daughterboard to a design.
News on theme: