Протокол i2c описание: Интерфейсная шина IIC (I2C) | Электроника для всех

Интерфейсная шина IIC (I2C) | Электроника для всех

Один из моих самых любимых интерфейсов. Разработан в компании Philips и право на его использование стоит денег, но все на это дружно положили и пользуют в свое удовольствие, называя только по другому. В Atmel его зовут TWI, но от этого ничего не меняется 🙂 Обычно при разборе IIC во всех книгах ограничиваются примером с EEPROM на этом и ограничиваются. Да еще юзают софтверный Master. Не дождетесь, у меня будет подробный разбор работы этой шины как в режиме Master так и Slave, да еще на аппаратных блоках с полным выполнением всей структуры конечного автомата протокола. Но об этом после, а сейчас основы.

Физический уровень.
Данные передаются по двум проводам — провод данных и провод тактов. Есть ведущий(master) и ведомый

(slave), такты генерирует master, ведомый лишь поддакивает при приеме байта. Всего на одной двупроводной шине может быть до 127 устройств. Схема подключения — монтажное И

Передача/Прием сигналов осуществляется прижиманием линии в 0, в единичку устанавливается сама, за счет подтягивающих резисторов. Их ставить обязательно всегда! Стандарт! Резисторы на 10к оптимальны. Чем больше резистор, тем дольше линия восстанавливается в единицу (идет перезаряд паразитной емкости между проводами) и тем сильней заваливаются фронты импульсов, а значит скорость передачи падает. Именно поэтому у I2C скорость передачи намного ниже чем у SPI. Обычно IIC работает либо на скорости 10кбит/с — в медленном режиме, либо на 100кбит/с в быстром. Но в реальности можно плавно менять скорость вплоть до нуля.

Ни в коем случае нельзя переключать вывод микроконтроллера в OUT и дергать ногу на +5. Можно запросто словить КЗ и пожечь либо контроллер либо какой-нибудь девайс на шине. Мало ли кто там линию придавит.

Вся передача данных состоит из Стартовой посылки, битов и стоповой посылки. Порядок изменения уровня на шинах задает тип посылки.


После старта передача одного бита данных идет по тактовому импульсу. То есть когда линия SCL в нуле master

или slave выставляют бит на SDA (прижимают — если 0 или не прижимают — если 1 линию SDA) после чего SCL отпускается и master/slave считывают бит. Таким образом, у нас протокол совершенно не зависит от временных интервалов, только от тактовых битов. Поэтому шину I2C очень легко отлаживать — если что то не так, то достаточно снизить скорость до байта в минуту и спокойно, обычными вольтметрами, смотреть что у нас происходит. Правда это не прокатит с железным I2C, там нет таких низких скоростей. Но что нам мешает затактовать микроконтроллер от ОЧЕНЬ медленного тактового генератора и отладить все по шагам? 😉

Повторим для ясности:

  • Начало передачи определяется Start последовательностью — провал
    SDA
    при высоком уровне SCL
  • При передаче информации от Master к Slave, ведущий генерирует такты на SCL и выдает биты на SDA. Которые ведомый считывает когда SCL становится 1.
  • При передачи информации от Slave к Master, ведущий генерирует такты на SCL и смотрит что там ведомый творит с линией SDA — считывает данные. А ведомый, когда SCL уходит в 0, выставляет на SDA бит, который мастер считывает когда поднимет SCL обратно.
  • Заканчивается все STOP последовательностью. Когда при высоком уровне на SCL линия SDA переходит с низкого на высокий уровень.

То есть, изменение на шине данных в момент приема данных может быть только при низком уровне на SCL

. Когда SCL вверху то идет чтение. Если же у нас SDA меняется при высоком SCL, то это уже служебные команды START или STOP.

Если Slave торомоз и не успевает (у EEPROM, например, низкая скорость записи), то он может насильно положить линию SCL в землю и не давать ведущему генерировать новые такты. Мастер должен это понять и дать слейву прожевать байт. Так что нельзя тупо генерить такты, при отпускании SCL надо следить за тем, что линия поднялась. Если не поднялась, то надо остановиться и ждать до тех пор, пока Slave ее не отпустит. Потом продолжить с того же места.

Логический уровень
Как передаются отдельные биты понятно, теперь о том что эти биты значат. В отличии от SPI тут умная адресная структура. Данные шлются пакетами, каждый пакет состоит из девяти бит. 8 данных и 1 бит подтверждения/не подтверждения приема.

