Lesson 40 of 48 intermediate

Interfacing Keyboard, LEDs, and Seven-Segment Displays

Building Real Input/Output Hardware

Open interactive version (quiz + challenge)

Real-world analogy

Think of a game show. The keyboard is the contestant panel — each button press sends a signal. LEDs are the score lights — the host turns them on or off. The seven-segment display is the scoreboard — it shows numbers by lighting up specific bar-shaped segments. The 8255 is the stage manager who connects contestants to the scoreboard, relaying every press and updating every display.

What is it?

This lesson covers the practical interfacing of common I/O devices to the 8086 through the 8255 PPI: matrix keyboard scanning (row-by-row with debouncing), LED driving (direct port output with running light patterns), seven-segment display encoding (lookup tables mapping digits to segment patterns), and multiplexed multi-digit displays (time-division scanning that creates the illusion of simultaneous display).

Real-world relevance

Every calculator, microwave oven, elevator panel, and gas pump uses these exact techniques. The seven-segment display in your alarm clock uses multiplexing — only one digit is actually lit at any instant, switching thousands of times per second. ATM keypads use matrix scanning identical to what we implement here. These are among the most universally used interfacing patterns in all of electronics.

Key points

Code example

; =============================================
; Keyboard → 7-Segment Display System
; =============================================
;
; 8255 at base 80h
; Port A (80h) = 7-segment output
; Port B (81h) = 4x4 keyboard (rows out, cols in)
; Control (83h)
;
; Configure 8255:
  MOV AL, 82h           ; PA=out, PB=in, Mode 0
  OUT 83h, AL
;
; Segment lookup table:
SEG_TBL DB 3Fh,06h,5Bh,4Fh,66h,6Dh,7Dh,07h,7Fh,6Fh
;           0    1    2    3    4    5    6    7    8    9
;
MAIN:
  ; --- Scan keyboard ---
  MOV AL, 0FEh          ; row 0 active (LOW)
  OUT 81h, AL
  NOP                   ; settling time
  IN AL, 81h            ; read columns
  AND AL, 0F0h
  CMP AL, 0F0h
  JNE GOT_KEY_R0        ; key in row 0
;
  MOV AL, 0FDh          ; row 1
  OUT 81h, AL
  NOP
  IN AL, 81h
  AND AL, 0F0h
  CMP AL, 0F0h
  JNE GOT_KEY_R1        ; key in row 1
;
  JMP MAIN              ; no key, rescan
;
GOT_KEY_R0:
  ; Decode column and map to digit 0-3
  ; (column detection logic here)
  MOV BL, 0             ; example: key = 0
  JMP DISPLAY_IT
;
GOT_KEY_R1:
  MOV BL, 4             ; example: key = 4
;
DISPLAY_IT:
  ; Debounce: wait 20ms
  MOV CX, 5000
DBNC: LOOP DBNC
;
  ; Lookup segment pattern
  LEA SI, SEG_TBL
  MOV BH, 0
  MOV AL, [SI+BX]       ; get pattern for digit
  OUT 80h, AL           ; display on 7-segment
  JMP MAIN              ; back to scanning

