Перейти к содержанию

Транзакция I²C по байтам

Введите адрес устройства, номер регистра или данные и число байтов для чтения — инструмент разложит обмен по шине I²C на условия START и STOP, байты и подтверждения, нарисует SCL и SDA по тактам, посчитает время и подскажет, какие микросхемы обычно сидят на этом адресе.

Исходные данные

Операция
HEX

7-битный, как в Arduino: от 00 до 7F

Адрес

в шестнадцатеричном виде: D0 или 00 10

минимальные времена условий START и STOP — из таблицы 11 UM10204

Ведомое устройство

Результат

Транзакция на шине
S EC A D0 A Sr ED A ?? N P
S — START, Sr — повторный START, P — STOP, A — ACK, N — NACK, ?? — байт от ведомого
Байт адреса
0xEC / 0xEDзапись (R/W = 0) / чтение (R/W = 1)
Тактов SCL
364 байта по 9 тактов, из них данных — 2
Длительность, не меньше
376,7 мкстакты — 360 мкс, условия START и STOP по Standard-mode — 16,7 мкс; без растягивания такта

На адресе 0x76 может отвечать: BMP280, BME280 (давление, температура, влажность, 0x76 или 0x77); PCA9685 (16-канальный ШИМ, 0x40–0x7F); TCA9548A (мультиплексор I²C на 8 каналов, 0x70–0x77).

SCL и SDA по тактам

Байты идут старшим битом вперёд, за каждым — девятый такт подтверждения. Чёрным — то, что выдаёт ведущий, оранжевым — ведомый.

Транзакция I²C: S EC A D0 A Sr ED A ?? N PSCLSDAадрес 0x76 + Wрегистр 0xD0адрес 0x76 + Rданные от ведомогоSSrP11101100A11010000A11101101AN
ШагПередаётНа линииСмысл
1ведущийSSTART: SDA падает при высоком SCL
2ведущий0xECадрес 0x76 + W — 11101100; ACK от ведомого
3ведущий0xD0регистр 0xD0 — 11010000; ACK от ведомого
4ведущийSrповторный START: шина не освобождается
5ведущий0xEDадрес 0x76 + R — 11101101; ACK от ведомого
6ведомый??данные от ведомого; NACK от ведущего
7ведущийPSTOP: SDA поднимается при высоком SCL

Arduino, библиотека Wire

#include <Wire.h>

// in setup(): Wire.begin();

Wire.beginTransmission(0x76);
Wire.write(0xD0);
Wire.endTransmission(false);  // false: repeated START instead of STOP
Wire.requestFrom(0x76, (uint8_t)1);
while (Wire.available()) {
  uint8_t value = Wire.read();
}

STM32, HAL

uint8_t buf[1];
// write the register number, repeated START, read
HAL_I2C_Mem_Read(&hi2c1, 0x76 << 1, 0xD0, I2C_MEMADD_SIZE_8BIT, buf, 1, 100);

HAL ждёт адрес, сдвинутый на разряд влево; hi2c1 — дескриптор из STM32CubeMX.

Обмен по шине I²C всегда устроен одинаково: условие START, байт адреса с битом направления, байты данных — каждый с подтверждением — и условие STOP. Инструмент собирает такую транзакцию для записи, чтения и чтения регистра, показывает её по тактам SCL и SDA, считает время и даёт код для Arduino и STM32.

Коротко

  • Байт адреса: 7 бит адреса и бит R/W: 0 — запись, 1 — чтение; 0x76 даёт 0xEC и 0xED.
  • Байт: 8 бит старшим вперёд и девятый такт подтверждения; ACK — SDA в нуле, NACK — в единице.
  • Чтение регистра: запись номера регистра, повторный START, адрес с R/W = 1, чтение; последний байт — NACK, затем STOP.
  • 10-битный адрес: первый байт 11110XX + R/W, второй — младшие 8 бит.
  • Время: 9 тактов SCL на байт плюс времена START и STOP по таблице 11 UM10204.

Как пользоваться