Первый пакет шлется от ведущего к ведомому это физический адрес устройства и бит направления.

Сам адрес состоит из семи бит (вот почему до 127 устройств на шине), а восьмой бит означает что будет делать Slave на следующем байте — принимать или передавать данные. Девятым битом идет бит подтверждения

ACK. Если Slave услышал свой адрес и считал полностью, то на девятом такте он придавит линию SDA в 0, сгенерировав ACK — то есть Понял! Мастер, заметя это, понимает, что все идет по плану и можно продолжать. Если Slave не обнаружился, прозевал адрес, неправильно принял байт, сгорел или еще что с ним случилось, то, соответственно, SDA на девятом такте будет прижать некому и ACK не получится. Будет NACK. Мастер с горя хлопнет водки и прекратит свои попытки до лучших времен.

После адресного пакета идут пакеты с данными в ту или другую сторону, в зависимости от бита RW в заголовочном пакете.
Вот, например, Запись. В квадратиках идут номера битов. W=0

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

При приеме последнего байта надо дать ведомому понять, что в его услугах больше не нуждаемся и отослать NACK на последнем байте. Если отослать ACK то после стопа Master не отпустит линию — такой уж там конечный автомат. Так что прием двух байтов будет выглядеть так (R=1):

Есть еще одно состояние, как повторный старт.
Это когда мы не обьявляя STOP вкатываем на шину еще один START. После него мы можем обратиться к другому устройству не освобождая шину. Но чаще идет обращение к тому же самому устройству и это связано с особенностями организации памяти.

Организация памяти.
Это относится уже не столько к самому протоколу

I2C, сколько к заморочкам создателей разных EEPROM и прочих I2C устройств. Но встречается это повсеместно, поэтому я расскажу про этот момент. Но, повторюсь, это не аксиома, не стандарт и вообще зависит от конкретного Slave устройства. Так что датит в зубы и вкуривать, но обычно так принято.

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

Поясню на примере:


Есть микросхема часов реального времени PCF8583 (я про нее еще напишу, следите за обновлениями), общающася по протоколу I2C. Внутри нее ячейки памяти, в которых хранятся часы, минуты, секунды, дата, состояние флагов и куча еще всего. До кучи там еще 240 байт просто так, для свободного пользования. Карта адресов этой микросхемы выглядит так:

И вот надо мне установить дату. Для этого надо мне записать две ячейки памяти с адресами 0х05 и 0x06. Как это сделать? Из даташита я узнаю, что первый байт данных это адрес куда мы будем обращаться, а потом уже идут данные и со следующим байтом счетчик адреса увеличивается на 1. Там же, в даташите, написано что эти часы откликаются на

Slave-адрес 1010000х где х — состояние ноги А0 микросхемы. Я эту ногу сразу посадил на 0 так что Slave-адрес у меня 10100000. Очевидно, что на одной шине может быть не более двух экземпляров этой микросхемы с адресами 10100000 и 10100001.

Задача решается так:

Вот и славно. Часы установлены и начали тикать. Но вот надо нам считать те же данные, а вдруг изменились?
С записью все понятно — записали вначале адрес, а потом следом записали данные. А умная микросхема все прекрасно поняла и рассовала по ячейкам. А с чтением? А с чтением все через задницу, в смысле через запись.

То есть, мы, вначале, записываем один байт — адрес. Потом делаем повторный старт, затем снова обращаемся к часам по ее Slave-адресу, но уже с битом R, на чтение. И умная микруха выдает нам байты с адреса который мы в нее вот только что записали. Выглядит это так:

В этих часах так, у других микрух может быть все по другому, но в 99% очень похоже. Адрес, например, может быть двухбайтным или страницу надо будет указать, но сути это не меняет. Цепочка запись-повстарт-чтение это повсеместно.
Вот так, кстати, выглядит чтение данных из часов PCF8583 на экране моего логического анализатора. Тут не полная посылка (все 5 байт просто не влезли в экран), но тут четко видно запись начального адреса, потом повторный старт, и чтение из девайса.

Скриншот с осциллографа RIGOL 1042CD

Арбитраж шины I2C.
Почему то все мануалы для начинающих в которых рассматривалась тема протокола IIC как то ссыкливо замалчивают возможность работы двух ведущих на линии. Master-Slave и все тут. А если у нас демократия? И каждый сам себе Master и сам себе Slave? Согласен, редкий случай, но тем не менее, описывать так описывать. Короче, в случае подобного садо-мазо варианта действует железное правило — кто раньше встал того и тапки. В смысле кто первый начал вещать тот и текущий Master.