Line-by-line walkthrough

  1. 1. Title comment for the keyboard-to-display system
  2. 2. Separator line
  3. 3. Blank line
  4. 4. System description: 8255 base address 80h
  5. 5. Port A at 80h drives the seven-segment display (output)
  6. 6. Port B at 81h reads the 4x4 keyboard matrix (input)
  7. 7. Control register at 83h
  8. 8. Blank line
  9. 9. Configure 8255: control word 82h means PA=output, PB=input, Mode 0
  10. 10. Write the control word to initialize the 8255
  11. 11. Blank line
  12. 12. Segment lookup table: 10 bytes mapping digits 0-9 to segment patterns
  13. 13. Comment showing which byte corresponds to which digit
  14. 14. Blank line
  15. 15. MAIN label: start of keyboard scanning loop
  16. 16. Load 0FEh (11111110) to drive row 0 LOW
  17. 17. Output to Port B to activate row 0
  18. 18. NOP gives the signal time to settle on the wires
  19. 19. Read back Port B to check which columns are LOW (key pressed)
  20. 20. AND with F0h isolates the column bits (upper nibble)
  21. 21. Compare with F0h — if all columns HIGH, no key in this row
  22. 22. If not equal, a key was detected in row 0 — jump to handler
  23. 23. Blank line
  24. 24. Load 0FDh (11111101) to drive row 1 LOW
  25. 25. Output to Port B to activate row 1
  26. 26. NOP for settling time
  27. 27. Read columns again
  28. 28. Isolate column bits
  29. 29. Compare for key press
  30. 30. If key found in row 1, jump to that handler
  31. 31. Blank line
  32. 32. No key detected in any row, jump back to MAIN and rescan
  33. 33. Blank line
  34. 34. Handler for key in row 0 — decode column to determine exact key
  35. 35. Comment: column detection logic maps the pattern to a key number
  36. 36. Example: BL=0 means the key maps to digit 0
  37. 37. Jump to display routine
  38. 38. Blank line
  39. 39. Handler for key in row 1 — example key = digit 4
  40. 40. Blank line
  41. 41. DISPLAY_IT label: show the digit on the seven-segment display
  42. 42. Debounce delay: load counter for approximately 20ms
  43. 43. DBNS label: LOOP decrements CX and repeats until zero — creating the delay
  44. 44. Blank line
  45. 45. Load address of segment lookup table into SI
  46. 46. Clear BH so BX = the digit value (0-9)
  47. 47. Fetch the segment pattern from the table using BX as index
  48. 48. Output the pattern to Port A, lighting the appropriate segments
  49. 49. Jump back to MAIN to scan for the next keypress

Spot the bug

; Multiplexed 2-digit display
; Port A = segments, Port B = digit select
;
  MOV AL, 80h
  OUT 83h, AL         ; all output mode
;
; Display digit 0 (tens)
  MOV AL, [SEG_TBL+3] ; pattern for '3'
  OUT 80h, AL
  MOV AL, 0FEh        ; select digit 0
  OUT 81h, AL
  CALL DELAY
;
; Display digit 1 (ones) — BUG HERE
  MOV AL, 0FDh        ; select digit 1
  OUT 81h, AL
  MOV AL, [SEG_TBL+7] ; pattern for '7'
  OUT 80h, AL
  CALL DELAY
Need a hint?
Look at the order of operations for digit 1. When does the digit select get activated versus when the segment data is sent?
Show answer
For digit 1, the digit select (0FDh) is output BEFORE the segment data. This means digit 1 briefly shows the OLD segment data (the '3' from digit 0) before being updated to '7', causing ghosting/flicker. Fix: always send segment data FIRST, then activate the digit select — swap the two OUT instructions for digit 1, just like digit 0 does it correctly.

Explain like I'm 5

The keyboard is like a treasure hunt grid — you check each row one by one and see which column responds, telling you exactly which square (key) was pressed. LEDs are simple light switches — flip a bit, flip a light. The seven-segment display is like arranging 7 matchsticks to spell numbers — each number uses a different combination of matchsticks. And multiplexing is like a magician spinning plates — only one plate spins at a time, but they switch so fast it looks like all plates are spinning together!

Fun fact

The seven-segment display was patented in 1908 — over 100 years ago — but did not become popular until LEDs were invented in the 1960s. The original patent used incandescent filaments shaped into segments. Today, seven-segment displays are being replaced by OLED screens, but they remain the cheapest and most reliable way to show numbers in harsh environments like gas stations and industrial equipment.

Hands-on challenge

Build a 2-digit multiplexed seven-segment counter that counts from 00 to 99. Use Port A for segment data and Port B for digit selection. Write the complete assembly code including the multiplexing routine, the counting logic, and a delay to make the count visible to human eyes (~1 second per increment).

More resources

Open interactive version (quiz + challenge) ← Back to course: Microprocessor A–Z