Интерфейс I2C (IIC)



I2C (также известная как InterIC, IIC, I2C) — разработанная компанией Philips последовательная шина для низкоскоростной (до 100 кбит/с в стандартном режиме и 400 кбит/с в «быстром» режиме) передачи 8-битных данных между микроконтроллерами (или процессорами) и периферийными компонентами, такими как различные датчики, драйверы, ОЗУ, АЦП и тому подобное.
Использование данного стандарта для передачи данных позволяет минимизировать количество соединения между интегральными схемами и, как следствие, уменьшить у них количество необходимых контактов и дорожек. Также интегрированный I2C-протокол устраняет необходимость в дешифраторах адреса и другой внешней логике согласования.

Для передачи информации используется всего две линии:

  • SDA — линия данных
  • SCL — линия синхронизации.

Каждое устройство определяется как ведущее или ведомое, а также обладает уникальным (в пределах шины) адресом. Максимальное допустимое количество элементов, подсоединённых к одной шине, ограничивается максимальной емкостью шины — 400 пФ.

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

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


Принцип работы

Начало и завершение обмена данными

Обмен данными, как уже было сказано, инициируется ведущим устройством. Оно генерирует тактирующие сигналы на линии SCL, которые имеют определенную периодичность, но могут быть задержаны приемником, если он еще не готов принят следующий байт данных.
В исходном состоянии обе линии SDA и SCL находятся в высоком состоянии.
Процедура обмена данными начинается с формирования ведущим устройством состояния СТАРТ: переход состояния линии SDA с высокого на низкое при высоком состоянии на линии SCL.
Процедура обмена данными заканчивается, когда ведущий формирует состояние СТОП: переход состояния линии SDA с низкого на высокое при высоком состоянии на линии SCL.


I2C. Состояния СТАРТ и СТОП

Обмен данными

Данные передаются изменением уровня сигнала на линии SDA в определенной последовательности. Обмен данными происходит байтами, каждый из которых состоит из 8-ми бит. За один сеанс может быть передано неограниченное количество байт.
После формирования состояния СТАРТ и до появления состояния СТОП изменять уровень на линии SDA можно только при низком состоянии на тактирующей линии SCL. Бит информации «читается» приёмником только когда на линии SCL установлен высокий уровень сигнала, поэтому в этот момент на линии SDA сигнал должен быть неизменным и стабильным. Принятые данные считаются действительными, только если соблюдается это правило.


I2C. Обмен данными

Подтверждение приема данных

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


I2C. Бит подтверждения

Адресация

Логично, что перед обменом данными ведущее устройство должно определить с каким ведомым устройством планируется работа в этом сеансе. Т.е. ведущий должен адресовать необходимого ведомого, «позвать его по имени». Для этого ведущее устройство, сразу после установки состояния СТАРТ, отправляет по шине специальный байт информации, первые 7 бит которого содержат адрес ведомого (в обычном режиме), а 8-й бит (бит направления) — информацию о направлении передачи.
Как уже отмечалось выше, каждое устройство в шине I2C должно иметь уникальный адрес, но также в системе предусмотрен адрес «общего вызова» для обращения ко всем ведомым сразу. Адрес ведомого может состоять из фиксированной и программируемой частей. После отправки адресного байта по шине, каждое устройство в системе сравнивает первые семь бит после сигнала СТАРТ со своим адресом. Если адреса совпали, устройство считает себя выбранным как ведомый-приёмник или как ведомый-передатчик, в зависимости от состояния бита направления:

  • низкий уровень («0») означает, что ведущий будет отправлять информацию ведомому
  • высокий («1») означает, что ведущий будет получать информацию от ведомого.

Из спецификации шины следует, что допускаются не только простые форматы обмена, но и комбинированные, когда в промежутке от состояния СТАРТ до состояния СТОП ведущий и ведомый могут выступать и как приемник и как передатчик данных. Комбинированные форматы могут быть использованы, например, для управления последовательной памятью.

Типичный сеанс обмена данными по шине I2C проиллюстрирован на следующем изображении:


I2C. Сеанс обмена данными
I2C. Направления обмена сигналами


Как узнать I2C адрес устройства?

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