Но вот случилось вообще невероятное — два Ведущих начали вещать одновременно. Прям совсем одновременно. Как быть? А тут нам поможет свойство монтажного И — где против

лома

нуля нет приема. Короче, оба мастера бит за битом играют в простую игру ножик-камень(1 и 0 соответственно). Кто первый выкинет камень против ножика тот и побеждает арбитраж, продолжая вещать дальше. Так что очевидно, что самый важный адрес должен начинаться с нулей, чтобы тот кто к нему пытался обращаться всегда выигрывал арбитраж. Проигравшая же сторона вынуждена ждать пока шина не освободится.

Вроде бы все, практический пример с AVR будет потом, а пока помедитируйте над диаграммой работы конечного автомата TWI передатчика ATmega8. Скоро я вас буду этим грузить!

Страшна? 😉 На самом деле там все не так брутально. Можно обойтись вообще парой десятков строк кода на ассемблере.

UPD:
Полный перевод оригинальной спецификации IIC от суровых Челябинских электронщиков с радиозавода Полет

Подробное описание интерфейса I2C — radiohlam.

ru

Интерфейс I2C (или по другому IIC) — это достаточно широко распространённый сетевой последовательный интерфейс, придуманный фирмой Philips и завоевавший популярность относительно высокой скоростью передачи данных (обычно до 100 кбит/с, в современных микросхемах до 400 кбит/с), дешевизной и простотой реализации.

1) Физика.

Физически сеть представляет собой двухпроводную шину, линии которой называются DATA и CLOCK (необходим ещё и третий провод — земля, но интерфейс принято называть двухпроводным по количеству сигнальных проводов). Соответственно, по линии DATA передаются данные, линия CLOCK служит для тактирования. К шине может быть подключено до 128 абонентов, каждый со своим уникальным номером. В каждый момент времени информация передаётся только одним абонентом и только в одну сторону.

Устройства I2C имеют выход с «открытым коллектором». Когда выходной транзистор закрыт — на соответствующей линии через внешний подтягивающий резистор устанавливается высокий уровень, когда выходной транзистор открыт — он притягивает соответствующую линию к земле и на ней устанавливается низкий уровень (смотрите рисунок). Резисторы имеют номинал от нескольких килоОм до нескольких десятков килоОм (чем выше скорость — тем меньше номинал резисторов, но больше энергопотребление). На рисунке треугольниками на входе показано, что входы высокоомные и, соответственно, влияния на уровни сигналов на линиях они не оказывают, а только «считывают» эти уровни. Обычно используются уровни 5В или 3,3В.

2) Логика.

Любое устройство на шине I2C может быть одного из двух типов: Master (ведущий) или Slave (ведомый). Обмен данными происходит сеансами. «Мастер»-устройство полностью управляет сеансом: инициирует сеанс обмена данными, управляет передачей, подавая тактовые импульсы на линию Clock, и завершает сеанс.

Кроме этого, в зависимости от направления передачи данных и «Мастер» и «Слэйв»-устройства могут быть «Приёмниками» или «Передатчиками». Когда «Мастер» принимает данные от «Слэйва» — он является «Приёмником», а «Слэйв» — «Передатчиком». Когда же «Слэйв» принимает данные от «Мастера», то он уже является «Приёмником», а «Мастер» в этом случае является «Передатчиком».

Не надо путать тип устройства «Мастер» со статусом «Передатчика». Несмотря на то, что при чтении «Мастером» информации из «Слэйва», последний выставляет данные на шину Data, делает он это только тогда, когда «Мастер» ему это разрешит, установкой соответствующего уровня на линии Clock. Так что, хотя «Слэйв» в этом случае и управляет шиной Data, — самим обменом всё равно управляет «Мастер».

В режиме ожидания (когда не идёт сеанс обмена данными) обе сигнальные линии (Data и Clock) находятся в состоянии высокого уровня (притянуты к питанию).

Каждый сеанс обмена начинается с подачи «Мастером» так называемого Start-условия. «Старт-условие» — это изменение уровня на линии Data с высокого на низкий при наличии высокого уровня на линии Clock.

