그라운드 임베디드 EN 유튜브 구독

노트 / C 언어

비트 연산: 켜고, 끄고, 뒤집기

AND로 지우고, OR로 켜고, XOR로 뒤집고, 시프트로 자리를 옮깁니다. 레지스터 제어의 기본 문법입니다.

GROUND EMBEDDED · 정리 노트C 언어 09비트 연산 1reg |= (1u << n);// n번 비트 켜기 2reg &= ~(1u << n);// n번 비트 끄기 3reg ^= (1u << n);// n번 비트 뒤집기 4if (reg & (1u << n))// n번 비트 확인

레지스터 하나에는 기능이 다른 비트가 여러 개 들어 있습니다. 원하는 비트만 바꾸고 나머지는 그대로 두는 것이 비트 연산의 목적입니다.

네 가지 패턴

reg |=  (1u << n);    // n번 비트 켜기
reg &= ~(1u << n);    // n번 비트 끄기
reg ^=  (1u << n);    // n번 비트 뒤집기
if (reg & (1u << n))  // n번 비트 확인

여러 비트짜리 필드 바꾸기

모드처럼 2비트 이상인 필드는 먼저 지우고 새 값을 넣습니다.

reg = (reg & ~(0x3u << 4)) | (mode << 4);

시프트 주의점

  • 1 << 31은 부호 있는 int라 정의되지 않은 동작이 될 수 있습니다. 1u를 씁니다.
  • 부호 있는 음수를 오른쪽으로 밀면 컴파일러에 따라 부호 비트가 채워집니다.

읽고-바꾸고-쓰기

|=는 읽고, 바꾸고, 다시 쓰는 세 단계입니다. 중간에 인터럽트가 같은 레지스터를 바꾸면 그 변경이 사라집니다. STM32의 BSRR처럼 쓰기만으로 비트를 바꾸는 레지스터가 따로 있는 이유입니다.

네 가지 기본 동작

레지스터의 다른 비트는 건드리지 않고 원하는 비트만 바꾸는 것이 목표입니다.

하려는 일 코드 원리
켜기 reg |= (1u << n); OR는 1과 만나면 1
끄기 reg &= ~(1u << n); AND는 0과 만나면 0
뒤집기 reg ^= (1u << n); XOR는 1과 만나면 반대
읽기 (reg >> n) & 1u 원하는 비트를 맨 아래로 내려서 확인
무료 전자책이 주제를 한 권으로 이어 읽기 (PDF 3권)→

여러 비트로 된 필드 바꾸기

GPIO 모드처럼 두 비트 이상이 한 묶음인 필드는 "지우고 나서 쓰기" 순서로 다룹니다. 지우지 않고 OR만 하면 예전 값과 섞입니다.

#define MODE_POS   10u
#define MODE_MASK  (0x3u << MODE_POS)

uint32_t tmp = GPIOA->MODER;
tmp &= ~MODE_MASK;              // 1) 해당 필드를 00으로
tmp |= (0x1u << MODE_POS);      // 2) 새 값 01(출력)을 써 넣기
GPIOA->MODER = tmp;             // 3) 한 번에 반영

임시 변수에서 계산을 끝내고 한 번에 쓰는 이유는, 중간 상태(00)가 실제 핀에 잠깐이라도 나가는 것을 막기 위해서입니다.

그림으로 보기

reg0010 1100원래 값mask0010 00001u << 5결과0010 1100이미 1이라 그대로끄기0000 1100reg & ~mask
0x2C의 5번 비트를 켜는 과정. 마스크와 OR 하면 나머지 비트는 그대로입니다.

현업에서 자주 터지는 문제

  • 1 << 31: 1은 부호 있는 int라서 31칸 밀면 정의되지 않은 동작입니다. 항상 1u를 씁니다.
  • 읽고-바꾸고-쓰기 사이의 인터럽트: 메인 루프가 reg |= A를 하는 도중 인터럽트가 같은 레지스터의 다른 비트를 바꾸면 그 변경이 사라집니다. 그래서 많은 MCU가 쓰기 전용인 SET, CLEAR 레지스터(BSRR 등)를 따로 둡니다.
  • 쓰면 지워지는 플래그: 상태 레지스터 중에는 1을 써야 지워지는 비트가 있습니다. |=로 쓰면 다른 플래그까지 함께 지워질 수 있으니 데이터시트의 rc_w1 같은 표기를 확인합니다.
  • 연산자 우선순위: reg & MASK == 0은 reg & (MASK == 0)으로 계산됩니다. 괄호를 씁니다.

스스로 확인

  • 8비트 값 0xA5에서 상위 4비트만 뽑아 내려면 어떤 식을 쓰면 될까요?
  • x & (x - 1)이 0이면 x는 어떤 수일까요?
영상으로 이어 보기공부법과 진로 시리즈 15편2025 임베디드 프로그래밍 공부 순서 | 공부 방법 | 로드맵PROJECT COURSEC 문법을 실제 펌웨어 코드로 써 보고 싶다면밸런싱 로봇 하나를 요구사항, 회로와 PCB, 펌웨어, 앱까지 실무 순서대로 만드는 강의입니다. 10파트 165강.강의 살펴보기 →FREE PDF무료 전자책 3권 받기이 주제를 한 권으로 이어서 읽고 싶다면. BLDC 모터 제어, 직렬통신, 센서를 책 분량으로 묶었습니다. 이메일만 남기면 바로 받습니다.무료로 받기 →