본문 바로가기

Programming/General

SPI interface

이글은 가필드 님이 작성하신 글입니다.
좋은 내용을 보존 및 확산 하기 위해서 부득이 하게 원문을 그대로 퍼 왔음을 양해해 주시기 바랍니다.

원문출처 : http://garfieldfactory.tistory.com/

 



 

SPI 란?

1. SPI란?

SPI는 Serial Peripheral interface의 약자로, 친절하게 해석해 드리면 “시리얼 방식의 주변 장치 인터페이스”정도 되시겠다. SPI 통신은 달랑 전선 3개로만 통신하는 간단하고도 쓸모가 많은 통신방식이다. 특히나 MCU의 GPIO 포트가 모자르거나, 데이터를 주고받는 프로토콜에 신경 쓰기 귀찮아하는 필자같은 게으름뱅이한테 딱 좋은 방식이라고 하겠다.


2. SPI의 동작 방식

자료구조에서 Circular Queue라고 아시는가? “환형 큐”라고 하는 것으로, 큐의 앞이랑 튀가 붙어 고리를 이루어 버린 구조를 말한다. 자세한건 자료구조를 찾아보라.

이걸 갑자기 꺼낸 이유는, 바로 이 SPI가 환형 큐의 형태를 가지고 있기 때문이다. 그림을 그려 확인해보자.

↓←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←↑

[7][6][5][4][3][2][1][0] →→→→→→→→→→→→→[7][6][5][4][3][2][1][0]

대강 이런 구조가 된다. 왼쪽 장치의 0번 비트부터 차례대로 오른쪽 장치로 전송이 되면, 오른쪽 장치는 반대로 왼쪽에 0번 비트부터 전송하는 것이다. 비트를 하나씩 오른쪽으로 밀어내는 것이라고 생각하면 되겠다. 저 화살표가 의미하는 것은 두 장치간의 데이터 전송 경로이다.

그럼 이제 이걸 어떻게 컨트롤 하는지 확인해 보자. SPI는 Socket 통신의 Server/Client 모델과 유사하게 Master/Slave 모델을 사용한다. Master는 SPI 통신 전체를 관장하는 녀석으로, SPI에서는 이녀석이 짱이다! 웃자고 한 말이 아니라 정말 그러하다. 모든 데이터 전송은 Master의 관리하에 있다고 보면된다.

SPI에서 Slave는 데이터 전송마저도 마음대로 못한다는 사실이다. SPI에서는 Master가 데이터를 전송하지 않으면 Slave에서 데이터 전송을 할 수가 없다. 다시 정리해 말하자면, SPI 통신은 두 장치의 데이터 전송이 동시에 이루어지기 때문에 데이터 송신이 바로 데이터 수신이 되며, 전송 타이밍을 결정하는 것은 마스터이다.


자, 그럼 이제 좀 더 하드웨어적인 얘기를 해보자. 아까 말하길, 선을 세가닥을 쓴다고 했는데 바로 MOSI/MISO/SCK이다.

MOSI : Master Out Slave In

MISO : Master In Slave Out

SCK : Serial Clock


위에서 나온 두가닥의 화살표가 MOSI와 MISO인건 눈치챘을 것이다. SCK는 데이터 전송을 하는 타이밍을 Master에서 Slave로 알려주는데 사용한다.

그러나 사실, SPI 통신은 몇가닥이 더 필요하다. 왜?


SPI 통신에서, Master는 무조건 하나여야 한다. 그러나 Slave는 여러 대가 될수도 있는데, 이런 경우 각 Slave를 구분하기 위한 방법이 몇 가지 있다.

(1) Slave 마다 CS(Chip Select) 선을 추가로 사용한다.

- 가장 대표적으로 쓰이는 방식이다. SPI 통신을 이용하는 외부 장치들은 대개 이 방법을 쓴다. 장치의 개수가 늘어나면 신호선이 늘어난다는 문제점이 있다.

(2) Slave 마다 SID(Slave ID)를 부여한다.

- SPI를 사용한 통신 Protocol이 정해져 있는 경우에만 사용할 수 있는 방식이다. Slave ID를 Broadcast하여, 그에 맞는 Slave만 응답하도록 한다.

(3) Demultiplexer(분배기)를 사용한다.

- 다수의 Slave 장치가 연결될 경우에 유용하게 사용될 수 있는 방식이다. 장치의 개수에 상관없이 미리 정해진 하드웨어만을 필요로 한다.

위의 세가지 방법 이외에도 다른 해결책이 있을 것이나, 이 세 가지가 가장 많이 쓰인다. 그러나 이들 중에도 (1)의 방법 이외의 사용은 매우 드물다.

그러나 무엇보다도 SPI는 장치의 수가 적을 때 유용한 통신방식이라는 것이다. 장치의 수가 늘게되면 추가적인 부담이 늘어나게 된다. 만약 장치의 개수가 8개가 넘어간다면 SPI 통신 이외에 다른 통신 방식을 찾아 보는 것이 좋을 것이다.