После подачи «Старт-условия» первым делом «Мастер» должен сказать с кем он хочет пообщаться и указать, что именно он хочет — передавать данные в устройство или читать их из него. Для этого он выдаёт на шину 7-ми битный адрес «Слэйв» устройства (по другому говорят: «адресует «Слэйв» устройство»), с которым хочет общаться, и один бит, указывающий направление передачи данных (0 — если от «Мастера» к «Слэйву» и 1 — если от «Слэйва» к «Мастеру»). Первый байт после подачи «Старт»-условия всегда всеми «Слэйвами» воспринимается как адресация.

Поскольку направление передачи данных указывается при открытии сеанса вместе с адресацией устройства, то для того, чтобы изменить это направление, необходимо открывать ещё один сеанс (снова подавать «Старт»-условие, адресовать это же устройство и указывать новое направление передачи).

После того, как «Мастер» скажет, к кому именно он обращается и укажет направление передачи данных, — начинается собственно передача: «Мастер» выдаёт на шину данные для «Слэйва» или получает их от него. Эта часть обмена (какие именно данные и в каком порядке «Мастер» должен выдавать на шину, чтобы устройство его поняло и сделало то, что ему нужно) уже определяется каждым конкретным устройством.

Заканчивается каждый сеанс обмена подачей «Мастером» так называемого Stop-условия, которое заключается в изменении уровня на линии Data с низкого на высокий, опять же при наличии высокого уровня на линии Clock. Если на шине сформировано Stop-условие, то закрываются все открытые сеансы обмена.

Внутри сеанса любые изменения на линии Data при наличии высокого уровня на линии Clock запрещены, поскольку в это время происходит считывание данных «Приёмником». Если такие изменения произойдут, то они в любом случае будут восприняты либо как «Старт»-условие (что вызовет прекращение обмена данными), либо как «Стоп»-условие (что будет означать окончание текущего сеанса обмена). Соответственно, во время сеанса обмена установка данных «Передатчиком» (выставление нужного уровня на линии Data) может происходить
только при низком уровне на линии Clock.

Несколько слов по поводу того, в чём в данном случае разница между «прекращением обмена данными» и «окончанием сеанса обмена». В принципе «Мастеру» разрешается, не закрыв первый сеанс обмена, открыть ещё один или несколько сеансов обмена с этим же (например, как было сказано выше, для изменения направления передачи данных) или даже с другими «Слэйвами», подав новое «Старт»-условие без подачи «Стоп»-условия для закрытия предыдущего сеанса. Управлять линией Data, для того, чтобы отвечать «Мастеру», в этом случае будет разрешено тому устройству, к которому «Мастер» обратился последним, однако старый сеанс при этом нельзя считать законченным. И вот почему. Многие устройства (например те же eeprom-ки 24Схх) для ускорения работы складывают данные, полученные от «Мастера» в буфер, а разбираться с этими полученными данными начинают только после получения сигнала об окончании сеанса обмена (то есть «Стоп-условия»).

То есть, например, если на шине висит 2 микросхемы eeprom 24Cxx и вы открыли сеанс записи в одну микросхему и передали ей данные для записи, а потом, не закрывая этот первый сеанс, открыли новый сеанс для записи в другую микросхему, то реальная запись и в первую и во вторую микросхему произойдёт только после формирования на шине «Стоп-условия», которое закроет оба сеанса. После получения данных от «Мастера» eeprom-ка складывает их во внутренний буфер и ждёт окончания сеанса, для того, чтобы начать собственно процесс записи из своего внутреннего буфера непосредственно в eeprom. То есть, если вы после после передачи данных для записи в первую микруху не закрыли этот сеанс, открыли второй сеанс и отправили данные для записи во вторую микруху, а потом, не сформировав «Стоп-условие», выключили питание, то реально данные не запишутся ни в первую микросхему, ни во вторую. Или, например, если вы пишете данные попеременно в две микрухи, то в принципе вы можете открыть один сеанс для записи в первую, потом другой сеанс для записи во вторую, потом третий сеанс для записи опять в первую и т.д., но если вы не будете закрывать эти сеансы, то в конце концов это приведёт к переполнению внутренних буферов и в итоге к потере данных.

Здесь можно привести такую аналогию: ученики в классе («слэйвы») и учитель («мастер»). Допустим учитель вызвал какого-то ученика (пусть будет Вася) к доске и попросил его решить какой-то пример. После того как Вася этот пример решил, учитель вызвал к доске Петю и начал спрашивать у него домашнее задание, но Васю на место не отпустил. Вот в этом случае вроде бы разговор с Васей закончен, — учитель разговаривает с Петей, но Вася стоит у доски и не может спокойно заниматься своими делами (сеанс общения с ним не закрыт).

