LabHub
배우기 러닝패스 코스

센서는 멀쩡한데 보드가 못 알아듣는다 · 두 선으로 여럿 — I2C · 이론

장치가 응답하지 않습니다, 라는 한 줄

LabHub 에서 이어서 보기

한 줄 요약

I2C 는 선을 끌어내리기만 할 수 있습니다. 올리는 일은 저항이 하고, 그래서 고장의 절반이 상승 모서리에 있습니다.

왜 이게 필요했나

온도 센서 하나가 어제까지 읽히다가 오늘 안 읽힙니다. 드라이버는 "장치가 응답하지 않습니다" 만 말합니다. 이 문장은 여러 원인을 하나로 뭉개 놓은 것입니다 — 주소가 틀렸을 수도 있고, 센서가 죽었을 수도 있고, 전원이 안 들어왔을 수도 있고, 버스가 통째로 잠겼을 수도 있습니다. 파형을 보면 이 넷이 전혀 다르게 생겼습니다.

I2C 를 읽을 줄 알면 드라이버의 한 줄짜리 오류를 어느 비트에서 무슨 일이 있었나로 바꿀 수 있습니다. 그게 이 모듈의 목적입니다.

어떻게 동작하나

두 선입니다. SCL 이 클럭, SDA 가 데이터이고 둘 다 오픈 드레인입니다. 장치는 트랜지스터로 선을 접지에 붙일 수만 있고, 놓으면 풀업 저항이 전원까지 끌어올립니다. 그래서 하강은 빠르고 상승은 저항과 기생 용량이 정하는 속도로 느립니다. TI 의 I2C 안내서는 이 비대칭을 그림으로 먼저 설명합니다 — 저항이 작으면 통신이 빠르지만 전류를 더 쓰고, 크면 느려집니다([SBAA565](https://www.ti.com/lit/pdf/sbaa565), [SLVA704](https://www.ti.com/lit/pdf/slva704)).

규칙은 두 줄로 요약됩니다. 데이터는 SCL 이 낮을 때만 바뀐다. 그리고 SCL 이 높은 동안 SDA 가 움직이면 그것은 데이터가 아니라 조건이다. 내려가면 START, 올라가면 STOP 입니다. NXP 의 규격서가 이 정의를 그대로 적고 있습니다([UM10204](https://www.nxp.com/docs/en/user-guide/UM10204.pdf)).

      START                                   STOPSDA  ‾‾\____  A6 A5 A4 A3 A2 A1 A0 R/W ACK  ____/‾‾SCL  ‾‾‾‾\__/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\__/‾‾‾‾

START 뒤에는 7비트 주소와 읽기·쓰기 비트 하나가 나오고, 아홉 번째 비트가 ACK 입니다. 이 자리에서 마스터는 SDA 를 놓고, 주소가 맞는 장치가 대신 끌어내립니다. 아무도 안 끌어내리면 풀업 때문에 높게 남고, 그것이 NACK 입니다. 즉 NACK 는 장치가 보낸 신호가 아니라 아무 일도 일어나지 않았다는 사실입니다. 주소를 잘못 짚었을 때와 센서에 전원이 없을 때의 파형이 똑같은 이유가 이것입니다.

읽기 전송은 대개 두 번 시작합니다. 먼저 쓰기 주소로 레지스터 번호를 넘기고, STOP 없이 반복 START 를 낸 뒤 읽기 주소로 다시 주소를 지정합니다. 중간에 STOP 을 내면 그 사이에 다른 마스터가 끼어들 수 있으니, 반복 START 는 "아직 안 끝났다" 는 선언입니다. 그리고 마스터는 마지막으로 받을 바이트에 일부러 NACK 를 냅니다. 이것은 오류가 아니라 "그만 보내라" 는 뜻입니다. 파형만 보고 마지막 NACK 를 고장으로 신고하는 일이 흔합니다.

클럭 늘이기는 슬레이브가 SCL 을 놓지 않고 붙들고 있는 것입니다. 준비가 안 됐으니 기다리라는 뜻이고, 마스터는 SCL 이 풀릴 때까지 기다려야 합니다. 파형에서는 마스터가 만든 다른 저준위 구간들과 길이가 확연히 다른 구간 하나로 보입니다. 이 코스의 포착에서는 저준위 구간의 중앙값이 5 µs 인데 그중 하나만 47 µs 입니다. 원인을 찾을 때 "누가 이 구간을 만들었나" 를 묻는 것이 핵심입니다 — 마스터는 자기가 만들지 않은 구간을 설명할 수 없습니다.

마지막이 약한 풀업입니다. 저항이 너무 크거나 배선 용량이 너무 크면 상승 시간이 길어지고, 비트 시간 안에 VIH 까지 못 올라갑니다. 이 코스의 포착에서 SDA 의 10 % → 90 % 상승은 5.25 µs 인데 SCL 은 1.00 µs 입니다. 400 kHz 에서 SCL 이 높은 구간은 그보다 짧으니, SDA 가 1을 실어 나를 시간이 없습니다. 절반 전압(1.65 V)으로 읽으면 데이터가 멀쩡해 보이지만 0.7 × 3.3 = 2.31 V 로 읽으면 18개 구간 중 하나만 1로 읽힙니다. 같은 파일, 다른 임계값, 다른 결론입니다.

현장에서 만나는 모습

버스가 잠기는 사고가 있습니다. 슬레이브가 바이트를 보내던 중에 마스터가 재시작하면, 슬레이브는 자기가 0을 내보내던 자리에서 멈춘 채 SDA 를 놓지 않습니다. 마스터는 STOP 을 만들려 하지만 STOP 은 SDA 를 올려야 성립하므로 만들 수 없습니다. 파형에는 START 는 있는데 STOP 이 없고 SDA 가 길게 낮은 채로 남습니다. 재부팅해도 안 풀리고, SCL 을 몇 번 흔들어 슬레이브가 남은 비트를 다 내보내게 해야 풀립니다.

풀업 저항을 여러 보드에 나눠 붙여 놓고 합쳐서 너무 작아진 경우도 봅니다. 이때는 상승이 빨라져서 통신은 되는데 소비 전류가 늘고, 배터리 수명 보고서에서 뒤늦게 드러납니다. 상승 시간은 한쪽으로만 나쁜 값이 아닙니다.

다음 퀴즈에서 확인할 것

START 와 STOP 의 정의, ACK 자리에서 실제로 일어나는 일, 마지막 바이트의 NACK 가 왜 정상인지, 클럭 늘이기를 파형에서 어떻게 가려내는지, 약한 풀업이 어느 모서리에 나타나는지를 묻습니다.