Connecting a 2-digit 7-segment display to a PIC microcontroller

Figure 1: Connecting a 2-digit 7-segment display to a PIC microcontroller

As we have learned from the Interfacing 7-Segment Display With PIC Microcontroller article, a 7-segment display is the earliest type of an electronic display that uses 7 LEDs bars arranged in a way that can be used show the numbers 0 – 9. (actually 8 segments if you count the decimal point, but the generic name adopted is 7-segment display.) These devices are commonly used in digital clocks, electronic meters, counters, signalling, and other equipment for displaying numeric only data. 

The segments of the displays are normally referred to by letters “a” to “g“. The easiest way to display a number on the 7-segment is to find a way to determine or look up the pattern corresponding to the digit to be displayed . This can be something like a table showing the numbers and the corresponding segment that should be turned ON or OFF to display something and the required number (this can be in decimal, hexadecimal or in binary format) to be sent to the port where the display is connected to in order to display a specific number.

Table 1 is an example to show the hexadecimal values of a common cathode 7-Segment display connected to a port of a microcontroller from bit 0 to bit 7.                         7-segment lookup table for hexadecimal values of a common cathode 7-Segment display

Table 1: 7-segment lookup table for hexadecimal values of a common cathode 7-Segment display 

To display more digits, more 1-digit Seven segment display can be joined together as needed. 

A 1-digit 7-segment display can only show numbers from 0 to 9, a 2-digit display can show numbers between 0 and 99, a 3-digit between 0 and 999, a 4-digit between 0 and 9999, and so on.
Figure 1 shows  a 2-digit 7-segment display connected to a PIC microcontroller and figure 2 shows 2-digit and 4-digit seven segment displays.
                   2-digit and 4-digit Seven segment displays

 Figure 2: 2-digit and 4-digit Seven segment displays 

When more digits are required to be displayed, we need to come up with a better technique to connect more than 1-digit 7-segment displays to a microcontroller because if we connect them like the 1-digit display we will soon run out of input/output pins.
A 1-digit 7-segment display requires 7 output pins, a 2-digit would require 14 and a 4-digit would require 28, this is definitely not an efficient way of using a microcontroller.
The common widely used technique is to multiplex the digits to save input/output pins. All the digits share the same microcontroller pins plus few more pins to connect the digits to ground or to positive power depending on whether a common cathode or anode segments are used.
With multiplexing, a 2-digit display will require only 9 pins, a 3-digit display will require 10 pins, a 4-digit display will require 11 pins, and so on. 
Another advantage of multiplexing 7-segment LEDs is to reduce the power consumption considerably. 
In multiplexed applications, all the digit segments are driven in parallel at the same time, but only the common pin (e.g. anode or cathode) of the required digit is enabled. By enabling or disabling the digits so fast that it gives the impression to the eye that both displays are ON at the same time as the human eye cannot differentiate it when the speed is too high. This technique is based on the principle of  Persistence of Vision of our eyes. If the frames change at a rate of 25 ( or more) frames per second, human eye can’t detect that visual change.
For example, let say we want to display the number ‘67’ on a 2-digit common cathode display. The steps are given below: 
   1. Send data to display ‘6’ on both digits. 
   2. Enable the left digit by grounding its cathode pin (send a high to the base of the transistor) and disable the right digit. 
   3. Wait for a while. (a short delay) 
   4. Send data to display ‘7’ on both digits. 
   5. Enable the right digit by grounding its cathode pin (send a high to the base of the transistor) and disable the left digit. 
   6. Wait for a while (a short delay). 
   7. Go back to step 1. By doing this rapidly, the eye won’t notice any fluctuation.
The common pins of each digit are usually controlled using transistors switches, almost any NPN transistor such as the BC108-Type transistor could be used for this purpose. A 1KΩ resistor can be used to limit the base current to about 4mA enough to saturate the transistor. 
Figure 1 shows how a 2-digit display can be connected to a microcontroller using NPN transistors to control the segment lines. Notice that setting the base of a transistor to logic HIGH will turn the transistor ON and hence will enable the common cathode pin connected to it.


We are going to display the number “67” on our 2-digit Seven Segment Display. 

Digit1 and Digit2 are defined to be equal to bit 0 and bit 1 of PORTA respectively, these will be used to enable/disable the different digits. The value to be displayed is stored in the variable count. This value has to be split into the least significant and the most significant digit. These two values are stored in LSD and MSD variables. The MSD is calculated by dividing the count value by 10 and the LSD is calculated by using the mod operator (“%”).

#include "Multiplexing-7-Segment.h"
#define Digit1 PORTAbits.RA0
#define Digit2 PORTAbits.RA1
unsigned char Display (unsigned char digit)
    unsigned char pattern;
    unsigned char  SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
    pattern =  SEGMENT_MAP[digit] ;  //The pattern to return
    return (pattern);
void main() {
  unsigned char MSD, LSD, count=67;
  TRISA = 0;            // Configure PORTA as outputs
  TRISB = 0;            // Configure PORTA as outputs
  OSCCON = 0x76;        // Set for Internal Oscillator
 Digit1 = 0;            //Disable digit 1
 Digit2 = 0;            //Disable digit 2
       MSD = count / 10;       //Extract MSD from count.
       LATB = Display(MSD);    //Display the MSD
       Digit2 = 1;             //Enable digit 2
       __delay_ms(10);         //a short 10ms delay
       Digit2 = 0;             //Disable digit 2
       LSD = count % 10;        // LSD digit
       LATB = Display(LSD);    //Display the LSD
       Digit1 = 1;             //Enable digit 1
        __delay_ms(10);           //a short 10ms delay
       Digit1 = 0;             //Disable digit 1

You can download the full project files (MPLAB XC8 source code and Proteus Schematic design) below here.   All the files are zipped, you will need to unzip them (Download a free version of the Winzip utility to unzip files).

Download MPLAB XC8 Project:  Multiplexing-7-Segment.X

Download Proteus Schematic:  Multiplexing 7-Segment Proteus Circuit XC8