3. SPI 레지스터들

AVR에서는 SPI를 다루기 위해 세 개의 레지스터를 제공한다. SPCR/SPSR/SPDR 이다.


SPCR : SPI Control Register

SPSR : SPI Status Register

SPDR : SPI Data Register


이 중에서 SPDR은 금방 이해될 것이다. SPI로 주고받는 데이터가 저장되는 8bit 레지스터이다. 위에서 그린 그림을 떠올려보자. 거기에 그려진 8개의 칸이 바로 SPDR을 의미하는 것이다. SPI는 1바이트 단위로 데이터 전송을 한다.


SPCR은 SPI를 사용하기 위한 각종 설정을 관리하는 레지스터이다. 각 비트는 다음과 같은 쓰임새를 가지고 있다.

Bit7 : SPIE(SPI Interrupt Enable) - SPI에 인터럽트 사용 여부(1 - 사용 / 0 - 미사용)

Bit6 : SPE(SPI Enable) - SPI 사용 여부(1 - 사용 / 0 - 미사용)

Bit5 : DORD(Data Order) - 데이터 전송 순서(1 - LSB/0 - MSB)

Bit4 : MSTR(Master) - Master/Slave 여부(1 - Master / 0 - Slave)

Bit3 : CPOL(Clock Polarity) - Clock의 형태(1 - Idle High / 0 - Idle Low)

Bit2 : CPHA(Clock Phase) - 데이터 읽기 시점(1 - Trailing / 0 - Leading)

Bit1 : SPR1(SPI Clock Rate 1) - Clock의 속도

Bit0 : SPR0(SPI Clock Rate 0) - Clock의 속도(00 - 4분주/01 - 16분주/10 - 64분주/11 - 128분주)


LSB와 MSB는 최하위 비트와 최상위 비트를 의미한다. LSB가 0번 비트라고 생각하면 헛갈리지 않고 쉽게 기억할 수 있다.

Clock의 형태는 평상시에 Clock이 High인지 Low인지를 의미하는 것인데, 보통은 Low 상태다. 데이터 읽기 시점은, Clock이 어떤 상태일 때 데이터를 읽는지를 얘기하는 것이다. 만약 평상시 Clock이 idle Low였다면, Reading은 High가 될 때 전선을 타고 오는 데이터가 1인지 0인지를 판단한다.

SPR 비트는 SPI의 속도를 결정하는 것인데, Master의 장치 Clock의 몇분의 몇인지를 뜻한다. SPI 통신은 1/4이하일 때만 올바른 전송을 보장한다. 예를 들어 16Mhz의 클럭을 사용하는 MCU라면, SPI 통신은 최대 4Mhz까지 가능하다는 말이다. 더 높은 속도가 필요하다면 2배속 모드 세팅을 해서 쓰면 되는데, 이렇게 되면 8Mhz까지 가능해지는 셈이다. 단, 이것은 Master로 사용할 때에만 해당하는 것으로, 연결되어 있는 Slave는 Master의 1/2 속도를 지원해야 한다. 다시 말해서, Slave가 Mater 보다 2배 이상 빠른 SPI 통신이 가능한 경우에 2배속 모드를 사용한다. 2배속 모드 세팅 비트는 SPSR에 있다.

SPSR은 다음과 같은 비트 구조를 가지고 있다.


Bit7 : SPIF(SPI Interrupt Flag) - 데이터 전송 완료 여부(1 - 완료 / 0 - 전송안함 또는 미완료)

Bit6 : WCOL(Write Collision Flag) - 데이터 전송 충돌 여부(1 - 전송중 / 0 - 전송안함)

Bit5 : 예약공간

Bit4 : 예약공간

Bit3 : 예약공간

Bit2 : 예약공간

Bit1 : 예약공간

Bit0 : SPI2X(SPI Double Speed Mode) - 2배속 모드(1 - 2배속 / 0 - 기본)

SPIF는 데이터 전송이 완료되었을 때 1로 세팅되고, SPSR을 읽을 때 0으로 바뀐다. 따라서 SPDR에 데이터를 넣어주고 나서 SPIF가 1이 될 때 까지 기다리면 데이터 전송이 완료되는 것이다.


WCOL는 Master 모드에서는 신경쓰지 않아도 되는 비트이다.


SPI2X가 위에서 언급한 2배속 모드 세팅 비트이다.


4. 소스코드

Master 모드, 4분주로 SPI를 설정하는 부분이다.


SPRC = 0x50;


위처럼 하는 순간, SPI가 시작된다.


다음은 SPI 데이터 송수신 함수이다.


byte SPI_IO(byte data)

{

        SPDR = data; // 데이터를 보낸다.

        

        while(!(SPSR & 0x80)); // 데이터를 모두 전송할 때 까지 대기한다.

        data = SPDR; // 받은 데이터를 저장한다.


        return data;

}


Slave의 데이터를 읽어와야 하는 경우라면, 그냥 아무 의미 없는 데이터를 전송하면 된다.