이 문서는 시리얼, I2C, SPI 각각의 문서로 나뉘어진 문서 중 하나입니다. 시리즈 순서대로 읽으시길 권합니다.
.
I2C 통신 개요
I2C (Inter-Integrated Circuit, 또는 TWI – Two Wire Interface) 는 복수개의 슬레이브 장치가 복수개의 마스터 장치와 통신하기 위한 프로토콜입니다. 앞서 살펴본 SPI 와 마찬가지로 하나의 완성품을 구성하는 요소들 간의 근거리 통신을 위해 고안되었습니다.
시리얼 통신에서 살펴보았다시피 비동기식 시리얼 통신(이하 UART)은 클럭을 맞춰줘야 하고 데이터 라인으로 들어오는 신호를 항상 주시해야 하기 때문에 오버헤드가 있으며 하드웨어가 복잡해지는 단점이 있습니다. 결정적으로 UART 통신은 1:1 통신만 가능합니다.
반면 동기식 시리얼 통신인 SPI 는 클럭(CLK) 라인을 이용해 데이터 라인을 동기화 하므로 하드웨어 구조도 간단하고 1:N 통신이 가능합니다. 송신용 핀과 수신용 핀이 분리되어 있고, full-duplex(동시 송수신) 연결을 이용해 10만 비트의 전송 속도를 지원하기도 합니다. 하지만 SPI 통신은 통신에 필요한 핀이 많아지는 단점이 있습니다. 하나의 장치를 연결하는데 4개의 라인 (CLK, MOSI, MISO, SS)이 필요하고, 추가로 장치를 더할 때마다 라인이 하나씩 추가됩니다. 그리고 N:N 통신은 할 수 없습니다.
I2C 통신은 SPI 통신의 이런 단점들을 보완할 수 있는 동기식(synchronous) 시리얼 통신 방법입니다. UART 통신처럼 단 두 라인만 사용하고 1008 개의 슬레이브 장치를 지원합니다. 또한 N:N 통신도 지원이 가능합니다. (단 마스터 장치끼리 통신은 불가) 하드웨어 요구사항이 SPI 보다 복잡하긴 하지만 UART 통신보다는 간단합니다. 통신 속도면에서도 SPI 와 UART 통신의 중간쯤 됩니다.(10kHz/40kHz)
I2C 하드웨어
I2C 통신은 두 개의 라인 – SCL, SDA 를 사용합니다.
SCL 은 SPI 의 CLK 처럼 클럭 신호를 생성해서 전달하는 역할을 하고 SDA 는 실제 데이터가 전달되는 라인입니다. 클럭 신호는 반드시 마스터 장치가 생성하는데 슬레이브 장치가 데이터 전송을 지연하기 위해 클럭 신호를 만드는 경우도 있습니다. 이것을 clock stretching 이라고 합니다.
I2C 통신은 UART/SPI 통신과는 달리 I2C 하드웨어(bus driver) 장치가 “open drain” 속성을 가진다는 점입니다. 이 말은 I2C 통신을 사용하는 장치 하나가 데이터 전송을 위해 라인에 LOW 신호를 넣고 있으면 다른 장치들은 이걸 강제로 HIGH로 바꿀 수 없다는 의미입니다. I2C 통신의 두 라인 SDA, SCL 은 모두 풀업 저항(pull-up resistor)에 연결되어 있으므로 통신라인이 사용이 끝나면 자동으로 HIGH 상태로 복귀됩니다.
또한 풀업 저항은 동작 전압이 다른 장치들이 연결되어 통신하는데 발생하는 문제점들을 없애줍니다. 풀업 저항이 두 장치가 사용하는 전압보다 낮은 레벨로 유지시켜주기 때문에 별도의 level-shifting 회로가 필요치 않습니다. (두 장치의 전압차가 큰 경우는 I2C level shifter 가 필요함)
프로토콜
I2C 통신의 데이터 구조는 UART/SPI 보다 복잡합니다. UART/SPI 에서 문제가 되는 부분들을 소프트웨어적으로 처리하기 때문입니다.
기본 구조
I2C가 전송하는 메시지는 2개의 프레임 – 주소(address) 프레임과 데이터(data) 프레임으로 구분할 수 있습니다. 주소 프레임은 마스터가 전송하는 데이터가 어떤 슬레이브로 가는지 알려주기 위한 프레임입니다. 데이터 프레임은 실제 전송하려는 데이터가 담긴 프레임입니다.
통신 시작 조건
데이터 통신을 시작하기 위해서는 주소 프레임부터 전송해야 합니다. 이를 위해 마스터 장치는 SCL(클럭) 라인을 HIGH 상태로 두고, SDA(데이터) 라인을 LOW로 변경합니다. 이 신호는 모든 슬레이브 장치들에게 데이터를 전송할 준비가 되었다는 신호로 인식됩니다. 만약 회로에 마스터 장치가 여러개 붙어 있다면 먼저 SDA 라인을 LOW 로 잡는 이가 제어권을 갖습니다.
주소 프레임(address frame)
주소 프레임은 항상 모든 통신 데이터의 앞에 위치합니다. 데이터 라인으로 처음 수신되는 1byte 중 앞선 7 bit 데이터(MSB, most significant bit)가 I2C 주소를 나타냅니다. 그리고 마지막 1 bit 는 읽기(read, 1, 데이터 요청) 또는 쓰기(write, 0, 데이터 전송) 동작임을 표시합니다.
프레임의 9번째 bit 값은 NACK/ACK 비트입니다. 이 비트는 마스터가 전송한 주소 정보(8bit)에 해당하는 장치가 만들어줘야 하는 신호입니다.(즉, 해당하는 슬레이브 장치가 잠시 SDA 라인의 컨트롤 권한을 가짐) 마스터 장치는 이 신호를 보고 데이터가 전송이 성공적인지, 실패라면 앞으로 어떤 동작을 할지 판단해야 합니다. NACK/ACK 비트는 주소 프레임, 데이터 프레임의 끝에 항상 붙습니다.
데이터 프레임(data frame)
주소 프레임의 전송이 완료되면 이제 데이터 프레임의 전송을 시작합니다. 마스터 장치는 SCL 라인의 클럭 신호를 계속 생성하며 SDA 라인으로는 데이터가 오고갑니다. 이때 SDA 라인의 데이터 프레임은 read, write 상태를 나타내는 bit 값에 따라 마스터 또는 슬레이브가 사용합니다.
통신 종료 조건
모든 데이터 프레임이 전송되면 마스터 장치는 종료 신호를 만들어야 합니다. 종료 신호는 클럭 라인인 SCL 을 0->1(LOW to HIGH) 상태로 변경한 뒤, SCL 라인이 HIGH 인 상태에서 SDA 라인을 0->1 (LOW to HIGH)로 변경하면 됩니다. 따라서 반드시 모든 장치들은 반드시 SCL 라인이 HIGH 인 상태에서 SDA 라인의 상태를 변경해서는 안됩니다. 이런 동작은 잘못된 종료신호로 인식될 수 있기 때문입니다.
.
프로토콜 심화
아래 링크에서 10비트 주소 체계를 사용하는 경우, Repeated Start Condition을 사용하는 경우, Clock stretching 의 상세 정보를 보실 수 있습니다.
참고자료
.