Для чего шина i2c

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

Для чего шина i2c

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

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

Любое устройство на шине 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 установлен высокий уровень, используется принимающим абонентом для считывания установленного значения бита с шины данных.

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

Для чего шина i2c
Для чего шина i2c

ПараметрОбозн.Мин.знач.Комментарий
Свободная шина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Скачать

Введение в шину I2C

Как настроить I2C-связь на Arduino

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

Видео:Лекция 308. Шина I2CСкачать

Лекция 308.  Шина I2C

Что такое I2C?

c — это аббревиатура от Inter-Integrated Circuit (меж-интеграционная цепь или последовательная асимметричная шина).

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

Для чего шина i2c

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

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

Многие датчики и модули, предназначенные для Arduino используют I2C для связи.

Видео:Шина I2C.Скачать

Шина I2C.

Сеть I2C

Сеть I2C состоит из ведущего и ведомого устройств, соединенных шиной. В сети I2C может быть несколько ведущих и ведомых устройств — мастеров и наследников.

Ведомое устройство (наследник)

Все ведомые устройства имеют I2C-адрес, который используется для идентификации устройства в сети. I2C-адрес позволяет ведущему устройству передавать данные конкретному ведомому устройству на шине.

Ведущее устройство (мастер)

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

Шина в I2C — это просто два провода, которые соединяют все I2C-устройства в сети.

Эти два провода называются SDA и SCL. Провод SDA используется для связи между ведущим и ведомым устройствами.

Линия SCL несет тактовый сигнал, используемый для правильной синхронизации связи. Для поддержания обоих проводов в состоянии HIGH необходимы импульсные или подтягивающие (pull-up) резисторы.

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

Будьте внимательны при подключении I2C устройств к Arduino.

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

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

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

Видео:Логический анализатор шины i2cСкачать

Логический анализатор шины i2c

Использование I2C

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

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

Один Arduino будет выступать в качестве мастера, а другой Arduino будет выступать в качестве ведомого.

Пины I2C Arduino

Arduino имеет специальные контакты для I2C, которые имеют встроенные подтягивающие резисторы в соответствии с требованиями протокола I2C.

Для плат Arduino Uno это контакты A4 и A5. Пин A4 — это контакт SDA, а пин A5 — это контакт SCL. В версии Arduino Uno R3 есть еще один набор контактов I2C рядом с USB-разъемом:

Для чего шина i2c

Компоненты оборудования

Чтобы создать этот проект, вам понадобятся следующие компоненты:

Схема соединения

После того, как вы соберете все детали, пришло время собрать проект. Следуйте нижеприведенной электрической схеме, чтобы все подключить:

Для чего шина i2c

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

Видео:Шина данных i2c - декодируем/синхронизируем с помощью осциллографа Lecroy!Скачать

Шина данных i2c - декодируем/синхронизируем   с помощью осциллографа Lecroy!

Скетч для мастера

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

Теперь откройте Arduino IDE и загрузите код ниже на мастер Arduino:

Видео:25 Шина I2CСкачать

25 Шина I2C

Объяснение скетча для мастера

Основная часть кода как для ведущего, так и для ведомых устройств — это то, что я называю логическим кодом мигания. Чтобы мигнуть светодиодом 13 на Ардуино, мы должны сделать следующее:

  • Добавим глобальные переменные byte i2c_rcv , int time_start , stat_LED и byte value_pot в верхней части нашего скетча
  • Инициализируйте значения глобальных переменных внутри функции setup()
  • Инициализируйте контакт 13 Arduino как выходной контакт внутри setup() с помощью pinMode()
  • Добавим код логики мигания внутри функции loop()

Читайте также: Грузовые шины в нижнем тагиле автопартнер

Библиотека Wire

Для использования встроенного интерфейса I2C Arduino мы будем использовать библиотеку Wire.

Эта библиотека поставляется в стандартной комплектации с Arduino IDE. Как и в других библиотеках Arduino, библиотека Wire имеет готовые I2C функции, чтобы сделать кодирование проще для нас.

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

После включения библиотеки мы можем использовать встроенные функции библиотеки.

Первое, что нужно сделать, это подключить устройство к шине I2C. Синтаксис для этого — Wire.begin(address) . Адрес является необязательным для мастер-устройств. Итак, для эскиза мастера Arduino, мы просто добавляем код Wire.begin(); внутри setup() .

Теперь мы переходим к циклу loop() . Наш код заставит Arduino прочитать значение потенциометра, подключенного к контакту A0, и сохранить его в переменной value_pot .

Отправка данных

После сохранения значения с пина A0 в переменную value_pot , мы можем отправить значение по I2C. Отправка данных по I2C включает в себя три функции:

  • Wire.beginTransmission()
  • Wire.write()
  • Wire.endTransmission()

Wire.beginTransmission()

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

Для этого мы вызываем функцию Wire.beginTransmission(address) . Адрес — это I2C-адрес ведомого прибора, который будет принимать данные. Эта функция делает две вещи:

  1. Она информирует шину о том, что мы будем посылать данные.
  2. Он информирует предполагаемого получателя о том, что данные готовы к получению.

Wire.write()

А затем мы отправим значение переменной value_to_send с помощью функции Wire.write(value) .

Wire.endTransmission()

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

Наше ведущее устройство также должно получить положение потенциометра от ведомого устройства. Мы делаем это с помощью Wire.requestFrom() , Wire.available() и Wire.read() .

Wire.requestFrom()

Полным синтаксисом запроса данных от ведомого устройства является Wire.requestFrom(адрес, количество).

