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

07. GPIO 출력 — LED 점멸

임베디드의 "Hello, World"는 LED 깜빡이기입니다. 포트에 어떤 값을 써야 LED가 켜지는지(액티브 로우/하이 배선), 얼마나 기다려야 보이는지(지연), 여러 LED로 패턴을 만드는 법(비트 마스크)까지 GPIO 출력의 핵심이 다 들어 있습니다. P1에 연결된 LED 8개로 흐르는 불빛(running light)을 만들고 Logic Analyzer로 핀 파형을 관찰합니다.

GPIO출력LED액티브로우지연마스크
소요 시간
약 1시간
난이도
📊 초급
선수 조건
🎯 06강
결과물
액티브 로우 배선에서 ~(1u<<pos) 로 한 LED만 켜고, while(1)+지연으로 흐르는 불빛 패턴을 만들며 Logic Analyzer로 파형을 확인할 수 있습니다.

이 강의에서 배우는 것

  • 1GPIO 출력으로 LED를 제어하고 액티브 로우/하이 차이를 설명한다
  • 2while(1) 안에서 포트 값을 바꿔 LED를 점멸시킨다
  • 3소프트웨어 지연 루프의 동작과 한계(부정확)를 이해한다
  • 4마스크 ~(1u<<pos) 로 흐르는 불빛 패턴을 만든다
  • 5Logic Analyzer로 포트 핀 토글을 관찰한다

소개

6편의 포트 SFR 쓰기를 무한 루프 안에서 반복해 패턴을 만듭니다. 많은 8051 보드가 LED를 액티브 로우(핀이 0일 때 ON)로 달기 때문에, "켜고 싶은 비트만 0"으로 만드는 감각이 중요합니다.

핵심 개념

1) LED 배선 — 액티브 로우 vs 하이

방식LED ON 조건
액티브 하이(핀→LED→GND)핀 = 1
액티브 로우(VCC→LED→핀)핀 = 0

8051은 0을 출력할 때(싱크) 전류를 더 흘릴 수 있어 보드들이 흔히 액티브 로우로 답니다. 이 편은 액티브 로우 가정.

2) 한 LED만 켜기 — ~(1u<<pos)

c
/* 액티브 로우: pos 번 비트만 0, 나머지 1 */
pos=0 -> ~(1<<0) = 0xFE = 11111110  (LED0 ON)
pos=3 -> ~(1<<3) = 0xF7 = 11110111  (LED3 ON)
/* pos 를 0->7 로 옮기며 반복하면 불빛이 한 칸씩 흐른다 */

3) 소프트웨어 지연

c
static void delay(unsigned int n) {
    unsigned int i;
    for (i = 0; i < n; i++) { }   /* 부정확! 정확한 시간은 9편 타이머 */
}
⚠️

컴파일러가 빈 루프를 최적화로 제거할 수 있습니다. 유지하려면 루프 변수를 volatile 로, 정밀 지연이 필요하면 타이머(9편)를 쓰세요.

핵심 예제

c
#include <reg52.h>
#define LED_PORT P1
static void delay(unsigned int n){ unsigned int i; for(i=0;i<n;i++){} }

void main(void) {
    unsigned char pos = 0;
    while (1) {
        LED_PORT = (unsigned char)~(1u << pos);  /* 액티브 로우 1개 ON */
        delay(20000);
        if (++pos >= 8) pos = 0;
    }
}

흐르는 불빛이 만드는 포트 값: 0xFE → 0xFD → 0xFB → 0xF7 → 0xEF → 0xDF → 0xBF → 0x7F. Logic Analyzer에 P1.0~P1.7을 추가하면 각 핀이 차례로 Low로 떨어지는 계단형 파형이 보입니다.

자주 하는 실수

Q. 포트에 1을 썼는데 LED가 안 켜져요.

A. 보드가 액티브 로우면 1은 OFF입니다. 0을 써야 켜집니다. 어느 쪽인지 모르면 회로도를 확인하세요(이 예제는 액티브 로우).

Q. LED가 깜빡이지 않고 그냥 켜져 있어요.

A. 지연이 없거나 너무 짧아 눈이 못 따라갑니다. delay 값을 키우거나 Logic Analyzer의 시간축으로 토글 자체를 확인하세요.

Q. 빈 지연 루프가 최적화로 사라져요.

A. 루프 변수를 volatile 로 선언하거나, 정확한 지연은 타이머(9편)를 쓰세요.

정리

  • 배선에 따라 켜는 값이 다르다 — 액티브 로우는 0이 ON
  • 한 LED만 켜기: ~(1u << pos)
  • while(1)+지연으로 점멸/패턴을 만들되 소프트웨어 지연은 부정확하다
  • 여러 LED는 마스크를 OR로 묶어(필요시 반전) 제어한다
  • Logic Analyzer로 파형을, Port 창으로 비트 값을 본다

과제

  1. 흐르는 불빛을 7→0 역방향으로도 도는 왕복(knight rider) 패턴으로 확장
  2. 인접한 LED 2개를 동시에 켜며 흐르게 하는 마스크 작성
  3. 액티브 하이 보드라면 코드를 어떻게 바꿔야 하는지 설명하고 적용
예제 코드 / 강의 자료

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

GitHub에서 보기 ↗