← Embedded C 강의 목록으로
🔌
STM32
STM32 · 선수: 14강

15. GPIO 입력·풀업/풀다운

14편이 핀으로 신호를 내보냈다면 이번엔 핀으로 신호를 읽습니다. 초보자가 꼭 걸리는 함정은 플로팅 입력 — 아무것도 연결 안 된 핀은 0도 1도 아닌 떠 있는 상태라 노이즈에 흔들립니다. 이를 막는 것이 풀업/풀다운 저항이고, STM32는 내부에 내장합니다. PA0를 입력+내부 풀업으로 두고 IDR로 버튼을 읽어 PC13 LED를 제어합니다. F1은 풀업/풀다운 선택을 ODR로 한다는 특이점이 핵심입니다.

GPIO입력IDR풀업풀다운플로팅액티브로우
소요 시간
약 1.5시간
난이도
📊 중급
선수 조건
🎯 14강
결과물
입력 모드(CNF=10, 0x8)와 ODR로 내부 풀업/풀다운을 설정하고, 읽기 전용 IDR로 버튼을 읽어 액티브 로우 판정으로 LED를 제어할 수 있습니다.

이 강의에서 배우는 것

  • 1GPIO를 입력 모드로 설정하고 IDR로 핀 상태를 읽는다
  • 2플로팅 입력의 위험과 풀업/풀다운의 필요성을 설명한다
  • 3F1에서 내부 풀업/풀다운을 ODR 비트로 선택한다
  • 4액티브 로우/하이 버튼 판정 논리를 구현한다
  • 5버튼 입력으로 LED를 켜고 끈다

소개

버튼·스위치 같은 입력은 임베디드의 기본입니다. 플로팅 입력은 주변 노이즈에 따라 0과 1 사이를 떠돌아 버튼을 안 눌러도 눌린 것처럼 읽힐 수 있습니다. 풀업(평소 1)·풀다운(평소 0)으로 기본값을 정해 해결합니다.

핵심 개념

1) 입력 모드 4비트와 풀업 선택

CNF입력 종류4비트
00아날로그0x0
01플로팅(리셋 기본)0x4
10풀업/풀다운0x8
c
GPIOA->CRL |= (0x8u << 0);   /* PA0 = 풀업/풀다운 입력 */
GPIOA->ODR |= (1u << 0);     /* ODR=1 → 풀업, ODR=0 → 풀다운 */
⚠️

F1의 특이점: CNF=10일 때 풀업이냐 풀다운이냐는 ODR 비트가 정합니다(1=풀업, 0=풀다운). ODR 설정을 빠뜨리면 풀업이 안 걸립니다.

2) 읽기(IDR)와 능동 논리

c
if ((GPIOA->IDR & (1u << 0)) == 0u) { /* PA0 = 0 (눌림) */ }
/* 풀업 + 버튼이 GND 로 연결 → 안 누름=1, 누름=0 (액티브 로우) */

IDR(Input Data Register)은 읽기 전용입니다. 출력은 ODR/BSRR/BRR로 합니다.

핵심 예제

c
#include "stm32f10x.h"
#define BTN 0u   /* PA0 */
#define LED 13u  /* PC13 */
int main(void) {
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
    GPIOA->CRL &= ~(0xFu << (BTN*4u));
    GPIOA->CRL |=  (0x8u << (BTN*4u));   /* 입력 풀업/풀다운 */
    GPIOA->ODR |=  (1u << BTN);          /* 풀업 선택 */
    GPIOC->CRH &= ~(0xFu << ((LED-8u)*4u));
    GPIOC->CRH |=  (0x2u << ((LED-8u)*4u));
    while (1) {
        if ((GPIOA->IDR & (1u << BTN)) == 0u) GPIOC->BRR  = (1u << LED); /* 눌림 ON */
        else                                  GPIOC->BSRR = (1u << LED); /* OFF */
    }
}

판정 검산: IDR=0x0001→released(LED OFF), IDR=0x0000→PRESSED(LED ON). 시뮬레이터 Command 창에서 `PORTA &= ~0x0001`(눌림)/`PORTA |= 0x0001`(뗌)로 흉내 냅니다.

자주 하는 실수

Q. 버튼을 안 눌렀는데 값이 마구 흔들려요.

A. 풀업/풀다운을 안 켜서 플로팅 상태입니다. CNF=10(0x8)으로 두고 ODR로 풀업(1)/풀다운(0)을 선택하세요.

Q. CNF=10으로 했는데도 풀업이 안 걸려요.

A. F1은 ODR 비트로 풀업/풀다운을 고릅니다. 입력 모드에서 ODR=1이면 풀업, 0이면 풀다운입니다. ODR 설정을 빠뜨리지 마세요.

Q. IDR에 쓰면 핀이 바뀌나요?

A. IDR은 읽기 전용입니다. 출력은 ODR/BSRR/BRR로 합니다. IDR은 핀의 현재 입력 상태를 읽기만 합니다.

정리

  • 입력은 MODE=00, CNF로 종류 결정(0x8=풀업/풀다운 입력)
  • 플로팅을 피하려 풀업/풀다운을 켜고, F1은 그 선택을 ODR로 한다
  • 핀 상태는 읽기 전용 IDR로 읽는다
  • 풀업 + GND 버튼 = 눌림이 0(액티브 로우)
  • 채터링 처리는 디바운싱(21편)에서

과제

  1. PA0를 풀다운(ODR=0)으로 바꾸고 버튼을 VCC에 달았을 때의 판정 논리 작성
  2. 버튼을 누르고 있는 동안만 LED ON 하는 미러링과, 누를 때마다 토글하는 에지 검출을 비교 구현
  3. IDR 마스킹 시 우선순위 함정((IDR & m) == 0)을 설명
예제 코드 / 강의 자료

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

GitHub에서 보기 ↗