Адрес — это I2C-адрес ведомого устройства, от которого мы должны получить данные, а количество — это количество байтов, которое нам нужно. Для нашего проекта, адрес ведомого устройства 0x08 и нам нужен один байт.

Внутри loop() мы используем Wire.requestFrom(0x08, 1); для запроса одного байта данных от ведомого устройства 0x08.

После выдачи команды Wire.requestFrom(0x08, 1) , за ней должна следовать команда чтения для получения ответа от шины I2C.

Write.available()

Сначала мы проверяем, есть ли данные на шине. Это делается с помощью функции Write.available() внутри условного оператора if() . Функция Write.available() возвращает количество байт, ожидающих чтения.

Wire.read();

Для получения доступных данных мы используем функцию Wire.read() и сохраняем возвращаемое значение в переменную i2c_rcv . Каждый вызов функции Wire.read() получает только один байт данных из шины I2C.

Видео:Что такое I2C ??? Подключаем GY-521 и Oled 96*16 к STM 32Скачать

Что такое I2C ??? Подключаем GY-521 и Oled 96*16 к STM 32

Скетч для наследника (ведомого)

Теперь загрузите этот код ведомому Ардуино:

Видео:Урок 24. Узнаём адреса устройств на шине I2CСкачать

Урок 24. Узнаём адреса устройств на шине I2C

Объяснение скетча для ведомого

Для ведомого устройства существует небольшая разница в кодировании I2C-связи. Первая разница заключается в адресе Wire.begin(address) .

Для ведомых устройств адрес является обязательным. Для нашего проекта адрес для ведомого устройства будет 0x08. Это может быть любой адрес, но убедитесь, что он уникален в сети I2C.

Некоторые I2C ведомые устройства также имеют определенные I2C-адреса, поэтому сначала проверьте спецификацию.

Мы присоединим I2C сеть в качестве ведомого устройства, добавив код Wire.begin(0x08); внутри setup() .

Обработчики событий

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

Обработчики событий — это части кода, которые управляют событиями, с которыми наше устройство, скорее всего, столкнется во время работы.

Wire.onReceive()

В части скетча setup() мы добавляем функцию Wire.onReceive(handler) для регистрации функции (обработчика), которая будет управлять полученными данными.

Мы вызываем нашу функцию-обработчик dataRcv() . Обратите внимание, что имя функции может быть любым. В приведенном выше эскизе Wire.onReceive(dataRcv); вызывается в секции setup() .

В конце эскиза находится код функции-обработчика. Он инициализируется как void dataRcv(int numBytes) . Параметр int numBytes содержит количество байт полученных данных.

Wire.onRequest()

Следующий обработчик события, который мы будем использовать — Wire.onRequest(handler) . Эта функция используется на подчиненных устройствах и работает аналогично Wire.onReceive() .

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

В функцию setup() мы добавляем код Wire.onRequest(dataRqst); . А в конце нашего эскиза добавляем функцию void dataRqst() . Обратите внимание, что обработчики Wire.onRequest() не принимают никаких параметров. Функция dataRqst() содержит только Wire.write() .

Нам не нужны Wire.beginTransmission() и Wire.endTransmission() , потому что библиотека Wire уже обрабатывает ответы от ведомых устройств.

Видео:I2c шина в iPhone, способы диагностики, причины циклического перезапуска.Скачать

I2c шина в iPhone, способы диагностики, причины циклического перезапуска.

Тестирование Arduino I2C

А вот и самая захватывающая часть — включение питания и тестирование!

Используя Arduino IDE, загрузите эскиз мастера Arduino в одну из Ардуино. Затем загрузите скетч наследника в другую Arduino.

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

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

  • Свежие записи
    • Нужно ли менять пружины при замене амортизаторов
    • Скрипят амортизаторы на машине что делать
    • Из чего состоит стойка амортизатора передняя
    • Чем стянуть пружину амортизатора без стяжек
    • Для чего нужны амортизаторы в автомобиле
    • Правообладателям
    • Политика конфиденциальности


    📸 Видео

    Подключение нескольких устройств, датчиков по I2C (АйТуСи) шинеСкачать

    Подключение нескольких устройств, датчиков по I2C (АйТуСи) шине

    STM32: Интерфейсная шина I2C. Подключаем HDC1080.Скачать

    STM32: Интерфейсная шина I2C. Подключаем HDC1080.

    Шина I2CСкачать

    Шина I2C

    Видеоуроки по Arduino. I2C и processing (7-я серия, ч1)Скачать

    Видеоуроки по Arduino. I2C и processing (7-я серия, ч1)

    Лекция "Интерфейсы (часть II). I2C. 1-Wire"Скачать

    Лекция "Интерфейсы (часть II). I2C. 1-Wire"

    I2C. Краткая теория с примером. STM32 CubeIDE.Скачать

    I2C. Краткая теория с примером. STM32 CubeIDE.

    Урок 9. Адреса модулей на шине I2C. Arduino (что такое I2C, адресация, как изменить адрес модуля)Скачать

    Урок 9. Адреса модулей на шине I2C. Arduino (что такое I2C, адресация, как изменить адрес модуля)

    Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED I2C, TJA 1020Скачать

    Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED  I2C, TJA 1020

    I2C интерфейсСкачать

    I2C интерфейс

    Подключение нескольких устройств по шине i2cСкачать

    Подключение нескольких устройств по шине i2c

    Установщик адресов Flash-i2cСкачать

    Установщик адресов Flash-i2c
Поделиться или сохранить к себе:
Технарь знаток