В случае, если «Слэйв» во время сеанса обмена не успевает обрабатывать данные, — он может растягивать процесс обмена, удерживая линию Clock в состоянии низкого уровня, поэтому «Мастер» должен проверять возврат линии Clock к высокому уровню после того, как он её отпустит. Хотелось бы подчеркнуть, что не стоит путать состояние, когда «Слэйв» не успевает принимать или посылать данные, с состоянием, когда он просто занят обработкой данных, полученных в результате сеанса обмена. В первом случае (во время обмена данными) он может растягивать обмен, удерживая линию Clock, а во втором случае (когда сеанс обмена с ним закончен) он никакие линии трогать не имеет права. В последнем случае он просто не будет отвечать на «обращение» к нему от «Мастера».

Внутри сеанса передача состоит из пакетов по девять бит, передаваемых в обычной положительной логике (то есть высокий уровень — это 1, а низкий уровень — это 0). Из них 8 бит передаёт «Передатчик» «Приёмнику», а последний девятый бит передаёт «Приёмник» «Передатчику». Биты в пакете передаются старшим битом вперёд. Последний, девятый бит называется битом подтверждения ACK (от английского слова acknowledge — подтверждение). Он передаётся в инвертированном виде, то есть 0 на линии соответствует наличию бита подтверждения, а 1 — его отсутствию. Бит подтверждения может сигнализировать как об отсутствии или занятости устройства (если он не установился при адресации), так и о том, что «Приёмник» хочет закончить передачу или о том, что команда, посланная «Мастером», не выполнена.

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

Вот собственно и всё. На рисунках ниже всё это описание показано в графической форме.

3) Диаграммы и тайминги.


ПараметрОбозн.Мин.знач.Комментарий
Свободная шинаtBUF4,7 мксэто минимальное время, в течении которого обе линии должны находиться в свободном состоянии перед подачей «Старт»-условия
Фиксация
«Старт»- условия
tHD;STA4,0 мксминимальное время от подачи «Старт»- условия до начала первого такта передачи
Готовность
«Стоп»- условия
tSU;STO4,0 мксминимальное время, через которое можно подавать «Стоп»- условие после освобождения шины Clock
Длительность LOW полупер. шины ClocktLOW4,7 мксминимальная длительность полупериода установки данных (когда на шине Clock низкий уровень)
Длительность HIGH полупер. шины ClocktHIGH4,0 мксминимальная длительность полупериода считывания данных (когда на шине Clock высокий уровень)
Удержание данныхtHD;DAT0то есть данные на шину Data можно выставлять сразу после спада на линии Clock
Готовность данныхtSU;DAT250 нсто есть поднимать уровень на шине Clock можно не ранее 250 нс после установки данных на шине Data

Минимальные значения времени в таблице указаны для максимальной скорости передачи 100 кбит/с.

Программная реализация мастер-абонента шины I2C в режиме single-master, библиотеки процедур: для PIC, для AVR

Программа для устройства копирования микросхем памяти 24Cxx (здесь можно посмотреть пример использования приведённых выше библиотек для реализации режима I2C-Master на PIC-контроллере)

Программа 2 для контроллера I2C-шлюза, режим Slave из терминалки ПК (а тут посмотреть пример того, как можно сделать I2C-Slave на контроллере AVR)

Протокол связи I2C — GeeksforGeeks

I2C расшифровывается как Inter-Integrated Circuit. Это протокол подключения интерфейса шины, встроенный в устройства для последовательной связи. Первоначально он был разработан Philips Semiconductor в 1982 году. В последнее время это широко используемый протокол для связи на короткие расстояния. Он также известен как двухпроводной интерфейс (TWI).

Работа протокола связи I2C:
Он использует только 2 двунаправленные линии с открытым стоком для передачи данных, называемые SDA и SCL. Обе эти линии натянуты высоко.

Последовательные данные (SDA) — Передача данных происходит через этот контакт.
Serial Clock (SCL) — Передает тактовый сигнал.

I2C работает в 2 режимах –

  • Ведущий режим
  • Ведомый режим

