임베디드 면접 용어 사전
시리얼 통신CPOL · CPHA · SPI 모드

CPOL / CPHA

SPI의 클럭 유휴 레벨과 샘플링 에지를 정하는 설정. 둘의 조합이 모드 0~3이다.

SPI에서 클럭의 유휴 상태와 데이터 샘플링 시점을 정하는 두 설정.

정의

  • CPOL (Clock Polarity) — — 클럭이 쉴 때의 레벨

    • CPOL = 0 → 유휴 시 Low
    • CPOL = 1 → 유휴 시 High
  • CPHA (Clock Phase) — — 어느 에지에서 데이터를 읽나

    • CPHA = 0 → 첫 번째 에지에서 샘플링
    • CPHA = 1 → 두 번째 에지에서 샘플링

네 가지 모드

모드CPOLCPHA샘플링 에지데이터 변경 에지
000상승하강
101하강상승
210하강상승
311상승하강

모드 0과 모드 3이 가장 널리 쓰인다.

파형으로 이해하기

모드 0 (CPOL=0, CPHA=0)
SCLK  ___┌─┐_┌─┐_┌─┐___     유휴 Low
MOSI  ─X───X───X───X──      데이터는 하강 에지에서 바뀌고
         ↑   ↑   ↑          상승 에지에서 읽힌다
       샘플링

모드 3 (CPOL=1, CPHA=1)
SCLK  ‾‾‾└─┘‾└─┘‾└─┘‾‾‾     유휴 High
MOSI  ─X───X───X───X──
         ↑   ↑   ↑
       샘플링 (상승 에지)

핵심 원리 — 왜 이렇게 나누나

  • 데이터가 안정된 시점에 읽어야 한다
  • 데이터를 바꾸는 에지와 읽는 에지가 반대여야 한다

한쪽 에지에서 출력 → 다른 쪽 에지에서 입력

CPHA가 이 "어느 쪽을 먼저 쓸지"를 정한다.

CPHA = 0 : 첫 에지에서 읽는다

  • 첫 비트는 클럭이 시작되기 전에 이미 나와 있어야 한다

  • CS가 내려가는 순간 첫 비트를 출력한다 ★ CPHA = 1 : 첫 에지에서 출력, 두 번째 에지에서 읽는다

  • 클럭 에지마다 규칙적이라 구현이 단순하다

★ CPHA=0의 특성이 중요하다 — 첫 비트가 CS 하강에 맞춰 나오므로, CS를 바이트마다 토글해야 하는 슬레이브가 있다. 연속 전송에서 CS를 계속 내려 둔 채로 보내면 동작하지 않는다.

모드가 틀리면 어떻게 되나

  • CPHA만 틀림 — → 한 비트씩 밀려서 읽힌다 (0x5A → 0xB4 같은 시프트)
  • CPOL만 틀림 — → 반전된 에지에서 읽어 값이 깨진다
    • (CPHA=1이면 우연히 동작하는 경우도 있다)
  • 둘 다 틀림 → 완전히 엉뚱한 값

"SPI로 읽으면 0xFF나 0x00만 나온다" → 슬레이브 미응답(전원·CS·배선) 또는 모드 불일치를 의심한다.

"읽은 값이 예상값을 1비트 시프트한 것 같다" → CPHA가 틀렸을 가능성이 높다.

설정 방법

hspi.Init.CLKPolarity = SPI_POLARITY_LOW;    // CPOL = 0
hspi.Init.CLKPhase    = SPI_PHASE_1EDGE;     // CPHA = 0
// → 모드 0

슬레이브 데이터시트의 타이밍 다이어그램에서 확인한다. "SCK idle low, data sampled on rising edge" 라고 쓰여 있으면 모드 0이다.

흔한 장치들의 모드

모드 0 : 대부분의 센서, SD 카드, 많은 SPI 플래시 모드 3 : 일부 플래시, 일부 디스플레이 모드 1/2 : 드물다

여러 슬레이브가 서로 다른 모드를 요구하면 슬레이브를 바꿀 때마다 SPI 설정을 재구성해야 한다. 하드웨어 SPI 인스턴스를 나누는 방법도 있다.

로직 애널라이저로 판별하기

  • ① 클럭이 쉴 때의 레벨을 본다 → CPOL
  • ② CS 하강 직후 데이터가 이미 나와 있는가
    • 있다 → CPHA = 0
    • 클럭 첫 에지에서 나온다 → CPHA = 1

대부분의 로직 애널라이저 소프트웨어가 모드를 지정하면 자동 디코딩해 준다. 모드를 바꿔 가며 시도해 보면 어느 것이 의미 있는 값을 내는지 알 수 있다.

비트 순서도 함께 확인

hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;   // 대부분 MSB 먼저

드물게 LSB 먼저인 장치가 있다. 값이 비트 반전된 것처럼 보이면 이것을 의심한다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 시리얼 통신 — UART/USART·SPI(CPOL/CPHA)·I2C(오픈드레인·풀업)·언제 무엇