Выберите операцию. «Запись» передаёт байты данных устройству; без данных получится проверка адреса — так работает сканер шины. «Чтение» сразу принимает байты от ведомого. «Чтение регистра» сначала записывает номер регистра, а затем после повторного START читает. Адрес вводится в шестнадцатеричном виде, как в даташитах; если ввести байт адреса вроде 0xEC, инструмент подскажет 7-битный адрес.

Результат — транзакция одной строкой, байты адреса для записи и чтения, число тактов и наименьшее время обмена на выбранной частоте. Ниже — диаграмма SCL и SDA, таблица шагов и код. Переключатель «Нет на шине» показывает, что видит ведущий, когда устройство не отвечает: NACK на байте адреса и STOP. Все параметры хранятся в адресе страницы.

Из чего состоит транзакция

Чтение регистра 0xD0 датчика BME280 с адресом 0x76: S, 0xEC, ACK, 0xD0, ACK, Sr, 0xED, ACK, байт от датчика, NACK, PSCLSDAадрес 0x76 + Wрегистр 0xD0адрес 0x76 + Rданные от ведомогоSSrP11101100A11010000A11101101AN
Чтение регистра 0xD0 датчика BME280 с адресом 0x76: запись номера регистра, повторный START, чтение одного байта, NACK и STOP. Чёрным — уровни, которые выдаёт ведущий, оранжевым — ведомый.
ЭлементКто формируетКак выглядит на линиях
START (S)ведущийSDA падает, пока SCL в единице
Байт адресаведущий7 бит адреса и R/W, старшим битом вперёд
ACKприёмник байтана девятом такте SDA в нуле
Данныепередатчик: ведущий при записи, ведомый при чтении8 бит старшим вперёд, SDA меняется только при низком SCL
NACKприёмник байтана девятом такте SDA остаётся в единице
Повторный START (Sr)ведущийSTART без STOP перед ним: шина остаётся занятой
STOP (P)ведущийSDA поднимается, пока SCL в единице

Байт адреса для 7-битного адреса AA и бита направления R/W‾R/\overline{W}:

B=2A+R/W‾,0x76→0xEC (запись),  0xED (чтение).B = 2A + R/\overline{W}, \qquad 0\text{x}76 \rightarrow 0\text{xEC} \text{ (запись)}, \; 0\text{xED} \text{ (чтение)}.

Для 10-битного адреса первый байт — 1111 0 A9A8 R/W‾1111\,0\,A_9 A_8\,R/\overline{W}, второй — A7…A0A_7 \dots A_0. Чтение 10-битного устройства начинается с записи обоих байтов: после повторного START передаётся только первый байт с R/W‾=1R/\overline{W} = 1, и ведомое, уже узнавшее свой адрес, отвечает.

Время обмена

Каждый байт занимает 9 тактов SCL. Наименьшее время транзакции из NN байтов на частоте ff:

t≥9Nf+tHD;STA+nSr (tSU;STA+tHD;STA)+tSU;STO,t \ge \frac{9N}{f} + t_\text{HD;STA} + n_\text{Sr}\,(t_\text{SU;STA} + t_\text{HD;STA}) + t_\text{SU;STO},

где nSrn_\text{Sr} — число повторных START. Времена условий — минимальные значения из таблицы 11 UM10204:

ПараметрStandard-mode, до 100 кГцFast-mode, до 400 кГцFast-mode Plus, до 1000 кГц
tHD;STA — удержание START (и повторного START) до первого такта4 мкс0,6 мкс0,26 мкс
tLOW — низкий уровень SCL4,7 мкс1,3 мкс0,5 мкс
tHIGH — высокий уровень SCL4 мкс0,6 мкс0,26 мкс
tSU;STA — установка повторного START4,7 мкс0,6 мкс0,26 мкс
tSU;STO — установка STOP4 мкс0,6 мкс0,26 мкс
tBUF — свободная шина между STOP и START4,7 мкс1,3 мкс0,5 мкс

Чтение регистра BME280 — 4 байта и один повторный START: на 100 кГц это не меньше 360 + 4,0 + 8,7 + 4,0 = 376,7 мкс, на 400 кГц — 90 + 2,4 = 92,4 мкс. Реальный обмен длиннее: ведомое может растягивать такт, а программа — делать паузы между байтами. Между STOP и следующим START шина ещё должна побыть свободной не меньше tBUFt_\text{BUF}.

