← Back to Embedded C series
🔌
8051
8051 · Prereq: lesson 11

12. 7-Segment Display (Multiplexing)

Now we show human-readable digits. A 7-segment uses 7 bar LEDs (a~g) + a dot to draw 0–9. The keys: ① a lookup table mapping a digit to "which bars to light", and ② multiplexing (dynamic drive) that shows multiple digits while saving pins. We light "1234" one digit at a time, very fast, so persistence of vision makes all four appear lit at once.

7-segmentlookup tablemultiplexingdynamic driveghostingcommon cathode
Duration
~1.5 hours
Level
📊 Intermediate
Prerequisite
🎯 Lesson 11
OUTCOME
Drive a 4-digit 7-segment without ghosting using a 0–9 lookup table and multiplexing (off→write→on order).

What you'll learn

  • 1Explain segment layout (a~g·dp) and common cathode/anode
  • 2Build a lookup table mapping 0–9 to segment bit patterns
  • 3Drive multiple digits by separating digit-select from segment output
  • 4Show 4 digits at once via multiplexing (time-division + persistence)
  • 5Avoid ghosting with the off→change→on order

Introduction

On top of lessons 6–7's port output we add a lookup table and time-division. This lesson assumes common cathode (bit=1 is ON). (μVision's simulator has no 7-segment graphic, so we verify the P0/P2 value cycling in the Port windows/Logic Analyzer, and the digit→code conversion in pc_test.)

Key concepts

1) 0–9 lookup table (common cathode)

Bit layout: a=0 b=1 c=2 d=3 e=4 f=5 g=6 dp=7. Each digit's segments are fixed, so precompute a table and fetch SEG_CODE[n].

c
static const unsigned char SEG_CODE[10] = {
  0x3F,0x06,0x5B,0x4F,0x66, 0x6D,0x7D,0x07,0x7F,0x6F
}; /* 0–9 */

2) Digit select — saving pins

Wiring 4 digits with 7 pins each needs 28 pins. Instead, the 4 digits share the segment pins (a~g) and a digit-select pin picks "which digit". That's 7+4=11 pins. But since segment lines are shared, only one digit can be lit at any instant.

3) Multiplexing and ghost prevention

c
1) turn off all digits  →  2) write the new segment pattern  →  3) turn on only that digit
⚠️

Changing the pattern while a digit is on briefly shows a wrong pattern there (ghosting). Always follow off → write → on.

Core example

c
#include <reg52.h>
#define SEG_PORT P2   /* segments */
#define DIG_PORT P0   /* digit select */
static const unsigned char SEG_CODE[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
static void delay(unsigned int n){ unsigned int i; for(i=0;i<n;i++){} }

void main(void){
    unsigned char digits[4] = {1,2,3,4};
    unsigned char d;
    while(1){
        for(d=0; d<4; d++){
            DIG_PORT = 0x00;                      /* 1) off (ghost prevention) */
            SEG_PORT = SEG_CODE[digits[d]];       /* 2) write pattern */
            DIG_PORT = (unsigned char)(1u << d);  /* 3) turn on only this digit */
            delay(150);
        }
    }
}

PC check: draw the lit segments as letters — 0→ABCDEF-, 1→-BC----, 8→ABCDEFG — to verify the lookup table.

Common mistakes

Q. Digits overlap or show faint ghosting.

A. You changed the pattern before turning the digit off. Always follow off (DIG_PORT=0) → write pattern → turn on digit.

Q. One digit is bright, others are dim.

A. The per-digit hold time is too long, or it stalls on one digit. Cycle the 4 digits fast enough (1–5ms each, ≥50Hz overall) for equal brightness.

Q. Common anode lights all or nothing.

A. This code assumes common cathode (bit=1 ON). For common anode, ON/OFF are reversed — invert (~) the segment code.

Summary

  • 7-segment draws digits with a~g(+dp); common cathode is ON at bit=1
  • Map digit→pattern fast with the lookup table SEG_CODE[n]
  • Sharing segment lines saves pins as you add digits (one digit at a time)
  • Multiplexing: cycle digits fast so persistence shows them all lit
  • Prevent ghosting: off → write pattern → turn on digit

Exercises

  1. Invert SEG_CODE (~) to drive a common-anode display
  2. Use a timer (lesson 9) to make a counter that increments 0000→0001… every second
  3. Extend the lookup table to show hex digits (A–F)
Example code / lecture materials

All lecture materials and example code (with homework and answers) are openly available on GitHub.

View on GitHub ↗