I2C 통신
- 데이터를 전송하는 SDA, Clock주기를 전송하는 SCL 두개의 버스로 디바이스끼리 데이터를 송/수신할 수 있는 통신 방식
- 동기식 통신 방식
[동기 vs 비동기]
동기 : 요청을 보냈을 때 응답이 돌아와야 다음 동작 수행(데이터가 전달된다는 것을 알려주는 용도로 Clock 사용)
비동기 : 요청을 보냈을 때 응답상태와 상관없이 다음 동작 수행
하나의 마스터에 다수의 슬레이브가 연결되어있습니다.
마스터에서 Clock을 생성하고 이 Clock에 맞춰서 SDA를 송/수신합니다. 그러므로 송/수신이 동시에 될 수 없습니다.
각 슬레이브에 주소가 있기때문에 원하는 슬레이브의 주소에서 해당 데이터를 읽어오거나 쓸 수 있습니다.
슬레이브의 주소를 마스터가 알고있어야합니다.
MCU 1대와 I2C통신을 지원하는 여러개의 IC칩을 연결하는 경우입니다.
[마스터에서 슬레이브로 1byte데이터를 쓸 때 데이터 규격]
# 통신 순서
- 마스터가 시작 신호 전송
- MCU와 연결된 IC의 RAM주소를 전송
- 마지막 비트는 0으로 줘서 데이터를 쓰겠다는 것을 알림
- Slave가 나 데이터 받았다는 뜻으로 ACK신호 전송(LOW신호 전송)
- Master가 데이터를 쓸 곳의 주소를 전송
- 잘 받았으면 Slave가 ACK 전송
- Master가 쓸 데이터 전송
- ACK
- 끝났으면 STOP
# ACK 신호 보내는 경우
- 데이터를 잘 받았을 때
[마스터에서 슬레이브로부터 1byte데이터를 읽을 때 데이터 규격]
# 통신 순서
- 마스터가 시작 신호 전송
- MCU와 연결된 IC의 RAM주소를 전송
- 일단 쓴다는 뜻으로 마지막 비트는 0 전송
- ACK
- Master가 데이터를 읽을 곳의 주소를 전송(그냥 가리키기는 용도)
- ACK
- 이제 읽을꺼니까 다시 시작한다는 신호 전송
- 읽을 IC의 RAM 주소 전송
- 마지막 비트는 읽는다는 뜻으로 1 전송
- ACK
- Slave가 해당하는 데이터 전송
- 데이터를 다 읽었다는 의미로 NACK신호 전송(HIGH신호 전송)
- STOP
# NACK 신호 보내는 경우
- 수신측에서 뭔가 다른 작업을 하고있거나 통신을 시작할 준비가 안되었을 때
- 전송 중 수신측에서 이해하지 못하는 데이터나 명령을 받을 때
- 전송 중 수신측에서 더 이상 데이터 바이트를 수신할 수 없을 때
- READ 동작시 Master가 수신측으로 작동하면서 예상한 만큼 데이터를 읽었을 때 더 이상 안 보내도 된다고 Slave에 알릴 때
[신호의 시작과 끝]
[데이터를 읽을 때 Repeated START부분]
[비트 전송 과정]
SCL이 HIGH인데 SDA가 HIGH에서 LOW가 되면 시작 → 주소 7비트를 보낸다 → 읽을지 쓸지 1비트 전송 → ACK → 데이터 8비트 전송 → ACK → SCL이 HIGH인데 SDA가 LOW에서 HIGH가 되면 끝
데이터 교환전에는 SDA, SCL모두 1을 유지합니다.
ACK전에 0이면 데이터 쓰는중, 1이면 데이터 읽는중을 의미합니다.
SDA와 SCL에 풀업저항을 달아서 전압을 공급합니다.
그러므로 신호가 없을 때는 HIGH를 유지하고 신호가 들어오면 LOW로 시작을 알립니다.
SDA는 SCL의 rising edge와 falling edge 사이에서(SCL=1인 동안) 읽어 들입니다.
신호를 읽는 방법이 잘 이해가 안가서 저는 이런 방식으로 읽는데요...
SDA 쿵 (전송 시작) -> SCL 쿵 하나 둘 … (하나에 SDA에서 주소1비트 전송 ...)
** SCL은 맞지않으니 SDA만 참고하시기 바랍니다. **
아두이노를 이용해 I2C통신을 구현해 봤습니다.
작성한 코드는 github에 올려뒀습니다.
출처
https://velog.io/@d3fau1t/I2C-%ED%86%B5%EC%8B%A0-%EC%9D%B4%ED%95%B4-with-MCP23008
'임베디드' 카테고리의 다른 글
I2C 통신으로 칩 펌웨어 업데이트 방법 (0) | 2025.02.06 |
---|---|
MCU I2C 통신 데이터 읽는 방법 (0) | 2025.02.04 |
UART 디버깅용 print함수 만들기 (0) | 2022.11.10 |