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

Для использования интерфейса понадобиться двухпроводная линия данных и общая линия GND. Линии называются DATA и CLOCK. Линия DATA — по ней передаются/принимаются данные. Линия CLOCK необходима для тактирования. Общее количество абонентов подключаемых к линиям может достигать 128.

Главное устройство называется master ведомое как slave. Генерация тактов осуществляется мастером. Ведомое устройство уведомляет мастера о том что принял байт данных.  У каждого абонента должен быть свой уникальный номер. Информация может передаваться только одним абонентом в одну сторону и в определенный временной интервал

Подключаемы к линиям устройства имеют выход с «открытым коллектором». В случае если выходной транзистор закрыт, на линии к которой он подключен через резистор устанавливается высокий уровень. Высокий уровень это обычно 5 В и 3.3 В. А если выходной транзистор открыт то линия притягивается к земле. Резисторы обычно имеют номинал до нескольких десятков кОм. Эти резисторы нужно ставить обязательно. Чем меньше номинал резисторов тем выше скорость передачи данных и больше потребляемая энергия.  Самое оптимальным значение сопротивления 10 кОм. Скорость передачи данных по I2C намного меньше чем по интерфейсу SPI.

 

Прием и передача данных по I2C

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

Порядок изменения уровня на шинах задает тип посылки.

После старта передача одного бита данных идет по тактовому импульсу. Другими словами когда линия SCL в низком уровне master или slave устанавливают бит на SDA. Прижимают — в случае 0 или не прижимают — если 1 линию SDA. После этого SCL отпускается и master или slave берут и считывают бит. Получается так что протокол совершенно не зависит от временных интервалов, только от тактовых битов. По этой причине шину I2C очень легко настаивать— для это нужно просто снизить скорость до к примеру 1 байта в минуту и при помощи вольтметра смотреть что происходит.

Если подытожить то передача данных по протоколу I2c происходит следующим образом:

Начало передачи определяет старт последовательность— провал 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 притормаживает, он может сделать так что линия SCL притянется к земле и в результате ведущий не сможет генерировать новые такты. Поэтому мастер должен понять это и дать слейву проработать байт. Поэтому нельзя слепо генерировать такты, при отпускании SCL нужно проверить а поднялась ли она. Если она в низком состоянии то нужно стопануться и подожать пока ведомое устройство ее не отпустит. Далее продолжить с того же места.

Логический уровень

О том как передаются биты стало понятно, теперь нужно разобраться а что же эти биты значат. В интерфейсе I2C добровольно продуманная  адресная структура в отличии от интерфейса SPI. Передача данных осуществляется пакетами данных. Пакет состоит из 1 бита отвечающего за подтверждение/не подтверждения  приемы и 8 бит данных.

Первый пакет данных идет от master к slave, в котором содержится физический адрес устройства и бит направления.

Адрес устройства состоит из 7 бит , и 8-й определяет что будет делать slave на следующем байте данных-либо передавать либо принимать данные.

Устройства подключенный к шине I2C могу работать в двух режимах Master (ведущий) или Slave (ведомый). Передача данных осуществляется сеансами. Ведущий девайс может полностью управлять сеансом:

  • начинает сеанс обмена данными;
  • контролирует передачу подавая тактовые импульсы на линию Clock;
  • завершает сеанс.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

Видео

Похожие записи

Память микроконтроллера. Виды памяти микроконтроллеров

Практически все современные микроконтроллеры имеют на своем борту 3 вида  памяти: Виды памяти микроконтроллеров память программ FLASH; оперативная память (ОЗУ) SRAM (Static RAM); ...

Светодиодная мигалка на микросхеме NE 555

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

Схема полицейской мигалки на микроконтроллере

Представленная схема полицейской мигалки на микроконтроллере и светодиодах может работать в 16 различных режимах. Режим выбирается при помощи одной кнопки, и собрана на микроконтроллере...

Последовательный интерфейс I2C

Последовательный интерфейс I2C (также его обозначается как IIC) довольно популярный последовательный интерфейс. Свою популярность он получил за неплохую скорость передачи информации. В...

Последовательный периферийный интерфейс SPI

Последовательный периферийный интерфейс SPI (Serial Peripheral Interface) — последовательный стандарт передачи данных. Предназначен для сопряжения микроконтроллеров и периферийных устройств. SPI...

Подключение кнопки к микроконтроллеру AVR

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

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