SPI 통신

Embeded : 2009. 4. 21. 04:01
반응형
출처 : http://garfieldfactory.tistory.com/entry/AVR에서의-SPI-통신

<AVR에서의 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의 데이터를 읽어와야 하는 경우라면, 그냥 아무 의미 없는 데이터를 전송하면 된다.


5. 기  타

덧글들...

 laputa1978  나무늘보님.. 당근이네님 블로그가따가 화가나서 들렸소

자료좀 고치시오... 화가날라하오.

while(!(SPSR&0x80)) 이거랑 while((SPSR0x80)==0x00) 이거랑 같은건지도 모르십니까? 개다가 위와같이

SPDR=data;

while(!(SPSR & 0x80)); 보내고


SPDR=0x00; 다시 더미 데이터

while(!(SPSR & 0x80)); 보내고

data=SPDR; 받아야 제대로 받아집니다.


너무 어처구니가 없습니다.. 재대로 된정보가아니면 오히려더 해가되는 정보가 될수 있다는거 명심하세요

2006/05/03 20:41 

 나무늘보  간만에 들어와보니 제 글에 답글을 남기셨네요.


죄송합니다만, 님께서야 말로 제대로 알고

글을 남기시길 바랍니다.


SPI 통신은 1:1 교환 방식입니다.

마스터가 1바이트를 송신하면서, 슬레이브로 바로 1바이트를

송신합니다.

다시 말해서 1바이트를 서로 교환합니다.


그렇기 때문에 SPDR에 바로 수신된 데이터가 들어옵니다.


그러나 데이터를 수신한다고 해서 바로 처리할 수는 없기

때문에, 처리를 할 시간이 주어져야 합니다.


그 처리 시간을 기다리기 위해서 더미 데이터를 지속적으로 보내는 것입니다. 더미 데이터를 보내는 것은 1:1교환이기 때문에 슬레이브가 응답을 할 기회를 주는 것이지요.


공부 좀 더 하고 오시기 바랍니다. 예의범절도 없이 대드는데

웃기지도 않네요.. 2006/05/04 01:14 

 tmcsjkim  공부하라고 일부러 틀리게 써줄수도 있지요..삽질을 해야 땀의 의미를 이해할수 있는데염.. 아뭇튼 감사.. 잘 정리되어 있네요.. 2006/05/04 19:29 

 laputa1978  우선... 무례하게 글올린거부터 사과드리구요..

제가말씀드린건... 이론상 1바이트가 송신되자마자 1바이트가 수신되는건

님말씀이 맞습니다.

제가 말씀드린부분은 명령..

즉 마스터에서 커맨드명령으로 위와같이 데이터를 송신했다면

나무늘보님말씀 대로라면 곧바로 SPDR에 이에해당하는 데이터가

송신된다는것인데 그렇지 않습니다.

명령을받고... 이에해당하는 데이타를 수신하기 위해서..

클럭을 계속해서 마스터에서 뿌려주어야 한다는 것이지요

되도 않한 테클이라고 생각하지마시고 한번... 쯤 생각해보세요..

그리고나서야 제대로된 데이터가 수신됩니다.

.. 그러니까 제가 말씀드린건

님의 말씀은 이론상이고 실제 구현상에서는 꼭그렇게만 이루지는건

아니라는겁니다.

실제 제가 상태 레지스터를 읽어오는 함수를 구현하면서

알게된것이구요 저도 무지에서 이리저리 자료를 구하고 책을 보다

님말씀을 보게되었고 실제 그렇게 구현했더니 되지 않더라는것입니다

즉...

SPDR=CMD; // opcode (상태레지스터 읽어오는명령

while(!(SPSR & 0x80)); 보내고

data=SPDR;

이리하였더니 아무런 값이 오질 않았습니다.

명령을 보내고... 다시 받기 위해선

클럭을 계속해서 발생해주어야 한다는 의미죠

물론.. 1:1통신이기에 데이터를 송신하자마자 슬레이브의 수신버터의

데이타가 마스터의 송신버퍼쪽으로 넘어오는것은 맞지만 실질적인 환경은

제가 말씀드린바와 같다는 뜻이입니다. 2006/05/08 09:55 

 나무늘보  아직도 이해를 못하신 겁니다. 그것은 SPI 통신을 사용하면서 일어나는 당연한 현상이고, 데이터시트에서도 말하고 있는 부분입니다.


마스터에서 명령어 0x09를 송신하였다고 가정합시다. 그러면 슬레이브에서도 동시에 무언가를 송신하는데, 이것은 명령어 0x09에 대한 응답은 될 수가 없습니다. 방금 수신받았으니깐 슬레이브는 명령어 0x09를 처리할 시간이 없습니다.


슬레이브의 데이터시트에는 명령어당 처리 시간이 클럭 단위로 정해져 있습니다. 0x09 명령어의 경우, 최소 100CLK 이 필요하다고 되어 있고, 슬레이브 장치가 1Mhz라면, 적어도 0.1초는 기다려줘야 슬레이브에서 응답을 할 수 있는 것입니다.


SPI 통신은, 마스터가 데이터를 전송함으로서 SCLK로 전송 클럭을 발생시켜줘야 슬레이브에서 응답할 수 있습니다. 때문에 명령어 이후에도 추가로 더미 데이터를 보내는 것이고, 슬레이브 역시 이 동안 명령어를 처리중이라면 정해진 규칙에 따라 응답합니다.


구현에서 그렇게 이루어지지 않는 것이 아니라, SPI 통신 자체가 원래 그렇게 사용하는 겁니다. 위에서도 언급한 내용이고, 제시한 함수 예제는 단순히 1바이트 송수신입니다. 아까 맨 처음에 명령어를 송신할 때 받은 슬레이브의 1바이트는 의미 없는 데이터라고 생각하면 됩니다. 슬레이브의 입장에서도 일단 더미 데이터를 보내야 명령어를 받을 수 있는 셈이지요.


데이터시트를 읽어보면 다 나오는 내용입니다. 저라고 뭐 별거 있겠나요..데이터 시트를 다 해석해보고 테스트해 본 겁니다. 다시 공부하세요. 2006/05/11 08:45 

 나무늘보  뭐 그래도 열심히 하시는거 같아서 좋네요. 아무래도 제가 문서 설명을 부족하게 한것 같습니다. 덕분에 좀 더 보충이 필요하다는 것을 알았습니다. :) 2006/05/11 08:48 


------------------------------------------------

 

나무 늘보님 블로그에서 퍼왔습니다... 퍼오기 금지 / 오른쪽 금지를 해놓으셔서... 보고...

모두 타이핑했다는... 헥헥~~!!!

[출처] AVR에서의 SPI 통신|작성자 얌이

반응형
Posted by Real_G