Руководство · Начальный · 30 мин

Как работает шина I2C: адреса и подтягивающие резисторы

Два провода и общая шина: зачем нужны подтягивающие резисторы, почему несколько отладочных плат мешают друг другу и как устранить конфликт адресов.

Введение

На страницах этого сайта про датчики пишут подключить SDA и SCL, но нигде не объясняют, что делают эти два провода. Чаще всего знать это не нужно: вы подключаете их, библиотека работает, и датчик считывает данные.

Потом вы добавляете вторую плату, и первая перестаёт отвечать. Или библиотека возвращает нули без ошибки. Или выясняется, что два устройства хотят один адрес, а в документации ничего не сказано, что с этим делать.

Все эти симптомы вызваны одним и тем же небольшим набором фактов об I²C, и их меньше, чем следует из числа симптомов.

Два провода, много устройств

I²C подключает все устройства к одной общей паре проводов:

  • SDA — линия данных.
  • SCL — линия тактовой частоты; ею управляет контроллер, хотя устройство может удерживать её на низком уровне для растяжения тактовой частоты.

На Arduino Uno это A4 и A5 (и дублирующие выводы рядом с AREF — те же два вывода, а не дополнительные). Каждое устройство подключается к тем же двум проводам параллельно. Отдельного провода выбора микросхемы нет, и кольца нет: чтобы добавить устройство, припаяйте его к той же паре.

Именно поэтому шина так хорошо масштабируется для роботов. MPU-6050, VL53L0X и PCA9685 используют одни и те же два провода, а различаются по адресу, а не по разводке.

Никто не переводит линию в высокий уровень

Вот факт, из которого следует всё остальное.

Устройство I²C может только опустить линию на низкий уровень. Оно не может перевести её в высокий уровень: выход с открытым стоком — это переключатель на землю и ничего больше. Без внешнего воздействия линия плавала бы при произвольном напряжении.

Подтягивающие резисторы подтягивают линию к высокому уровню. Это не средство повышения надёжности и не необязательное дополнение; это половина электрической цепи. Без них у шины нет состояния покоя, и ничего не работает.

Выход с открытым стоком имеет реальное преимущество, поэтому его и используют: если два устройства говорят одновременно, одно опускает линию, а другое отпускает её, результатом будет низкий уровень. Ничего не конфликтует, ничего не замыкается, а проиграшее устройство может это обнаружить. На шине, где говорить может любое устройство, это важно.

Окно, в котором должен жить подтягивающий резистор

Ограничения есть с обеих сторон, и их можно вычислить.

Слишком малое значение — и ни одно устройство не сможет опустить линию. Спецификация требует, чтобы устройство обеспечивало ток стока не менее 3 mA, удерживая линию ниже 0.4 V, поэтому:

R_min = (Vcc − V_OL) / I_sink = (5 − 0.4) / 0.003 = 1533 Ω

Слишком большое значение — и нарастающий фронт будет слишком медленным. Линия поднимается по RC-кривой относительно ёмкости шины, а тактовая частота не будет ждать:

t_rise ≈ 0.85 × R × C        ≤ 1000 ns at 100 kHz, ≤ 300 ns at 400 kHz
Логарифмический график допустимого сопротивления подтягивающих резисторов в зависимости от полной ёмкости шины. Две падающие кривые отмечают предел времени нарастания для 100 килогерц и 400 килогерц, а горизонтальная красная линия на 1533 ом отмечает нижнюю границу, ниже которой устройство не может потреблять достаточно тока, чтобы опустить линию. Четыре горизонтальные пунктирные линии отмечают эффективное сопротивление одной, двух, трёх и четырёх отладочных плат, подключённых параллельно к одной шине: 4700, 2350, 1567 и 1175 ом; линия для четырёх плат опускается ниже границы.
Рабочий диапазон находится между пределом тока и пределом времени нарастания. Обратите внимание, куда попадает 400 kHz на сильно нагруженной шине: примерно после 250 pF её предел опускается ниже нижней границы, поэтому быстрый режим там вообще недостижим на обычных резисторах. Скачать SVG

