12. 7-세그먼트 표시 (멀티플렉싱)
사람이 읽을 수 있는 숫자를 표시합니다. 7-세그먼트는 막대 LED 7개(a~g)+소수점으로 0~9를 그립니다. 핵심은 ① 숫자를 "어떤 막대를 켤지"의 비트 패턴으로 바꾸는 룩업 테이블, ② 자리가 여러 개일 때 핀을 아끼며 모두 켜 보이게 하는 멀티플렉싱(동적 구동)입니다. "1234"를 한 자리씩 빠르게 번갈아 켜 잔상으로 네 자리가 동시에 켜진 것처럼 보이게 만듭니다.
이 강의에서 배우는 것
- 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] 으로 꺼내 씁니다.
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) 멀티플렉싱과 잔상 방지
1) 모든 자리 끄기 → 2) 새 세그먼트 패턴 쓰기 → 3) 해당 자리만 켜기자리를 켠 채 패턴을 바꾸면 바뀌는 순간 엉뚱한 패턴이 비쳐 잔상(ghosting)이 생깁니다. 항상 끄기 → 쓰기 → 켜기 순서를 지키세요.
핵심 예제
#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]로 빠르게 변환한다
- 세그먼트선을 공유하면 자리를 늘려도 핀을 아낀다(한 순간 한 자리)
- 멀티플렉싱: 빠르게 자리를 번갈아 켜면 잔상으로 모두 켜 보인다
- 잔상 방지: 끄기 → 패턴 쓰기 → 자리 켜기 순서를 지킨다
과제
- 공통 양극 디스플레이용으로 SEG_CODE 를 반전(~)해 동작시키기
- 타이머(9편)로 1초마다 표시 숫자를 0000→0001…로 증가시키는 카운터 만들기
- 16진 숫자(A~F)까지 표시하도록 룩업 테이블 확장