C++에서 SPI Peripheral 사용하기

SPI(Serial Peripheral Interface)는 임베디드 시스템에서 센서, 외부 메모리, 디스플레이 등 다양한 장치와 고속 통신을 하기 위해 널리 사용되는 인터페이스입니다.
UART와 달리 마스터/슬레이브 구조를 가지고, 클럭 신호를 포함한 4선(SCLK, MOSI, MISO, CS)을 통해 동작합니다.

이번 단계에서는 SPI를 클래스 기반 구조로 설계하는 방법을 다룹니다.
UART와 달리 SPI는 장치마다 프로토콜이 달라 공통 확장 클래스를 두기보다, BaseSPI를 상속받아 개별 장치 전용 클래스를 작성하는 방식이 일반적입니다.


BaseSPI: 기본 클래스

BaseSPI는 SPI 통신을 위한 공통 기반을 제공합니다. 주요 기능은 다음과 같습니다.

  • 송수신 함수
    단일 바이트 및 멀티 바이트 전송 함수 제공
  • 통신 설정(Properties)
    클럭 속도(Prescaler), 클럭 극성/위상(CPOL/CPHA), 비트 순서(MSB/LSB), 데이터 길이 등
  • 칩 선택 제어 (CS)
    슬레이브 장치와 통신하기 위한 Chip Select 핀 제어

이 클래스는 공통적인 SPI 동작만을 담당하며, 실제 장치별 프로토콜 처리는 별도 확장 클래스에서 수행합니다.


장치별 확장 클래스

SPI 장치들은 프로토콜이 제각각입니다. 예를 들어:

  • AT25 계열 EEPROM → 쓰기/읽기 명령어 세트 필요
  • 외부 ADC/DAC → 샘플링 시작/정지 명령, 레지스터 접근 방식
  • 디스플레이 컨트롤러(예: ST7735, ILI9341) → 명령어 전송과 데이터 전송 구분 필요

따라서 BaseSPI를 상속받아 장치별 전용 클래스를 구현하는 것이 가장 효율적입니다.

각 장치 클래스는 BaseSPI의 전송 함수를 활용하여 자신만의 명령어 집합과 프로토콜을 구현합니다.


코드 예제

예제 1 – SPI 기반 EEPROM 클래스

  1. 헤더 포함 및 객체 선언
#include "BaseSPI.h"

BaseSPI tmpSPI;

트러블슈팅 & 팁

  1. 데이터 꼬임 발생
    • 원인: 클럭 극성(CPOL) / 위상(CPHA) 불일치
    • 해결: 데이터시트에 맞게 SPI 모드(Mode0~3) 설정
  2. 슬레이브 응답 없음
    • 원인: CS 핀 제어 누락
    • 해결: 장치 접근 전후에 CS Low/High 제어 확인
  3. 속도 문제
    • 원인: Prescaler 설정이 너무 낮거나 높음
    • 해결: 장치 사양에 맞는 SPI 클럭으로 조정
  4. 프로토콜 호환성 문제
    • 원인: 장치별 명령어/데이터 전송 순서 차이
    • 해결: 장치 전용 클래스를 작성하여 프로토콜 반영

마치며

이번 단계에서는 SPI를 클래스 기반으로 사용하는 구조를 소개했습니다.

  • BaseSPI: 공통 기능(전송/수신, CS 제어, 설정 관리) 제공
  • 장치별 확장 클래스: EEPROM, 센서, 디스플레이 등 프로토콜에 맞춘 구현
  • 애플리케이션은 장치 클래스의 API를 사용 → SPI 내부 동작을 신경 쓸 필요 없음

다음 단계에서는 SPI 기반 장치 중 하나를 선정하여, 실제 데이터 전송/수신 흐름을 예제로 다루겠습니다.


0개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

ko_KRKorean