Каждый бит данных, передаваемый по линии SDA, синхронизируется высоким и низким импульсами каждого тактового сигнала на линии SCL.

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

  1. Стоимость начала — 1 бит
  2. Рабоечный адрес — 8 бит
  3. Благодарность — 1 бит

Стари генерироваться путем поддержания линии SCL на высоком уровне и изменения уровня SDA. Чтобы сгенерировать условие START, SDA изменяется с высокого на низкий при сохранении высокого уровня SCL. Чтобы сгенерировать условие STOP, SDA переходит от низкого уровня к высокому, сохраняя при этом высокий уровень SCL, как показано на рисунке ниже.

Условие пуска и останова

Условие повторного пуска :

Между каждой парой условий пуска и останова шина считается занятой, и ни одно ведущее устройство не может взять на себя управление шиной. Если мастер пытается инициировать новую передачу и не хочет освобождать шину до начала новой передачи, он выдает новое условие СТАРТ. Это называется условием ПОВТОРНОГО ЗАПУСКА.

Бит чтения/записи:

Высокий бит чтения/записи указывает на то, что ведущий отправляет данные подчиненному устройству, тогда как низкий бит чтения/записи указывает на то, что ведущий получает данные от подчиненного устройства.

Бит ACK/NACK :

После каждого кадра данных следует бит ACK/NACK. Если кадр данных получен успешно, то получатель отправляет бит ACK отправителю.

Адресация:

Фрейм адреса — это первый кадр после стартового бита. Адрес ведомого устройства, с которым хочет установить связь мастер, передается мастером каждому связанному с ним ведомому устройству. Затем ведомое устройство сравнивает свой собственный адрес с этим адресом и отправляет ACK.

Формат пакета I2C:

В протоколе связи I2C данные передаются в виде пакетов. Эти пакеты имеют длину 9 бит, из которых первые 8 бит помещаются в строку SDA, а 9-й бит зарезервирован для ACK/NACK, т. е. подтверждения или не подтверждения получателем.

  Условие START плюс адресный пакет плюс еще один пакет данных плюс STOP условие вместе образуют полный Передача данных.

Особенности протокола связи I2C:

  • Полудуплекс Протокол связи –  
    Двунаправленная связь возможна, но не одновременно.
  • Синхронная связь – 
    Данные передаются в виде кадров или блоков.
  • Можно настроить в конфигурации с несколькими ведущими.
  • Растяжка часов —
    Часы растягиваются, когда ведомое устройство не готово принять больше данных, удерживая линию SCL на низком уровне, что не позволяет ведущему поднять линию часов. Мастер не сможет поднять линию синхронизации, потому что провода подключены по И и ждут, пока ведомое устройство не освободит линию SCL, чтобы показать, что оно готово к передаче следующего бита.
  • Арбитраж – 
    Протокол I2C поддерживает систему с несколькими главными шинами, но одновременное использование более одной шины невозможно. SDA и SCL контролируются мастерами. Если SDA оказывается высоким, когда он должен был быть низким, будет сделан вывод, что активен другой мастер, и, следовательно, он останавливает передачу данных.
  • Последовательная передача – 
    I2C использует последовательную передачу для передачи данных.
  • Используется для низкоскоростной связи.

Преимущества:

  • Можно настроить в режиме с несколькими мастерами.
  • Уменьшена сложность, поскольку используются только 2 двунаправленные линии (в отличие от связи SPI).
  • Экономичность.
  • Он использует функцию ACK/NACK, благодаря которой улучшены возможности обработки ошибок.

Ограничения:

  • Низкая скорость.
  • Полудуплексная связь используется в протоколе связи I2C.

Спецификация шины I2C

Типичная встроенная система состоит из одного или нескольких микроконтроллеров и периферийных устройств, таких как память, преобразователи, расширители ввода-вывода, драйверы ЖК-дисплеев, датчики, матричные переключатели и т. д. Сложность и стоимость подключения всех этих устройства вместе должны быть сведены к минимуму. Система должна быть спроектирована таким образом, чтобы более медленные устройства могли взаимодействовать с системой, не замедляя работу более быстрых.

Для удовлетворения этих требований необходима последовательная шина. Шина означает спецификацию соединений, протоколов, форматов, адресов и процедур, которые определяют правила на шине. Это именно то, что определяют спецификации шины I2C.

