1. 핀 정보
SPI 통신은 [그림1]처럼 기본적으로 4개의 선을 사용한다.
1) 데이터 선
SPI 통신은 데이터를 주고 받는 선과 Clock선, 이 두 가닥은 반드시 있어야 한다. 이때 데이터를 주고 받는 선을 한 선을 이용하냐 두 선을 이용하냐에 따라 차이점이 있다. [그림2]처럼 한 선을 이용할 때는 A가 말하고 있으면 전기적 전압이 가고, Clock도 같이 보낸다. 이때 B도 같이 말한다면 전기적 전압이 충돌하여 한 선에서 신호가 망가진다. 따라서 A가 데이터 선으로 전압을 내보낼 때 B는 말하면 안 된다. 결론적으로 한 선을 이용하려면 서로 이야기하는 순서를 지켜서 이야기해야 하는데 이러한 방식을 반이중방식이라 한다.
반이중방식과 달리 [그림3]처럼 A와 B가 말하는 선이 따로 있어 신호가 망가지는 경우가 없는 방식을 전이중방식이라고 한다. SPI 통신은 반이중방식과 전이중방식 둘 다 사용 가능하지만 기본적으로 전이중방식이다.
2) Clock 선
SPI 통신은 데이터를 주고 받는데 전압 차이를 이용한다. [그림4]처럼 전압이 올라가면 1, 내려가면 0이다.
하지만 문제는 [그림5]처럼 1을 연속으로 보낼 때 전압만으로는 ①번인지 ②번인지 알 수 없다. 따라서 구분 점이 필요하다.
구분하는 방법은 두 가지가 있는데 첫 번째로 time base이다. 대표적인 예로 BPS(RS-485, RS-232에서 주로 사용)가 있는데 시간을 쪼개서 서로 약속을 하는 것이다.
데이터를 쭉 보내주면 이것을 [그림6]처럼 서로 약속한 시간으로 쪼개는데 만약 BPS가 9600이면 1초를 9600으로 나눈다. 그러면 타임의 간격들이 있는데 7개의 간격 동안 쭉 High를 유지했다면 1111111이 되는 것이다.
두 번째는 Clock을 이용하는 방법이다. Clock이라는 별도의 선을 하나 이용하여 [그림7]처럼 Clock 주기 동안 신호가 어디를 유지하고 있었느냐를 보는 방법이다.
예를 들어 [그림8]은 Clock 한 주기 동안 신호가 High를 유지하고 있으므로 1로 본다. 이처럼 중요한 것은 Clock을 기준으로 신호가 High인지 Low인지를 구분할 수 있다는 것이다. 그리고 SPI통신은 이러한 Clock을 이용한다.
하지만 Clock 한 주기 동안 신호가 애매한 경우가 있다. [그림9]는 그 경우를 나타낸 것이다. 앞의 두 주기 동안 신호는 1로 명확하나 마지막 신호는 알 수 없다. 따라서 이를 구분하기 위해 Clock 극성과 위상을 사용한다.
※ SPI Modes(Clock 극성 및 위상)
SPI 통신의 Master와 Slave는 Master의 출력인 Clock에 맞추어 동기화된다. 그런데 Clock에 동기를 맞추는 시나리오는 한가지만 있는 것이 아니다. Clock의 기본 값이 0일 수도 있고, 1일 수도 있다. 그리고 Master와 Slave가 데이터를 읽어오는 Edge도 다를 수 있다.
Clock의 기본 상태를 설정하는 속성을 Clock 극성(CPOL, Clock POLarity)이라고 한다. 만일, CPOL이 Low(0)이면 Clock의 기본 값이 0이고, High(1)이면 Clock의 기본 값이 1이다.
Clock이 어떤 Edge에서 데이터를 전송할지를 설정하는 속성을 Clock 위상(CPHA, Clock PHAse)이라고 한다. CPHA는 Clock의 동작위치에 따른 데이터 적용으로 Clock이 첫 번째에서 동작하게 할지, 두 번째에서 동작하게 할지를 의미한다. Low(0)이면 첫 번째에서 동작, High(1)이면 두 번째에서 동작한다.
결론적으로 SPI 통신에서의 신호 동기화는 Clock의 극성과 위상에 따라 4가지 유형을 가진다.
SPI Mode | Clock 극성(CPOL) | Clock 위상(CPHA) |
Mode1 | 0 | 0 |
Mode2 | 0 | 1 |
Mode3 | 1 | 0 |
Mode4 | 1 | 1 |
- Mode 1(CPOL = 0, CPHA = 0)
Clock의 기본 상태가 Low(0)이며, 데이터 전송이 Clock의 상승 Edge(Low->High)에서 발생한다.
- Mode 2(CPOL = 0, CPHA = 1)
Clock의 기본 상태가 Low(0)이며, 데이터 전송이 Clock의 하강 Edge(High->Low)에서 발생한다.
- Mode 3(CPOL = 1, CPHA = 0)
Clock의 기본 상태가 High(1)이며, 데이터 전송이 Clock의 하강 Edge(High->Low)에서 발생한다.
- Mode 4(CPOL = 1, CPHA = 1)
Clock의 기본 상태가 High(1)이며, 데이터 전송이 Clock의 상승 Edge(Low->High)에서 발생한다.
3) CS 선
CS 선은 아래의 문제를 해결하기 위해 존재한다.
[그림11]을 보면 A에서 데이터를 보내면 전압이 B, C, D에 똑같이 들어온다. 따라서 누구에게 데이터를 전달하는지 알 수 없다.
[그림11]에서의 문제는 마스터가 말하는 건지는 알겠는데 누구에게 말하는지 모르는 것이었다. 따라서 그 해결책으로 [그림12]처럼 SPI 통신은 CS(Chip Select)선을 독자적으로 사용하는데 이 선은 한꺼번에 사용할 수 없다. CS선은 평상시에는 전압이 High로 있다가 B에게 말하고 싶다고 하면 B와 연결된 CS선의 전압을 Low로 낮춘다. 그러면 B가 자신에게 말하고 있다는 것을 알고 마스터가 말하는 것을 듣는다. 만약 B와 C에 연결된 CS선의 전압을 동시에 Low로 만든다면 B와 C는 마스터가 말하는 것을 동시에 듣게 된다.
※ 누가 데이터를 보내는지도 명확히 알 수 없는 문제와 해결
[그림13]을 보면 A가 데이터를 보내는지도 명확히 알 수 없다. B입장에서는 1번 전기 도선이 깔려있는 것이다. 우리가 1번 선을 A가 말하는 전용선이라고 정했기 때문에 1번 선을 통해 데이터가 오면 A가 데이터를 보내는지 알 수 있었다. 그런데 만약 D도 이 선을 통해서 데이터를 보낸다고 하면 B입장에서는 A와 D중 누가 데이터를 보내는 것인지 구분할 수 없다.
[그림13]에서의 문제는 누가 말하는지 모르는 것이었다. 그래서 SPI 통신은 Master와 Slave 관계를 정한다. 그래서 SPI 통신하는 기계를 만든다면 Master 또는 Slave 전용으로 기계를 만든다. 만약 Slave 전용 기계라면 말하는 권한이 없고 무조건 듣고 응답하는 것만 할 수 있다.
결론적으로 [그림14]처럼 A가 Master라면 주인이 되는 것이다. B, C입장에서는 A가 데이터를 보내는지 알 수 없지만 누군가 데이터를 보낸다면 주인으로 인식하여 동작하는 것이다. 즉, SPI 통신은 1:N 통신이 가능한데 1은 반드시 Master이다.
4) SPI 핀 설명
I2C통신에서는 데이터를 전송하는 SDA(Serial Data)선과 Clock을 전송하는 SCL(Serial Clock)선 두 개만 필요하다. 하지만 SPI통신에서는 송신과 수신을 위한 MOSI(Master Out Slave IN)선과 MISO(Master In Slave Out)선, Clock(SCLK)선, SS(Slave Select)선 이렇게 4개가 필요하다.
MOSI(Master Out Slave IN): Master에서 나와서 Slave에게 가는 데이터를 전송하는 선이다.
MISO(Master In Slave Out): Slave에게 나와서 Master에게 가는 데이터를 전송하는 선이다.
※ I2C통신이 전이중통신이 안됐다면 SPI는 선이 구분되어 있기 때문에 송수신이 동시에 가능하다. 다만 SPI통신은 Master-Slave관계(주인-종)처럼 Slave는 Master에게 통신을 마음대로 하지 못한다. SPI의 데이터 송수신은 동시에 이루어지기 때문에 데이터 송신이 곧 수신이 된다. 이 데이터 송수신의 타이밍을 결정짓는 것은 Master장치이다.
SCLK, CLK(Clock): 동기화 신호를 위한 Clock 선이다.
SS, CS(Slave Select, Chip Select): Master장치가 여러 개의 Slave 장치와 통신할 때 하나를 선택하여 통신을 하는데 그 때 선택을 하는 역할의 신호 선이다. 한마디로 어디로 보낼지 결정하는 신호 선이다.
2. 동작구조
[그림15]처럼 SPI 장치들은 Shift Register를 가지고 있고, Shift Register에 의해 데이터가 이동된다.
[그림16]처럼 기본적으로 MSB부터 전송되는데 특정 컨트롤러는 LSB부터 전송을 수행시키는 방법도 지원한다. Master에서 어떤 값을 Slave로 보낸다고 가정했을 때, 보내는 1Clock의 신호마다 1bit의 data가 이동된다.
[그림17]처럼 밀어내기 식으로 data가 들어간다고 생각하면 된다. 여기서 Slave에 들어있던 쓰레기 값이 Master로 넘어왔을 때, 이 값이 만약 필요한 값이라면 마스터에서 받아서 처리하면 되지만 그렇지 않다면 그냥 버리면 된다. SPI는 이렇게 송수신이 한번에 이루어지는 간단한 통신방식을 가지고 있다.
<참고>
https://hanbulkr.tistory.com/5
https://m.blog.naver.com/cjsksk3113/222303465870
https://www.youtube.com/watch?v=srHAjFKXXk8