HW 기초

AVR / 기본개념 / SPI 기초, 예제코딩

. . . 2010. 1. 11. 23:34
반응형
  • 기타사항 : ATmega128 에서 테스트완료

spi 개요.

SPI는 serial peripheral interface의 약자로서 한마디로 말해서 주변 IC와 통신하기 위한 직렬통신장치입니다. 친절하게 해석해드리면 '시리얼 방식의 주변 장치 인터페이스' 정도 된다. 특히나 MCU의 GPIO 포트가 모자르거나, 데이터를 주고받는 프로토콜에 신경 쓰기 귀찮아하는 사람에게 딱좋은 방식입니다.

가장 많이 쓰는것들은.. PLL IC나 AUDIO관련 IC등을 제어하기 위한 장치죠.

보통 CLOCK,DATA,STOBE 이렇게 3단자또는 DATA IN,OUT 을 구분하여 4단자로 구성되어 있습니다. 물론 일반 PORT를 이용해 전송할수도 있지만 전용 SPI단자의 경우는 속도가 빠르고 간편하게 사용할수 있습니다. 때로는 두개의 MCU를 연결하여 DATA를 주고 받을때도 사용하죠. 유럽이나 미국에서 생산된 IC의 경우 주로 IIC 통신을 사용하지만 일본에서 설계된 IC는 SPI로 제어하는 IC가 많습니다. ATmega128 에서의 SPI motorola에 의해 개발된 근거리용 직렬통신규격으로서 MOSI, MISO, SCK, SS 등 4개의 통신선을 이용하는 고속/동기식 직렬통신방식이다. 128에서의 SPI는 플래시 메모리에 사용자 프로그램을 다운로드 하는 ISP기능을 위해서도 사용된다.

  • MOSI : Master Out Slave In
  • MISO : Master In Slave Out
  • SCK : Serial Clock
  • SS : Slave Slect ?

마스터는 각 슬레이브 별로 독립적인 슬레이브 선택 신호(SS)를 사용하여 슬레이브를 지정한 후에 통신을 수행한다. MOSI, MISO, SCK 는 공용사용. SS1 / SS2 / SS3 이런식으로 SS를 이용해 선택한후 MOSI, MISO, SCK 로 통신 시작.

이것은 슬레이브의 수가 증가하면 회로의 복잡성도 함께 증가한다는 것을 의미하므로 슬레이브의 수가 많은 시스템에서는 SPI통신이 적합하지 않을수 있다.

SPI의 동작 방식.

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 통신 전체를 관장하는 녀석으로, 모든 데이터 전송은 Master의 관리 하에 있다고 보면 된다. 여기서 주의할점은 SPI에서 Slave는 데이터 전송마저도 마음대로 못한다는 사실이었다. SPI에서는 Master가 데이터를 전송하지 않으면 Slave에서 데이터 전송을 할 수가 없다. 다시 정리해 말하자면, SPI 통신은 두 장치의 데이터 전송이 동시에 이루어지기 때문에 데이터 송신이 바로 데이터 수신이 되며, 전송 타이밍을 결정 하는 것은 Master이다.

  • 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 통신 외에 다른 통신 방식을 찾아보는 것이 좋을 것 같다.

AVR애서의 SPI 레지스터들.

AVR에서는 SPI를 다루기 위해 다음과 같은 세 개의 레지스터를 제공한다.

  • SPCR : SPI Control Register*
  • SPSR : SPI Status Register*
  • SPDR : SPI Data Register*

SPCR(SPI Control Register)

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 - Idel High / 0 - Idel 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이 Idel Low였다면, Leading은 High가 될 때 전선을 타고 오는 데이터가 1인지 0인지를 판단한다.

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

SPSR(SPI Status Register)

SPSR은 SPI 통신의 상태를 보여주며, 수신 및 송신시에 완료등의 상태를 알수있다.

  • 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 모드에서는 일반적인 상황에서는 신경쓰지 않아도 되는 비트이다. (자세한내용은 DataSheet를 참조하시길) 

SPI2X가 아까 언급한 2배속 모드 세팅 비트이다.

SPDR(SPI Data Register)

SPDR은 금방 이해될 것이다. SPI로 주고받는 데이터가 저장되는 8Bit 레지스터이다. SPI는 1바이트 단위로 데이터 전송을 한다.

AVR 에서의 SPI 코딩

SPI 설정

-  Master모드, 4분주로 SPI를 설정하는 부분이다. 너무 간단해서 눈물이 나온다..

SPCR = 0x50;

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

송수신

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

    byte SPI_IO(byte data)
    {
        SPDR = data; /* 데이터를 보내고 */

        while(!(SPSR & 0x80)); /* 다 보내질 때 까지 기다리고 */
        data = SPDR; /* 받은 데이터를 저장한다 */

        return data;
    }

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

반응형