Шина I2C использует два провода: последовательные данные (SDA) и последовательные часы (SCL). Все ведущие и ведомые устройства I2C подключаются только этими двумя проводами. Каждое устройство может быть передатчиком, приемником или обоими. Некоторые устройства являются ведущими — они генерируют часы шины и инициируют обмен данными по шине, другие устройства являются ведомыми и реагируют на команды на шине. Для связи с конкретным устройством каждое ведомое устройство должно иметь уникальный адрес на шине. Ведущие устройства I2C (обычно микроконтроллеры) не нуждаются в адресе, поскольку никакое другое (ведомое) устройство не отправляет команды ведущему.

Терминология I2C

Передатчик
Это устройство, которое передает данные в шину

Приемник
Это устройство, которое получает данные из шины начинает связь, отправляет команды I2C и прекращает связь

Подчиненное устройство
Это устройство, которое прослушивает шину и к которому обращается ведущий

Мультимастер
I2C может иметь более одного мастера, и каждый может отправлять команды

Арбитраж
Процесс определения того, какой из мастеров на шине может использовать его, когда шину необходимо использовать большему количеству мастеров

Синхронизация
Процесс для синхронизации часов двух или более устройств

Сигналы шины

Оба сигнала (SCL и SDA) являются двунаправленными. Они подключены через резисторы к положительному напряжению питания. Это означает, что когда шина свободна, обе линии имеют высокий уровень. Все устройства на шине должны иметь выводы с открытым коллектором или открытым стоком. Активация линии означает ее опускание (проводное И). Количество устройств на одной шине практически не ограничено — единственное требование — емкость шины не должна превышать 400 пФ. Поскольку уровень логической 1 зависит от напряжения питания, стандартного напряжения на шине нет.

Последовательная передача данных

За каждый тактовый импульс передается один бит данных. Сигнал SDA может изменяться только при низком уровне сигнала SCL — когда тактовый сигнал высокий, данные должны быть стабильными.

Условия запуска и остановки

Каждая команда I2C, инициированная ведущим устройством, начинается с условия ПУСК и заканчивается состоянием СТОП . Для обоих условий SCL должен быть высоким. Переход SDA с высокого уровня на низкий рассматривается как START и переход от низкого к высокому как STOP .

После состояния Start шина считается занятой и может использоваться другим мастером только после обнаружения состояния Stop. После условия Start мастер может генерировать повторный Start. Это эквивалентно обычному запуску и обычно сопровождается подчиненным адресом I2C.

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

Передача данных I2C

Данные по шине I2C передаются 8-битными пакетами (байтами). Количество байтов не ограничено, однако за каждым байтом должен следовать бит подтверждения. Этот бит сигнализирует, готово ли устройство перейти к следующему байту. Для всех битов данных, включая бит подтверждения, мастер должен генерировать тактовые импульсы. Если ведомое устройство не подтверждает передачу, это означает, что данных больше нет или устройство еще не готово к передаче. Ведущее устройство должно генерировать условие остановки или повторного запуска.

Синхронизация

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

Арбитраж

Для нормальной передачи данных по шине I2C может быть активен только один мастер. Если по какой-то причине два мастера инициируют команду I2C одновременно, процедура арбитража определяет, какой мастер выигрывает и может продолжить выполнение команды. Арбитраж выполняется для сигнала SDA, пока сигнал SCL имеет высокий уровень. Каждый мастер проверяет, соответствует ли сигнал SDA на шине сгенерированному сигналу SDA. Если сигнал SDA на шине низкий, а должен быть высоким, то этот мастер проиграл арбитраж. Ведущее устройство I2C, проигравшее арбитраж, может генерировать импульсы SCL до тех пор, пока не закончится байт, а затем должно освободить шину и перейти в подчиненный режим. Арбитражная процедура может продолжаться до тех пор, пока не будут переданы все данные. Это означает, что в системе с несколькими мастерами каждый мастер I2C должен контролировать шину I2C на наличие коллизий и действовать соответствующим образом.

Синхронизация часов и квитирование

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

Связь с 7-битными адресами I2C

Каждое ведомое устройство на шине должно иметь уникальный 7-битный адрес. Коммуникация начинается с условия Start, за которым следует 7-битный адрес подчиненного устройства и бит направления данных. Если этот бит равен 0, то мастер будет писать на ведомое устройство. В противном случае, если бит направления данных равен 1, ведущее устройство будет считывать данные с ведомого устройства. После отправки адреса ведомого устройства и направления данных ведущий может продолжить чтение или запись. Связь завершается состоянием Stop, которое также сигнализирует о том, что шина I2C свободна. Если ведущему необходимо связаться с другими ведомыми, он может сгенерировать повторный запуск с другим адресом ведомого без условия остановки генерации. Все байты передаются со сдвигом старшего бита.

