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

06. 8051 구조·SFR·reg52.h

1~5편의 토대 위에서 드디어 실제 칩에 올라섭니다. 첫 주인공은 임베디드 교육의 고전 8051(AT89C52)입니다. 8051의 주변장치(포트·타이머·시리얼·인터럽트)는 모두 SFR(특수 기능 레지스터)로 제어합니다. Keil C51의 <reg52.h> 가 SFR을 이름으로 미리 선언해 둬서 P1 = 0x0F; 처럼 변수에 대입하듯 하드웨어를 다룹니다. 포트에 쓰는 두 방법(전체 / sbit 비트)을 익힙니다.

8051SFRreg52.hsbitsfrAT89C52
소요 시간
약 1.5시간
난이도
📊 초급
선수 조건
🎯 05강
결과물
8051의 구조와 SFR(0x80~0xFF) 개념을 이해하고, <reg52.h> 로 포트를 전체 쓰기와 sbit 비트 쓰기로 제어할 수 있습니다.

이 강의에서 배우는 것

  • 18051의 기본 구조(CPU·ROM/RAM·포트·타이머·시리얼·인터럽트)를 개략한다
  • 2SFR이 무엇이고 메모리 어디(0x80~0xFF)에 위치하는지 설명한다
  • 3<reg52.h> 가 SFR을 이름으로 노출하는 방식을 이해한다
  • 4포트 전체 쓰기(P1 = ...)와 비트 쓰기(sbit)를 구분해 쓴다
  • 5C51 전용 키워드 sfr·sbit·bit 의 쓰임을 안다

소개

8051은 구조가 단순하고 레지스터가 적어 "C로 하드웨어를 어떻게 만지는가"를 배우기에 가장 좋은 칩입니다. 이 트랙의 8051 예제는 μVision 내장 시뮬레이터(Peripherals → I/O-Ports)에서 검증하며, 실제 보드는 필요 없습니다.

핵심 개념

1) 8051 한눈에 보기

자원내용
CPU8비트, 누산기(ACC) 중심
메모리코드 ROM(8KB), 내부 RAM 256B + SFR
입출력4개 8비트 포트 P0~P3
타이머/시리얼Timer0/1(+T2), UART 1채널
ℹ️

8051에서 int 는 16비트입니다(2편). 8비트로 충분한 값은 unsigned char(uint8_t)로 RAM·코드 크기를 아낍니다.

2) SFR — 특수 기능 레지스터

SFR은 주변장치를 제어하는 레지스터로 내부 RAM 0x80~0xFF 영역에 배치됩니다. 주소가 8의 배수(0x80·0x88·0x90…)인 SFR(P0~P3·TCON·SCON·IE 등)은 sbit 으로 개별 비트 접근(bit-addressable)이 가능합니다.

SFR주소역할
P10x90포트 1
TMOD0x89타이머 모드
SCON0x98시리얼 제어
IE0xA8인터럽트 인에이블

3) <reg52.h> 와 포트 쓰기 두 방법

c
#include <reg52.h>     /* sfr P1 = 0x90; 등을 미리 선언 */

P1 = 0x0F;             /* (1) 포트 전체 쓰기: 하위 4비트=1 */

sbit LED0 = P1 ^ 0;    /* (2) sbit: P1 의 0번 비트에 이름 (파일 범위) */
LED0 = 1;              /* P1.0 만 1, 나머지 비트는 그대로 */

`P1 ^ 0` 의 ^ 는 XOR이 아니라 "P1의 0번 비트"를 뜻하는 C51 전용 표기입니다. sfr·sbit·bit 은 표준 C에 없는 Keil C51 확장이라 이 main.c 는 PC gcc 로 컴파일되지 않습니다(로직은 pc_test.c 로).

핵심 예제

포트 전체 쓰기 후 개별 비트를 조작한 최종값을 PC에서 검산합니다(SFR을 일반 변수로 흉내).

c
#include <stdio.h>
int main(void) {
    unsigned char P1 = 0x0F;                       /* 전체 쓰기 */
    P1 = (unsigned char)(P1 & ~(1u << 0));         /* LED0 = 0 */
    P1 = (unsigned char)(P1 | (1u << 7));          /* LED7 = 1 */
    printf("P1 = 0x%02X\n", P1);                   /* 0x8E */
    return 0;
}

시뮬레이터: Peripherals → I/O-Ports → Port 1 창에서 P1 = 0x8E(1000 1110) 패턴을 확인합니다.

자주 하는 실수

Q. gcc 로 main.c 를 컴파일하니 reg52.h 가 없대요.

A. <reg52.h>·sfr·sbit 은 Keil C51 전용입니다. 디바이스 main.c 는 μVision에서만 빌드됩니다. PC에서는 pc_test.c(표준 C)로 로직만 검산하세요.

Q. sbit LED = P1 ^ 0; 을 함수 안에 썼더니 오류가 나요.

A. sfr/sbit 선언은 파일 범위(전역)에 둬야 합니다. 함수 안에서는 선언할 수 없으니 main 위쪽에 두세요.

Q. 큰 카운터에 int 를 썼더니 이상해요.

A. 8051에서 int 는 16비트입니다. 8비트면 충분한 포트 값/카운터는 unsigned char 를, 큰 수는 unsigned int(16비트)/unsigned long(32비트)을 명시하세요.

정리

  • 8051은 단순한 8비트 MCU로 주변장치를 SFR(0x80~0xFF)로 제어한다
  • <reg52.h> 가 P1·TMOD·IE 등 SFR을 이름으로 제공한다
  • 포트는 전체 쓰기(P1 = 0x0F)와 비트 쓰기(sbit)로 다룬다
  • sfr·sbit·bit 은 C51 전용이라 PC gcc 로는 안 된다(로직은 pc_test.c)
  • 8비트로 충분한 값엔 unsigned char 로 자원을 아낀다

과제

  1. P1 에 0xAA 를 쓴 뒤 sbit 으로 P1.0 과 P1.7 만 반전한 결과를 예측하고 pc_test 로 검산
  2. P2 의 하위 4비트만 켜고 상위 4비트는 보존하는 코드를 마스크로 작성
  3. μVision에서 AT89C52 빈 프로젝트를 만들고 Port 1 창으로 P1 값 변화를 관찰
예제 코드 / 강의 자료

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

GitHub에서 보기 ↗