Теперь часть, которая сбивает с толку. Почти на каждой любительской отладочной плате уже установлены свои подтягивающие резисторы, обычно 4.7 kΩ. Если подключить несколько плат к одной шине, эти резисторы окажутся параллельно:

Плат на шине Эффективное сопротивление подтягивающих резисторов Вердикт
1 4700 Ω Нормально
2 2350 Ω Нормально
3 1567 Ω На границе — 34 Ω выше нижнего предела
4 1175 Ω Ниже нижнего предела

Поэтому отказ имеет определённую форму: один датчик работает, два работают, три работают в удачный день, а четвёртая плата останавливает всю шину. Ничего не сломано. Устройства просто больше не могут опустить линию достаточно низко, чтобы это считалось низким уровнем.

Исправление — удалить подтягивающие резисторы со всех плат, кроме одной. Обычно это два маленьких резистора для поверхностного монтажа с маркировкой 472, и документация платы указывает, где они находятся. Выпаивание в первый раз кажется неправильным, но это верное решение.

Просканируйте шину до любой другой отладки

Прежде чем трогать библиотеку, спросите у шины, что на ней находится. Этот скетч пробует каждый адрес и сообщает, какие отвечают:

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial) {}

  Serial.println(F("Scanning I2C..."));
  uint8_t found = 0;
  for (uint8_t addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    if (Wire.endTransmission() == 0) {
      Serial.print(F("  device at 0x"));
      Serial.println(addr, HEX);
      found++;
    }
  }
  Serial.println(found ? F("done") : F("nothing answered — check wiring and pull-ups"));
}

void loop() {}

Результат показывает, какая у вас проблема:

  • Никто не отвечает → проблема в проводах, питании или отсутствии подтягивающих резисторов. Не в библиотеке.
  • Устройство отвечает по неожиданному адресу → вывод для установки адреса настроен иначе, чем вы предполагали.
  • Устройство отвечает, но библиотека возвращает нули → шина исправна, а проблема находится выше неё.

Последняя строка стоит больше всего остального в этом скетче. Она чётко отделяет «неправильно подключён провод» от «неправильно написан код», а без этого на отладку уходит большая часть времени.

Адреса и путаница с 0xD0

Адрес I²C занимает 7 бит. Шестнадцать значений зарезервированы, остаётся 112 пригодных.

Вот ловушка. На проводе адрес передаётся как семь битов, за которыми следует бит чтения/записи, поэтому он выглядит как 8-битное значение. В технических описаниях часто приводят именно эту 8-битную форму. Библиотека Arduino Wire ожидает 7-битный адрес.

В техническом описании MPU-6050 указано, что его адрес равен 0xD0 для записи и 0xD1 для чтения. Библиотека Wire ожидает 0x68:

0xD0 = 1101 0000
0x68 = 0110 1000        the same bits, shifted right by one

Если устройство не отвечает по адресу, напечатанному в его техническом описании, сначала попробуйте сдвинуть это значение вправо на один разряд, и только потом делайте вывод, что плата неисправна. Это самая распространённая ошибка в I²C.

Когда два устройства хотят один адрес

Адреса задаются производителем, поэтому конфликты совершенно обычны. Есть три исправления — в порядке предпочтительности:

1. Вывод для установки адреса. Самое дешёвое исправление, если у компонента есть такой вывод. MPU-6050 находится по адресу 0x68 или по 0x69, если его вывод AD0 подтянут к высокому уровню, поэтому два таких устройства сосуществуют с одним проводом. У PCA9685 есть шесть паяемых перемычек, дающих 64 адреса, поэтому на одной шине можно подключить до 62 плат.

2. Удерживать остальные в сбросе, пока меняете адрес одного. У некоторых компонентов адрес фиксирован, но его можно перепрограммировать во время работы. VL53L0X всегда выходит с завода с адресом 0x29, и это стандартный способ запуска нескольких устройств: удерживайте вывод XSHUT каждого датчика на низком уровне, поднимите один, скажите ему перейти на новый адрес и повторите. Новый адрес хранится в RAM, поэтому последовательность повторяется при каждой загрузке.

