[아두이노] I²C는 어떻게 데이터와 ACK를 구분할까? (클럭 기반 상태 머신의 이해)
I²C를 공부하다 보면 많은 사람들이 한 번쯤 이런 의문을 가집니다.
"ACK도 그냥 1비트인데,
데이터 비트와 어떻게 구분하지?"
예를 들어 I²C는:
8비트 데이터 + ACK/NACK 1비트
구조로 동작합니다.
그런데 버스에는 결국:
SDA(Data)
SCL(Clock)
두 선밖에 없습니다.
즉 전압만 보면:
0인지 1인지
밖에 안 보입니다.
그렇다면 MCU는 어떻게:
데이터
ACK
START
STOP
을 구분하는 걸까요?
오늘은 I²C 프로토콜의 핵심인:
클럭 기반 상태 머신(State Machine)
관점으로 정리해보겠습니다.
1. I²C는 "값"보다 "타이밍"이 중요하다
초보자는 흔히 이렇게 생각합니다.
"ACK는 특별한 전압값인가?"
하지만 아닙니다.
ACK도 단순한 1비트입니다.
핵심은:
언제 나타났는가
입니다.
즉 I²C는:
비트 값 자체보다
클럭 타이밍이 더 중요
합니다.
2. I²C는 동기식 통신이다
I²C에는 두 선이 있습니다.
| 선 | 역할 |
|---|---|
| SDA | 데이터 |
| SCL | 클럭 |
그리고 모든 장치는:
SCL을 기준으로 동작
합니다.
즉:
몇 번째 클럭인가?
를 계속 추적합니다.
3. ACK는 항상 9번째 클럭
I²C 규칙은 매우 엄격합니다.
| 클럭 번호 | 의미 |
|---|---|
| 1~8 | 데이터 |
| 9 | ACK/NACK |
즉:
1~8번째 클럭:
데이터 비트
9번째 클럭:
응답 비트
입니다.
그래서 MCU는:
"지금 9번째 클럭이네?
그럼 ACK 슬롯이구나"
라고 판단합니다.
즉:
값이 아니라 위치로 구분
합니다.
4. 실제 흐름 예시
예를 들어:
10110010
를 전송한다고 해봅시다.
그러면 실제 버스 흐름은:
클럭 1 → 1
클럭 2 → 0
클럭 3 → 1
클럭 4 → 1
클럭 5 → 0
클럭 6 → 0
클럭 7 → 1
클럭 8 → 0
클럭 9 → ACK/NACK
입니다.
즉 마지막 9번째 클럭은:
무조건 ACK 전용 슬롯
입니다.
5. ACK는 누가 만드는가?
여기서 중요한 점이 있습니다.
I²C는:
송신자와 수신자가 번갈아 SDA를 제어
합니다.
데이터 전송 중
1~8번째 클럭에서는:
송신자(TX)가 SDA 제어
합니다.
즉 데이터를 출력합니다.
ACK 구간
9번째 클럭에서는:
송신자가 SDA를 놓아버림
니다.
그러면:
수신자(RX)가 SDA를 제어
하여 ACK/NACK를 생성합니다.
즉 구조는:
| 구간 | SDA 제어 주체 |
|---|---|
| 1~8비트 | 송신자 |
| 9비트 | 수신자 |
입니다.
6. 이것이 가능한 이유: Open Drain 구조
I²C는 일반 Push-Pull 출력이 아닙니다.
대신:
Open Drain(Open Collector)
구조를 사용합니다.
즉 장치는:
LOW는 직접 만들 수 있음
HIGH는 직접 출력하지 않음
입니다.
HIGH는:
풀업 저항(Pull-up Resistor)
이 만들어줍니다.
7. ACK와 NACK의 실제 의미
ACK
ACK는:
수신기가 SDA를 LOW로 당김
입니다.
즉:
0
입니다.
의미는:
"정상적으로 받았다"
입니다.
NACK
NACK는:
아무도 SDA를 LOW로 안 당김
입니다.
그러면 풀업 저항 때문에 자동으로 HIGH가 됩니다.
즉:
1
입니다.
의미는:
"못 받음"
또는
"더 이상 안 받을래"
입니다.
8. START/STOP은 왜 데이터와 안 헷갈릴까?
I²C는 특별한 규칙이 하나 더 있습니다.
START 조건
SCL이 HIGH일 때 SDA가 HIGH→LOW
이면 START입니다.
STOP 조건
SCL이 HIGH일 때 SDA가 LOW→HIGH
이면 STOP입니다.
데이터 비트는?
데이터는:
SCL LOW 상태에서만 변경
됩니다.
즉 START/STOP은 일반 데이터 비트와 타이밍 규칙 자체가 다릅니다.
그래서 절대 혼동되지 않습니다.
9. 결국 I²C는 상태 머신(State Machine)
이쯤 되면 보이는 사실이 있습니다.
I²C는 단순히:
전압 변화만 보는 통신
이 아닙니다.
실제로는:
현재 몇 번째 클럭인가
현재 START 상태인가
현재 ACK 슬롯인가
를 계속 추적합니다.
즉 내부적으로는:
프로토콜 상태 머신(State Machine)
처럼 동작합니다.
10. MCU 내부 I²C 하드웨어의 정체
STM32나 AVR 내부의 I²C Peripheral도 사실상:
I²C 전용 하드웨어 상태 머신
입니다.
그래서 자동으로:
START 생성
Address 송신
ACK 처리
STOP 생성
등을 수행합니다.
Arduino의:
Wire.requestFrom()
같은 함수가 가능한 이유도 이것입니다.
핵심 정리
| 항목 | 구분 방식 |
|---|---|
| 데이터 비트 | 1~8번째 클럭 |
| ACK/NACK | 9번째 클럭 |
| START | SCL HIGH에서 SDA↓ |
| STOP | SCL HIGH에서 SDA↑ |
| ACK | SDA LOW |
| NACK | SDA HIGH |
즉 I²C는:
값 자체보다
"언제 발생했는가"
로 의미를 구분하는 프로토콜입니다.
그리고 이것이 바로:
클럭 기반 동기식 통신
의 핵심 개념입니다.
댓글
댓글 쓰기