Если ведущее устройство только пишет на ведомое устройство, то направление передачи данных не изменяется.

Если ведущему устройству нужно только читать с ведомого устройства, то он просто отправляет адрес I2C с битом R/W, установленным для чтения. После этого ведущее устройство начинает считывать данные.

Иногда ведущему устройству необходимо записать некоторые данные, а затем прочитать их с ведомого устройства. В таких случаях он должен сначала записать на ведомое устройство, изменить направление передачи данных, а затем прочитать устройство. Это означает отправку адреса I2C с установленным битом R/W для записи, а затем отправку некоторых дополнительных данных, таких как адрес регистра. После завершения записи ведущее устройство генерирует повторное условие запуска и отправляет адрес I2C с битом R/W, установленным для чтения. После этого направление передачи данных меняется, и ведущее устройство начинает чтение данных.

7-битная адресация I2C

Адрес подчиненного устройства может содержать фиксированную и программируемую часть. Некоторые ведомые устройства имеют несколько битов адреса I2C в зависимости от уровня контактов адреса. Таким образом, можно иметь на одной шине I2C более одного устройства I2C с одной и той же фиксированной частью адреса I2C.

Распределением адресов I2C управляет комитет шины I2C, который занимается распределением. Две группы из 8 адресов I2C зарезервированы для будущего использования, а один адрес используется для 10-битной адресации I2C.

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

Стартовый байт

Если микроконтроллер имеет аппаратное обеспечение I2C и микроконтроллер действует как ведомый, тогда программному обеспечению не нужно ничего делать для проверки состояния шины. Аппаратное обеспечение I2C обнаружит состояние запуска, получит адрес I2C и при необходимости прервет работу программного обеспечения. Однако, если интерфейс I2C реализован программным обеспечением, микроконтроллер должен опрашивать линию SDA не менее двух раз за тактовый импульс, чтобы обнаружить изменения. Чтобы упростить обнаружение команд I2C на шине в таких случаях, используется специальный адрес I2C, называемый стартовым байтом. За таким стартовым байтом (0000 0001) следует импульс подтверждения (из соображений совместимости интерфейса). Эта комбинация удерживает линию SDA на низком уровне в течение 7 тактовых импульсов и позволяет легко обнаруживать активную шину I2C с более низкой частотой дискретизации.

Расширение спецификаций I2C

Стандартный режим шины I2C использует скорость передачи до 100 кбит/с и 7-битную адресацию. Такой интерфейс I2C используется многими сотнями I2C-совместимых устройств от многих производителей с момента его появления в 80-х годах. Однако с развитием технологии возникла потребность в более высоких скоростях передачи и большем адресном пространстве. Бывают случаи, когда необходимо передать большой объем данных. Многие сложные встроенные платы содержат большое количество различных устройств I2C. В некоторых случаях очень трудно избежать конфликтов адресов, поскольку 7 битов для адресов I2C позволяют использовать только 127 различных адресов, из которых фактически можно использовать только 112. Некоторые устройства I2C на плате, несмотря на адресные контакты, имеют одинаковый адрес. Это привело к нескольким обновлениям спецификаций I2C стандартного режима:

  • Быстрый режим — поддерживает скорость передачи до 400 кбит/с
  • Высокоскоростной режим (Hs-режим) — поддерживает скорость передачи до 3,4 Мбит/с
  • 10-битная адресация — поддерживает до 1024 адресов I2C

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

Высокоскоростной режим использует сигналы, называемые SCLH и SDAH, чтобы подчеркнуть более высокую скорость. Эти сигналы обычно отделены от стандартных линий SDA и SCL. Высокоскоростной режим также имеет несколько отличий (или улучшений) в спецификациях:

  • Улучшенные драйверы вывода данных и тактовой линии
  • Схемы триггера Шмитта и подавления выбросов на входах данных и тактовых импульсов
  • Синхронизация часов и арбитраж не используются
  • Тактовый сигнал имеет отношение высокого/низкого уровня 1 к 2

10-битная адресация I2C

10-битная адресация может использоваться вместе с 7-битной адресацией, поскольку специальный 7-битный адрес (1111 0XX) используется для передачи 10-битного адреса I2C.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *