← Embedded C 강의 목록으로
🔌
8051
8051 · 선수: 11강

12. 7-세그먼트 표시 (멀티플렉싱)

사람이 읽을 수 있는 숫자를 표시합니다. 7-세그먼트는 막대 LED 7개(a~g)+소수점으로 0~9를 그립니다. 핵심은 ① 숫자를 "어떤 막대를 켤지"의 비트 패턴으로 바꾸는 룩업 테이블, ② 자리가 여러 개일 때 핀을 아끼며 모두 켜 보이게 하는 멀티플렉싱(동적 구동)입니다. "1234"를 한 자리씩 빠르게 번갈아 켜 잔상으로 네 자리가 동시에 켜진 것처럼 보이게 만듭니다.

7세그먼트룩업테이블멀티플렉싱동적구동잔상공통음극
소요 시간
약 1.5시간
난이도
📊 중급
선수 조건
🎯 11강
결과물
0~9 룩업 테이블과 멀티플렉싱(끄기→쓰기→켜기 순서)으로 4자리 7-세그먼트를 잔상 없이 구동할 수 있습니다.

이 강의에서 배우는 것

  • 17-세그먼트 배치(a~g·dp)와 공통 음극/양극 차이를 설명한다
  • 20~9를 세그먼트 비트 패턴으로 바꾸는 룩업 테이블을 만든다
  • 3자리 선택과 세그먼트 출력을 분리해 여러 자리를 구동한다
  • 4멀티플렉싱(시간 분할+잔상)으로 4자리를 동시에 켜 보이게 한다
  • 5잔상(ghosting)을 막는 끄기→바꾸기→켜기 순서를 적용한다

소개

6~7편의 포트 출력 위에 룩업 테이블과 시간 분할이라는 새 도구를 얹습니다. 이 편은 공통 음극(비트=1이 ON)을 가정합니다. (μVision 시뮬레이터엔 7-세그먼트 그래픽이 없어 P0/P2 값의 순환을 Port 창/Logic Analyzer로 확인하고, 숫자→코드 변환은 pc_test 로 검증합니다.)

핵심 개념

1) 0~9 룩업 테이블 (공통 음극)

비트 배치: a=0 b=1 c=2 d=3 e=4 f=5 g=6 dp=7. 숫자마다 켤 세그먼트가 정해져 있으니 표로 만들어 SEG_CODE[n] 으로 꺼내 씁니다.

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

2) 자리 선택 — 핀 아끼기

4자리를 각각 7핀씩 따로 연결하면 28핀이 필요합니다. 세그먼트 핀(a~g)을 4자리가 공유하고 "어느 자리를 켤지"만 자리 선택 핀으로 고르면 7+4=11핀으로 충분합니다. 단, 세그먼트선을 공유하므로 한 순간에는 한 자리만 켭니다.

3) 멀티플렉싱과 잔상 방지

c
1) 모든 자리 끄기  →  2) 새 세그먼트 패턴 쓰기  →  3) 해당 자리만 켜기
⚠️

자리를 켠 채 패턴을 바꾸면 바뀌는 순간 엉뚱한 패턴이 비쳐 잔상(ghosting)이 생깁니다. 항상 끄기 → 쓰기 → 켜기 순서를 지키세요.

핵심 예제

c
#include <reg52.h>
#define SEG_PORT P2   /* 세그먼트 */
#define DIG_PORT P0   /* 자리 선택 */
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) 끄기(잔상 방지) */
            SEG_PORT = SEG_CODE[digits[d]];       /* 2) 패턴 쓰기 */
            DIG_PORT = (unsigned char)(1u << d);  /* 3) 이 자리만 켜기 */
            delay(150);
        }
    }
}

PC 검산: 0→ABCDEF-, 1→-BC----, 8→ABCDEFG 처럼 켜진 세그먼트를 글자로 그려 룩업 테이블 정확성을 확인합니다.

자주 하는 실수

Q. 자리가 겹쳐 보이거나 흐릿한 잔상이 생겨요.

A. 패턴을 바꾸기 전에 자리를 끄지 않아서입니다. 반드시 끄기(DIG_PORT=0) → 패턴 쓰기 → 자리 켜기 순서를 지키세요.

Q. 한 자리만 밝고 나머지는 어두워요.

A. 자리당 유지 시간이 너무 길거나 한 자리에서 멈췄습니다. 4자리를 충분히 빠르게(자리당 1~5ms, 전체 50Hz 이상) 돌아야 같은 밝기로 보입니다.

Q. 공통 양극인데 다 켜지거나 다 꺼져요.

A. 이 코드는 공통 음극(비트=1 ON) 가정입니다. 공통 양극이면 ON/OFF가 반대라 세그먼트 코드를 반전(~)해야 합니다.

정리

  • 7-세그먼트는 a~g(+dp)로 숫자를 그리며 공통 음극은 비트=1이 ON
  • 숫자→패턴은 룩업 테이블 SEG_CODE[n]로 빠르게 변환한다
  • 세그먼트선을 공유하면 자리를 늘려도 핀을 아낀다(한 순간 한 자리)
  • 멀티플렉싱: 빠르게 자리를 번갈아 켜면 잔상으로 모두 켜 보인다
  • 잔상 방지: 끄기 → 패턴 쓰기 → 자리 켜기 순서를 지킨다

과제

  1. 공통 양극 디스플레이용으로 SEG_CODE 를 반전(~)해 동작시키기
  2. 타이머(9편)로 1초마다 표시 숫자를 0000→0001…로 증가시키는 카운터 만들기
  3. 16진 숫자(A~F)까지 표시하도록 룩업 테이블 확장
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드(과제·정답 포함)는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