3. Мультиплексор. TCA9548A — это одно устройство по адресу 0x70 с восемью переключаемыми шинами за ним. Выберите канал, поговорите с устройством на нём, выберите следующий. Это решение для восьми одинаковых датчиков без вывода для установки адреса и без перепрограммирования — ценой дополнительного компонента и того, что шина обслуживается по одному устройству за раз.

Скорость, длина и реальные причины отказов

I²C проектировалась для работы между микросхемами на одной плате. Робот растягивает её через всё шасси, и именно там ограничения начинают давать о себе знать.

  • Главное ограничение — ёмкость, а не длина. Спецификация допускает суммарно 400 pF. Ленточный кабель добавляет примерно 50–100 pF на метр, а каждое устройство — около 10 pF. Длинные трассы отказывают из-за слишком медленного нарастающего фронта — на рисунке выше это видно как падение предела.
  • Сначала замедлитесь, потом сдавайтесь. Wire.setClock(50000) вдвое снижает стандартную частоту и даёт реальный запас на граничной шине. Роботу, опрашивающему датчик с частотой 100 Hz, не нужны 400 kHz.
  • Держите SDA и SCL раздельно. Если провести их рядом в ленточном кабеле, фронты тактовой частоты наводятся на данные. Провод земли между ними помогает.
  • Растяжение тактовой частоты. Устройству, которому нужно время, может удерживать SCL на низком уровне, и контроллер должен ждать. Реальные аппаратные реализации I²C поддерживают растяжение тактовой частоты; некоторые реализации с программным формированием сигналов — нет, и симптомом становится устройство, которое работает в одиночку, но портит данные при загруженной шине.
  • Зависшая шина. Если устройство было сброшено посреди передачи, оно может навсегда удерживать SDA на низком уровне, и каждый скан возвращает пустоту. Девять импульсов по SCL позволяют ему закончить байт, который он считал отправляемым, и отпустить линию — именно это делает процедура восстановления в хорошей библиотеке.

Смешивание 3.3 V и 5 V

ESP32 и Raspberry Pi работают с I²C при 3.3 V, а Uno — при 5 V. Поскольку шина имеет выход с открытым стоком, напряжение подтягивания задаёт высокий уровень для всех находящихся на ней. Если подтянуть её к 5 V при подключённом компоненте, рассчитанном только на 3.3 V, вы подадите 5 V на вывод с допустимым напряжением 3.6 V.

Два приёма спасают почти всегда, и стоит знать, на какой из них вы полагаетесь:

  • Многие отладочные платы, «совместимые с 5 V», содержат микросхему на 3.3 V, регулятор и уже установленное преобразование уровней. Проверяйте до предположений — наличие только регулятора напряжения не означает, что сигнальные выводы защищены.
  • Там, где его нет, стандартный ответ — двунаправленный MOSFET-преобразователь уровней. Делитель напряжения не подходит: он нарушает поведение выхода с открытым стоком в важном направлении.

Когда что-то идёт не так

Симптом Обычно
Сканер вообще ничего не находит Нет подтягивающих резисторов, перепутаны SDA/SCL или отсутствует общая земля
С тремя платами работает, с четырьмя отказывает Параллельные подтягивающие резисторы ниже предела по току
Устройства нет по адресу из технического описания Указан 8-битный адрес; сдвиньте вправо на один разряд
Два одинаковых датчика, отвечает только один Конфликт адресов — вывод установки адреса, XSHUT или мультиплексор
На коротком кабеле читает нормально, на длинном отказывает Ёмкость шины; снизьте частоту или сократите трассу
Случайные повреждения при работе двигателей Шум питания — см. питание и просадки
После сбоя сканер внезапно возвращает пустоту Устройство зависло, удерживая SDA на низком уровне; подайте SCL девять раз
Работает отдельно, портит данные при загруженной шине Контроллер не поддерживает растяжение тактовой частоты

Полезная привычка — сначала каждый раз запускать сканер, до открытия исходников библиотеки. Это занимает тридцать секунд и делит проблему пополам — а половина всей отладки I²C состоит в незнании того, на какой стороне провода находится неисправность.

Исследуйте граф

Входит в эти сборки

Проекты и учебные пути, в которые входит это руководство.

Дополнительные материалы

Источники