Skip to main content

I2C в Linux - краткое руководство

Что такое I2C

I2C (Inter-Integrated Circuit) - двухпроводная шина для связи между микросхемами. На одной шине может висеть несколько устройств: датчики, RTC, EEPROM, дисплеи. Каждое устройство имеет свой 7-битный адрес (от 0x03 до 0x77).

В Linux каждая I2C-шина представлена файлом устройства /dev/i2c-N, где N — номер шины.

Подготовка

Armbian / Debian

Установить пакет i2c-tools и загрузить модуль ядра:

sudo apt install i2c-tools
sudo modprobe i2c-dev

OpenWrt

apk update
apk add i2c-tools kmod-i2c-core kmod-i2c-dev

Проверка

После загрузки модулей должны появиться файлы устройств:

ls /dev/i2c-*

Если вывод пустой - шина не настроена в device tree или модули не загружены.

Сканирование шины утилитой i2cdetect

i2cdetect — основной инструмент из пакета i2c-tools. Он перебирает все адреса на шине и показывает, какие устройства отвечают.

Посмотреть список шин

i2cdetect -l

Пример вывода:

i2c-0   i2c     rk3x-i2c    I2C adapter
i2c-1 i2c rk3x-i2c I2C adapter
i2c-3 i2c rk3x-i2c I2C adapter

Просканировать конкретную шину

i2cdetect -y 1

Флаг -y отключает подтверждение (без него утилита спросит «Continue? [Y/n]»). Цифра 1 — номер шины.

Пример вывода:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Здесь найдены два устройства: на адресе 0x50 (скорее всего EEPROM) и 0x68 (может быть RTC DS3231 или акселерометр MPU6050).

Чтение данных с устройства

Прочитать один байт из регистра

i2cget -y 1 0x76 0xD0

Здесь: шина 1, адрес устройства 0x76, регистр 0xD0. Для датчика BME280 вернёт 0x60 — это его chip ID.

Прочитать все регистры (дамп)

i2cdump -y 1 0x76

Выведет таблицу 256 регистров — полезно для отладки и реверс-инжиниринга неизвестных устройств.

Записать значение в регистр

i2cset -y 1 0x76 0xF2 0x01

Запишет значение 0x01 в регистр 0xF2 устройства на адресе 0x76. Будьте осторожны — неправильная запись может нарушить работу устройства или изменить данные в EEPROM.

Определение устройства по адресу

i2cdetect показывает только адреса, но не говорит, что за устройство отвечает. Определить можно двумя способами.

По адресу

Многие устройства используют фиксированные адреса. Наиболее распространённые:

АдресУстройство
0x23BH1750 (датчик освещённости)
0x3CSSD1306 (OLED-дисплей)
0x44SHT30/SHT31 (температура/влажность)
0x50EEPROM серии 24Cxx
0x51PCF8563 (RTC)
0x68DS1307/DS3231 (RTC) или MPU6050 (акселерометр)
0x76BME280/BMP280 (давление/температура)

По регистру chip ID

Если адрес неоднозначный (например, 0x68 — это RTC или акселерометр?), можно прочитать регистр идентификации:

# BME280: регистр 0xD0 содержит chip ID
i2cget -y 1 0x76 0xD0
# 0x60 = BME280, 0x58 = BMP280

# MPU6050: регистр 0x75 содержит WHO_AM_I
i2cget -y 1 0x68 0x75
# 0x68 = MPU6050, 0x70 = MPU6500

Типичные проблемы

Нет /dev/i2c-* - не загружен модуль i2c-dev. Выполните modprobe i2c-dev.

Если после загрузки модуля шины всё равно не появились - значит I2C не включён в device tree. Дальнейшие действия зависят от платы:

  • NAPI-C, NAPI-P (RK3308): шины I2C по умолчанию выключены и активируются через overlay. Проверьте файл /boot/armbianEnv.txt - в строке overlays= должен быть указан нужный overlay, например rk3308-i2c1 или rk3308-i2c3-m0. Посмотреть доступные overlay:
ls /boot/dtb/rockchip/overlay/rk3308-i2c*

Добавить нужный overlay в /boot/armbianEnv.txt:

overlays=rk3308-i2c1 rk3308-i2c3-m0

После изменения перезагрузите плату. Подробнее об overlay - в руководстве DTS, DTB и Overlays.

  • NAPI2 (RK3568): на плате два I2C-разъёма на GPIO-колодке - они доступны из коробки без дополнительных overlay. После установки i2c-tools и загрузки i2c-dev должны появиться устройства /dev/i2c-*. Проверьте список шин командой i2cdetect -l. Если шин нет - убедитесь, что модуль загружен: lsmod | grep i2c_dev.

Permission denied - нужен root или добавление пользователя в группу i2c:

sudo usermod -aG i2c $USER

Устройство не обнаруживается - проверьте подтяжки SDA/SCL (обычно 4.7 кОм к VCC), питание устройства и правильность распиновки.

irq in STATE_IDLE - сообщение от контроллера Rockchip I2C. Обычно безвредно, возникает когда устройство не отвечает вовремя. Если сканирование проходит - можно игнорировать.