SPI

김준혁·2일 전

1. SPI 통신이란?

SPI는 모토로라에서 제안한 동기식(Synchronous), 전이중(Full-Duplex)(데이터 송신과 수신이 동시에 이루어짐) 방식의 직렬 통신입니다. 주로 MCU와 센서, 메모리(Flash), 디스플레이 간의 고속 데이터 전송에 사용됩니다. I2C에 비해 통신 속도가 매우 빠르다. 1:N 통신이 가능하다=하나의 마스터에 여러 개의 슬레이브를 연결할 수 있다.

핀 구성 (4-Wire)

  • SCLK (Serial Clock): 통신 속도를 결정하는 클럭 (Master가 생성).
  • MOSI (Master Out Slave In): 마스터에서 슬레이브로 데이터 전송.
  • MISO (Master In Slave Out): 슬레이브에서 마스터로 데이터 전송.
  • CS/SS (Slave Select): 통신할 슬레이브를 선택 (보통 Active Low).

2. 핵심 파라미터: CPOL과 CPHA

SPI를 처음 연결할 때 가장 많이 하는 실수가 바로 SPI Mode 설정입니다. 데이터시트의 Timing Diagram을 보고 아래 4가지 모드 중 하나를 선택해야 합니다.

ModeCPOL (Polarity)CPHA (Phase)설명
000Idle 시 클럭 Low, 첫 번째 엣지에서 샘플링
101Idle 시 클럭 Low, 두 번째 엣지에서 샘플링
210Idle 시 클럭 High, 첫 번째 엣지에서 샘플링
311Idle 시 클럭 High, 두 번째 엣지에서 샘플링

3. ATmega328P SPI 주요 레지스터 정리

AVR 아키텍처에서 SPI를 제어하려면 크게 3가지 레지스터(SPCR, SPSR, SPDR)만 이해하면 됩니다.

1) SPCR (SPI Control Register)

SPI의 동작 모드와 설정을 담당하는 가장 중요한 레지스터입니다.

BitNameDescription
7SPIESPI Interrupt Enable: 1로 설정 시 전송 완료 인터뷰트 활성화
6SPESPI Enable: 1로 설정 시 SPI 모듈 활성화
5DORDData Order: 1이면 LSB First, 0이면 MSB First
4MSTRMaster/Slave Select: 1이면 Master 모드, 0이면 Slave 모드
3CPOLClock Polarity: 1이면 Idle 시 High, 0이면 Low
2CPHAClock Phase: 데이터 샘플링 시점 결정 (Mode 설정)
1:0SPR1:0SPI Clock Rate: 분주비 설정 (SCK 속도 결정)

2) SPSR (SPI Status Register)

현재 통신 상태를 확인하거나 속도를 배속하는 데 사용합니다.

  • Bit 7 - SPIF (SPI Interrupt Flag): 데이터 전송이 완료되면 1이 됩니다. SPDR 레지스터를 읽거나 인터럽트가 실행되면 자동으로 0이 됩니다.
  • Bit 6 - WCOL (Write Collision Flag): 전송 중에 SPDR에 데이터를 쓰려고 하면 발생합니다.
  • Bit 0 - SPI2X (Double SPI Speed Bit): 1로 설정하면 SPI 속도가 2배 빨라집니다.

3) SPDR (SPI Data Register)

실제 데이터를 주고받는 통로입니다.

  • 쓰기: 이 레지스터에 값을 넣으면 즉시 전송이 시작됩니다 (Master 모드일 때).
  • 읽기: 전송이 완료된 후 이 레지스터를 읽으면 수신된 데이터를 얻을 수 있습니다.

4. 표준 SPI 통신 시퀀스 (Standard Sequence)

SPI 통신이 시작되고 끝날 때까지 하드웨어 내부에서 일어나는 논리적 순서입니다. 개발자는 이 타이밍을 이해해야 정확한 드라이버 코드를 작성할 수 있습니다.

단계별 동작 과정

  1. Slave 선택 (SS/CS Assert)

    • Master가 통신하고자 하는 특정 Slave의 SS(Slave Select) 핀을 Low(0)로 떨어뜨립니다.
    • 이때부터 해당 Slave는 활성화되어 Master의 클럭에 반응할 준비를 합니다.
  2. 클럭 생성 (SCLK Generation)

    • Master가 설정된 보드레이트(Baud Rate)에 맞춰 SCLK 신호를 출력하기 시작합니다.
    • CPOL 설정에 따라 클럭의 시작 레벨(High or Low)이 결정됩니다.
  3. 데이터 교환 (Data Shift-out/in)

    • MOSI: Master는 출력할 비트를 MOSI 라인에 싣습니다.
    • MISO: Slave는 응답 비트를 MISO 라인에 싣습니다.
    • CPHA 설정에 따라 클럭의 첫 번째 또는 두 번째 엣지에서 데이터를 샘플링(읽기)합니다.
    • 보통 8비트(1바이트) 단위로 이 과정이 8번 반복됩니다.
  4. 전송 완료 플래그 (Interrupt Flag)

    • 8비트 전송이 완료되면 MCU 내부의 SPIF(SPI Interrupt Flag)가 1로 세팅됩니다.
    • 인터럽트가 설정되어 있다면 ISR(Interrupt Service Routine)이 실행됩니다.
  5. Slave 해제 (SS/CS De-assert)

    • 데이터 전송이 모두 끝나면 Master는 SS 핀을 다시 High(1)로 올립니다.
    • Slave는 비활성 상태로 돌아가며 MISO 라인을 High-Z(플로팅) 상태로 만듭니다.

⚠️ 시퀀스 제어 시 주의사항

  • Dummy Byte: SPI는 송신과 수신이 동시에 일어납니다. 슬레이브로부터 데이터를 읽기만 하고 싶을 때도, 마스터는 반드시 의미 없는 데이터(0xFF 등)를 송신하여 클럭을 생성해주어야 합니다.
  • CS 딜레이: 아주 빠른 MCU를 사용할 경우, CS를 Low로 내린 직후 너무 빨리 데이터를 보내면 슬레이브가 준비되지 않아 첫 비트가 깨질 수 있습니다. 필요시 아주 짧은 지연 시간(Software Delay)을 주어야 합니다.

profile
임베디드

0개의 댓글