Адреса микросхем и зарезервированные адреса

Инструмент сверяет введённый адрес с таблицей популярных микросхем из статьи об I²C — все адреса в ней 7-битные и проверены по даташитам:

МикросхемаНазначениеАдресЧем задаётся
AT24C02, AT24C256 и другие EEPROM серии 24память0x50–0x57выводы A2–A0; у AT24C неподключённые выводы внутри притянуты к нулю, тогда адрес 0x50. У AT24C16 адресных выводов нет: эти три бита — старшие биты адреса ячейки памяти, и микросхема занимает все восемь адресов
DS1307часы реального времени0x68фиксирован; только 100 кГц
DS3231часы реального времени0x68фиксирован
PCF8574расширитель портов, модули LCD 16020x20–0x27выводы A2–A0
PCF8574Aрасширитель портов, модули LCD 16020x38–0x3Fвыводы A2–A0
SSD1306контроллер OLED-дисплея0x3C или 0x3Dвывод SA0 (он же D/C#)
BMP280, BME280давление, температура, влажность0x76 или 0x77вывод SDO: земля — 0x76, питание — 0x77; оставлять в воздухе нельзя
MPU-6050акселерометр и гироскоп0x68 или 0x69вывод AD0
ADS1115 (ADS1113, ADS1114)АЦП 16 бит0x48–0x4Bвывод ADDR на GND, VDD, SDA или SCL
INA219монитор тока и мощности0x40–0x4Fвыводы A1 и A0, каждый на GND, VS+, SDA или SCL — 16 адресов
PCA968516-канальный ШИМ0x40–0x7Fвыводы A5–A0; 0x70 по умолчанию занят групповым адресом LED All Call
BH1750датчик освещённости0x23 или 0x5Cвывод ADDR: низкий — 0x23, высокий — 0x5C
SHT30, SHT31, SHT35температура и влажность0x44 или 0x45вывод ADDR; оставлять в воздухе нельзя
TCA9548Aмультиплексор I²C на 8 каналов0x70–0x77выводы A2–A0

Две группы адресов зарезервированы спецификацией (таблица 4 UM10204), обычные устройства их не занимают:

Адрес (7 бит)R/WНазначение
0000 000 (0x00)0общий вызов (general call)
0000 000 (0x00)1START-байт
0000 001 (0x01)любойадрес шины CBUS
0000 010 (0x02)любойдля шин другого формата
0000 011 (0x03)любойрезерв на будущее
0000 1XX (0x04–0x07)любойкод ведущего High-speed mode
1111 1XX (0x7C–0x7F)1Device ID
1111 0XX (0x78–0x7B)любойпервый байт 10-битного адреса

Ограничения

  • Режимы High-speed (до 3,4 МГц) и Ultra Fast-mode здесь не считаются: у них свои условия и тайминги.
  • Байты, которые выдаёт ведомый, заранее неизвестны: на диаграмме они показаны полосой, в строке транзакции — как «??».
  • Растягивание такта, арбитраж нескольких ведущих, общий вызов и START-байт не моделируются.
  • Код для Arduino и STM32 — для 7-битных адресов. Библиотека Wire в Arduino на AVR читает за один вызов не больше 32 байт, а HAL_I2C_Mem_Read принимает номер регистра из одного или двух байтов.

Частые вопросы

Чем 7-битный адрес I2C отличается от 8-битного?

Адрес устройства — 7 бит, а первый байт на шине — это адрес, сдвинутый на разряд влево, плюс бит R/W. Для датчика с адресом 0x76 байт записи — 0xEC, байт чтения — 0xED. Библиотека Wire в Arduino принимает 7-битный адрес, HAL для STM32 — уже сдвинутый: 0x76 << 1. Если в документации стоит пара вроде 0x4E/0x4F или число больше 0x7F, это байты, а адрес — их значение, делённое на два.

Почему последний прочитанный байт подтверждается NACK?

Так ведущий-приёмник сообщает ведомому, что больше байтов не нужно: на девятом такте он оставляет SDA в единице, и ведомый освобождает линию. Это пятая из причин NACK в UM10204 (раздел 3.1.6). Сразу после NACK ведущий формирует STOP или повторный START. Если подтвердить последний байт ACK, ведомый начнёт выдавать следующий и может удержать SDA в нуле, помешав STOP.

Зачем повторный START при чтении регистра?

Чтобы прочитать регистр, ведущий сначала записывает его номер, а потом меняет направление обмена на чтение. Повторный START (Sr) делает это, не освобождая шину: никакой другой ведущий не вклинится между записью номера и чтением. В UM10204 это комбинированный формат (рисунок 13). В Arduino его даёт endTransmission(false), в STM32 HAL — функция HAL_I2C_Mem_Read.

Как устроен 10-битный адрес I2C?

Первый байт — 11110, два старших бита адреса и бит R/W; второй — восемь младших бит. Для чтения ведущий передаёт оба байта с R/W = 0, затем повторный START и только первый байт, уже с R/W = 1 (рисунок 15 UM10204). Для адреса 0x2A5 это байты 0xF4 и 0xA5, а после Sr — 0xF5.

Сколько времени занимает обмен по I2C?

Каждый байт занимает 9 тактов SCL: 8 бит и подтверждение. Чтение регистра BME280 — четыре байта, 36 тактов: 360 мкс на 100 кГц и 90 мкс на 400 кГц. К этому добавляются времена условий START, повторного START и STOP — по таблице 11 UM10204 ещё не меньше 16,7 мкс в Standard-mode и 2,4 мкс в Fast-mode. Растягивание такта ведомым и паузы программы увеличивают время.

Какие адреса I2C нельзя занимать?

Таблица 4 UM10204 резервирует две группы по восемь адресов: 0x00–0x07 (общий вызов, START-байт, CBUS, другой формат шины, резерв и коды ведущего High-speed mode) и 0x78–0x7F (первый байт 10-битного адреса и Device ID).

Источники

  1. NXP Semiconductors. UM10204: I2C-bus specification and user manual, Rev. 7.0, 1 October 2021 — разд. 3.1.4 — START, повторный START и STOP; 3.1.5 — байт из 8 бит старшим вперёд с битом подтверждения; 3.1.6 — ACK и NACK; 3.1.10 и рис. 9–13 — адрес и R/W, запись, чтение, комбинированный формат; 3.1.11 и рис. 14–15 — 10-битная адресация; 3.1.12 и табл. 4 — зарезервированные адреса; табл. 11 — времена SCL и SDA
  2. sigrok project. sigrok-test: decoder/test/i2c — расшифровки записей шины: часы DS1307 на 200 кГц (rtc_ds1307_200khz) и инициализация контроллера Wii Nunchuk (wii_nunchuk_init); по ним проверены порядок байтов, ACK и NACK
  3. Даташиты микросхем из таблицы адресов — те же, что в статье об I²C: Microchip AT24C02C, AT24C16C, AT24C256C; Maxim DS1307, DS3231, DS3231M; Solomon Systech SSD1306; Bosch Sensortec BMP280 и BME280; InvenSense MPU-6000/6050; TI ADS1115, INA219, TCA9548A; NXP PCF8574, PCA9685; ROHM BH1750FVI; Sensirion SHT3x-DIS
  4. Arduino. ArduinoCore-avr, библиотека Wire (Wire.h, Wire.cpp) — endTransmission(false) — повторный START вместо STOP, requestFrom, буфер BUFFER_LENGTH = 32 байта
  5. STMicroelectronics. STM32F4 HAL, драйвер stm32f4xx_hal_i2c.c — HAL_I2C_Master_Transmit, HAL_I2C_Master_Receive, HAL_I2C_Mem_Read; адрес ведомого передаётся сдвинутым на разряд влево
Встроить калькулятор на свой сайт

Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах

<iframe src="https://gaw.ru/embed/i2c-transaction/" title="Транзакция I²C по байтам" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/i2c-transaction/">Транзакция I²C по байтам</a> — GAW.ru</p>
Автоподстройка высоты рамки

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

<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>

Обновлено . Нашли ошибку в расчёте? Напишите нам.