JINTBEAT Design Life

ARM I2C(Inter-Integrated Circuit) 동작 원리 본문

🖥️ - ARM

ARM I2C(Inter-Integrated Circuit) 동작 원리

jintbeat_design 2025. 8. 10. 02:54
반응형
I2C란 ?

 
I2C는 마스터 - 슬레이브 구조로 동작하는 2개의 선(SCL, SDA)만으로 여러 칩끼리 데이터를 주고 받는 통신 방식이다.

  • SCL ( Serial Clock ) : 마스터가 만들어 주는 Clock 신호
  • SDA ( Serial Data ) : 데이터를 주고 받는 선
ARM MCU에서 I2C 구조

 
Cortex-M 계열 MCU에서 I2C는 하드웨어 주변장치(Peripheral)로 내장되어 있다.
CPU가 직접 SCL/SDA를 toggle하는게 아니라, I2C 컨트롤러가 알아서 처리해주는 것이다.
 
구성 요소 :

  • I2C controller : HW 상태 제어(START, STOP, ACK/NACK, 데이터 전송)
  • APB Bus 연결 : CPU - I2C 레지스터
  • Pin Mapping : SCL, SDA pin을 GPIO에서 I2C 기능으로 설정 - GPIO pin을 I2C HW 주변장치 전용 기능으로 설정하는 과정이고, open-drain 방식이 일반적이다. 
그렇다면, Open Drain 방식이란 ?

 
High 출력을 직접 만들지 않고, Low만 강제로 당기는 방식. High는 Pull-Up 저항을 통해 올라가게 된다.
여러 장치가 SDA/SCL을 공유하는 버스이기 때문에, 한 장치가 High를 만들고 다른 장치가 Low를 만들면 쇼트가 나버린다. Open-Drain 방식은 "여러 장치가 동시에 버스를 사용해도" 충돌이 없게 해준다. 이 말은 즉슨, High는 "아무도 당기지 않은 상태"이고, Low는 "적어도 한 장치가 당김" 상태이기 때문에 밑의 그림처럼 되지 않을까 싶다. 
 

 

I2C의 "Bit Level Rule"


다음은 I2C의 규칙이다!

  • data는 SCL=High 동안 고정. 바뀌어도 되는 구간은 SCL=Low일 때만 가능하다.
  • START : SCL=High에서 SDA High->Low
  • STOP : SCL = High에서 SDA Low -> High
  • 9번 째 Clock은 ACK/NACK 비트
    • 송신자는 8비트 보낸 뒤 9번 째 Clock에서 SDA를 풀어준다(High-Z)
    • 수신자는 ACK이면 SDA Low, NACK이면 SDA High(풀업 유지)
주소 전송(7bit/10bit)와 R/W 비트
  • 7bit 주소 : [ADDR(7)] + [R/W] -> 총 8bit 보낸 뒤 수신 ACK.
  • 10bit 주소(참고) : 1110 + A9:A8 + W -> ACK -> A7:A0 -> ACK -> (읽기인 경우) Repeated START 후 11110 + A9:A8 + R -> ACK...

대부분은 7비트 주소를 사용한다.
 

Master - Write Sequence

 
1. START
2. [Slave Address + W] 전송 -> Slave ACK 확인
3. [Register Address] 전송 -> ACK
4. [Data bytes] 전송(byte마다 ACK 확인)
5. STOP
 
여러 바이트 연속 전송 가능(Slave가 각 byte마다 ACK)
 
Polling 예시 )

START
ADDR+W  → ACK?
REG     → ACK?
DATA0   → ACK?
DATA1   → ACK?
...
STOP

 

Master - Read sequence

 
먼저 읽고 싶은 주소를 W로 써넣고, 이어서 반복 시작(Repeated START)로 R를 건다.
 
1. START
2. [Slave Address + W] -> ACK
3. [Register 주소] -> ACK
4. Repeated START(BUS 놓지 않음)
5. [Slave Address + R] -> ACK
6. Slave가 byte 보냄 -> 마스터는 byte마다 ACK(더 받을 거면 ACK)
7. 마지막 byte를 받은 뒤 마스터는 NACK(더 이상 안 받겠다는 의미)
8. STOP
 
Polling 예시 )

START
ADDR+W  → ACK
REG     → ACK
REPEATED START
ADDR+R  → ACK
READ BYTE0 → ACK
READ BYTE1 → ACK
...
READ BYTE(N-1) → NACK
STOP

 

ACK/NACK 를 해석하는 법?

 

  • 주소 직 후, NACK : 해당 주소의 디바이스 없음, 혹은 바쁘다(Busy) -> 보통 STOP 후 재시도.
  • 데이터 중간 NACK : Slave가 더 이상 받을 수 없음/읽기 종료 신호 -> STOP 또는 RESTART로 종료/재시작.
Clock Stretching(Clock 늘리기)
  • Slave가 일시적으로 SCL을 Low로 잡고 처리 시간을 벌 수 있음.
  • Master HW는 SCL이 실제로 High가 될 때까지 다음 bit를 진행하지 않음.
  • 일부 MCU는 Stretching timeout option/Flag가 있음.
Multi-Master & Arbitration
  • 버스는 Low 우선(유선-AND)
  • 마스터가 "1"을 내보냈다고 생각했는데, SDA를 샘플링했더니 "0"이면 -> Arbitration Lost
    • 해당 Master는 즉시 전송 중단, Bus 양보.
  • 전기적으로는 안전(open-drain + pull up), 논리적으로만 승자/패자 결정.
Repeated START vs STOP
  • Repeated START : 버스를 놓지 않은 채(R/W) 전환이나 장치 전환. 메모리, 센서 읽기에서 표준 패턴.
  • STOP 후 Re Start : 버스를 완전히 해제했다 다시 잡음. 어떤 디바이스는 STOP 사이에 요구하기도 함(예 : EEPROM의 내부 write cycle)
Timing 관점

 

  • tHD;STA: START 후 SCL Low 유지 최소 시간
  • tSU;STA: START setup 시간
  • tSU;DAT / tHD;DAT: 데이터 setup/hold (SCL 에지 기준)
  • tSU;STO: STOP setup
  • 표준(100k), 패스트(400k), Fm+(1MHz)마다 요구치가 달라지므로 디바이스 데이터시트를 따라야 함.
(참고) ARM 계열 I2C 컨트롤러 사용 흐름(개념)

 
MCU마다 레지스터 이름은 다르지만 큰 틀은 같다.
 
마스터-쓰기(폴링 예)

  1. I2C 활성화, 속도 설정(SCL 분주).
  2. START 트리거 → “Start Bit Sent” 플래그 대기.
  3. ADDR+W 쓰기 → “Address Sent/ACK” 플래그 대기.
  4. REG 쓰기 → TXE/BTF 등 상태 플래그 확인.
  5. DATA… 쓰기(필요 바이트 수만큼) → 매 바이트 후 플래그 확인.
  6. STOP 트리거.

마스터-읽기(Repeated START)

  1. START → ADDR+W → ACK 대기
  2. REG 바이트 쓰기 → ACK 대기
  3. Repeated START → ADDR+R → ACK 대기
  4. (N바이트 읽기)
    • 마지막 1바이트 남기고는 ACK=1(계속 받기)
    • 마지막 바이트 직전 ACK=0(NACK 준비)
  5. 마지막 바이트 수신 직후 STOP.

 

반응형