I 2 C – двухпроводной интерфейс, разработанный корпорацией Philips. В первоначальном техническом требовании к интерфейсу максимальная скорость передачи данных составляла 100 Кбит/с. Однако со временем появились стандарты на более скоростные режимы работы I 2 C. К одной шине I 2 C могут быть подключены устройства с различными скоростями доступа, так как скорость передачи данных определяется тактовым сигналом.
Протокол передачи данных разработан таким образом, чтобы гарантировать надежный прием передаваемых данных.
При передаче данных одно устройство является «Master», которое инициирует передачу данных и формирует сигналы синхронизации. Другое устройство «Slave» — начинает передачу только по команде, пришедшей от «Master».
В микроконтроллерах PIC16CXXX аппаратно реализован режим «Slave» устройства в модуле SSP. Режим «Master» реализуется программно.
Основные термины, используемые при описании работы с шиной I 2 C:
Передатчик – устройство, передающее данные по шине
Приемник – устройство, получающее данные с шины
«Master» — устройство, которое инициирует передачу и формирует тактовый сигнал
«Slave» — устройство, к которому обращается «Master»
Multi-«Master» — режим работы шины I 2 C с более чем одним «Master»
Арбитраж – процедура, гарантирующая, что только один «Master» управляет шиной
Синхронизация – процедура синхронизации тактового сигнала от двух или более устройств
Выходные каскады формирователей сигналов синхронизации (SCL) и данных (SDA) должны быть выполнены по схемам с открытым коллектором (стоком) для объединения нескольких выходов и через внешний резистор подключены к плюсу питания для того, чтобы на шине был уровень «1», когда ни одно устройство не формирует сигнал «0». Максимальная емкостная нагрузка ограничена емкостью 400 пФ.
Инициализация и завершение передачи данных
В то время, когда передача данных на шине отсутствует, сигналы SCL и SDA имеют высокий уровень за счет внешнего резистора.
Сигналы START и STOP формируются «Master» для определения начала и окончания передачи данных соответственно.
Сигнал START формируется переходом сигнала SDA из высокого уровня в низкий при высоком уровне сигнала SCL. Сигнал STOP определяется как переход SDA из низкого уровня в высокий при высоком уровне SCL. Таким образом, при передаче данных сигнал SDA может изменяться только при низком уровне сигнала SCL.
Адресация устройств на шине I 2 C
Для адресации устройств используется два формата адреса:
Простой 7-разрядный формат с битом чтения/записи R/W;
и 10-разрядный формат – в первом байте передается два старших бита адреса и бит записи/чтения, во втором байте передается младшая часть адреса.
Подтверждение приема
При передаче данных после каждого переданного байта приемник должен подтвердить получение байта сигналом ACK.
Если «Slave» не подтверждает получение байта адреса или данных, «Master» должен прервать передачу, сформировав сигнал STOP.
При передаче данных от «Slave» к «Master», «Master» формирует сигналы подтверждения приема данных ACK. Если «Master» не подтвердит приема байта, «Slave» прекращает передачу данных, «отпуская» линию SDA. После этого «Master» может сформировать сигнал STOP.
Для задержки передачи данных «Slave» может установить логический нуль, указывая «Master» о необходимости ожидания. После «отпускания» линии SCL передача данных продолжается.
Передача данных от «Master» к «Slave»
Чтение данных из «Slave»
Использование сигнала повторного START для обращения к «Slave»
Режим Multi-«Master»
Протокол передачи данных I 2 C позволяет иметь более одного «Master» на шине. Для разрешения конфликтов на шине при инициализации передачи используются функции арбитража и синхронизации.
Арбитраж выполняется на линии SDA при высоком уровне линии SCL. Устройство, которое формирует на линии SDA высокий уровень когда другое передает низкий, теряет право брать «Master» и должно перейти в режим «Slave». «Master», потерявший инициативу на шине, может формировать тактовые импульсы до конца байта, в котором потерял свойства ведущего.
Синхронизация
Синхронизация на шине происходит после выполнения арбитража по отношению к сигналу SCL. При переходе сигнала SCL с высокого уровня в низкий, все заинтересованные устройства начинают отсчитывать длительность низкого уровня. Затем устройства начинают переводить уровень SCL из низкого в высокий согласно требуемой скорости передачи данных. После перехода уровня из низкого в высокое состояние, заинтересованные устройства отсчитывают длительность высокого уровня. Первое устройство, которое переведет сигнал SCL в низкий уровень, определяет параметры тактового сигнала.
- Интерфейс I2C и Arduino
- Инструкция по использованию протокола I 2 C совместно с Arduino
- Нам понадобится:
- 1 Описание интерфейса I2C
- 2 Реализация I2Cв Arduino
- 3 Библиотека «Wire» для работы с IIC
- 4 Подключение I2C устройствак Arduino
- 5 Управление устройством по шине IIC
- 6 Дополнительно о шине I2C
- Как настроить I2C-связь на Arduino
- Что такое I2C?
- Сеть I2C
- Ведомое устройство (наследник)
- Ведущее устройство (мастер)
- Логические уровни
- Использование I2C
- Пины I2C Arduino
- Компоненты оборудования
- Схема соединения
- Скетч для мастера
- Объяснение скетча для мастера
- Библиотека Wire
- Отправка данных
- Wire.beginTransmission()
- Wire.write()
- Wire.endTransmission()
- Wire.requestFrom()
- Write.available()
- Wire.read();
- Скетч для наследника (ведомого)
- Объяснение скетча для ведомого
- Обработчики событий
- Wire.onReceive()
- Wire.onRequest()
- Тестирование Arduino I2C
- 🔥 Видео
Видео:Подключение нескольких устройств по шине i2cСкачать
Интерфейс I2C и Arduino
Видео:Введение в шину I2CСкачать
Инструкция по использованию протокола I 2 C совместно с Arduino
Нам понадобится:
- Arduino UNO или другая совместимая;
- цифровой потенциометр AD5171 или другой с управлением по шине IIC;
- светодиод любой (к примеру, вот из такого набора);
- резистор на 220 Ом (рекомендую набор резисторов с номиналами от 10 Ом до 1 МОм);
- 2 резистора по 4,7 кОм (из того же набора);
- макетная плата;
- соединительные провода (например, вот хороший набор);
- компьютер с Arduino IDE.
Видео:Подключение нескольких устройств, датчиков по I2C (АйТуСи) шинеСкачать
1 Описание интерфейса I2C
Последовательный протокол обмена данными IIC (также называемый I2C – Inter-Integrated Circuits, межмикросхемное соединение) использует для передачи данных две двунаправленные линии связи, которые называются шина последовательных данных SDA (Serial Data) и шина тактирования SCL (Serial Clock). Также имеются две линии для питания. Шины SDA и SCL подтягиваются к шине питания через резисторы.
Читайте также: Шины isa pci usb
В сети есть хотя бы одно ведущее устройство (Master), которое инициализирует передачу данных и генерирует сигналы синхронизации. В сети также есть ведомые устройства (Slave), которые передают данные по запросу ведущего. У каждого ведомого устройства есть уникальный адрес, по которому ведущий и обращается к нему. Адрес устройства указывается в паспорте (datasheet). К одной шине I2C может быть подключено до 127 устройств, в том числе несколько ведущих. К шине можно подключать устройства в процессе работы, т.е. она поддерживает «горячее подключение».
Давайте рассмотрим временную диаграмму обмена по протоколу I2C. Есть несколько различающихся вариантов, рассмотрим один из распространённых. Воспользуемся логическим анализатором, подключённым к шинам SCL и SDA.
Мастер инициирует обмен. Для этого он начинает генерировать тактовые импульсы и посылает их по линии SCL пачкой из 9-ти штук. Одновременно на линии данных SDA он выставляет адрес устройства, с которым необходимо установить связь, которые тактируются первыми 7-ми тактовыми импульсами (отсюда ограничение на диапазон адресов: 2 7 = 128 минус нулевой адрес). Следующий бит посылки – это код операции (чтение или запись) и ещё один бит – бит подтверждения (ACK), что ведомое устройство приняло запрос. Если бит подтверждения не пришёл, на этом обмен заканчивается. Или мастер продолжает посылать повторные запросы.
Это проиллюстрировано на рисунке ниже. Задача такая: подключиться к ведомому устройству с адресом 0x27 и передать ему строку «SOLTAU.RU». В первом случае, для примера, отключим ведомое устройство от шины. Видно, что мастер пытается установить связь с устройством с адресом 0x27, но не получает подтверждения (NAK). Обмен заканчивается.
Попытка мастера установить соединение с ведомым по I2C
Теперь подключим к шине I2C ведомое устройство и повторим операцию. Ситуация изменилась. На первый пакет с адресом пришло подтверждение (ACK) от ведомого. Обмен продолжился. Информация передаётся также 9-битовыми посылками, но теперь 8 битов занимают данные и 1 бит – бит подтверждения получения ведомым каждого байта данных. Если в какой-то момент связь оборвётся и бит подтверждения не придёт, мастер прекратит передачу.
Временная диаграмма обмена по протоколу I2C
Видео:Урок 26.3 Соединяем две arduino по шине I2C #iarduinoСкачать
2 Реализация I2Cв Arduino
Arduino использует для работы по интерфейсу I2C два порта. Например, в Arduino UNO и Arduino Nano аналоговый порт A4 соответствует SDA, аналоговый порт A5 соответствует SCL.
Реализация I2C в Arduino UNO и Nano
Для других моделей плат соответствие выводов такое:
Плата | Пин SDA | Пин SCL |
---|---|---|
Arduino Uno, Nano, Pro и Pro Mini | A4 | A5 |
Arduino Mega | 20 | 21 |
Arduino Leonardo | 2 | 3 |
Arduino Due | 20, SDA1 | 21, SCL1 |
Видео:Урок 24. Узнаём адреса устройств на шине I2CСкачать
3 Библиотека «Wire» для работы с IIC
Для облегчения обмена данными с устройствами по шине I2C для Arduino написана стандартная библиотека Wire. Она имеет следующие функции:
Функция | Назначение |
---|---|
begin(address) | инициализация библиотеки и подключение к шине I2C; если не указан адрес, то присоединённое устройство считается ведущим; используется 7-битная адресация; |
requestFrom() | используется ведущим устройством для запроса определённого количества байтов от ведомого; |
beginTransmission(address) | начало передачи данных к ведомому устройству по определённому адресу; |
endTransmission() | прекращение передачи данных ведомому; |
write() | запись данных от ведомого в ответ на запрос; |
available() | возвращает количество байт информации, доступных для приёма от ведомого; |
read() | чтение байта, переданного от ведомого ведущему или от ведущего ведомому; |
onReceive() | указывает на функцию, которая должна быть вызвана, когда ведомое устройство получит передачу от ведущего; |
onRequest() | указывает на функцию, которая должна быть вызвана, когда ведущее устройство получит передачу от ведомого. |
Видео:Логический анализатор шины i2cСкачать
4 Подключение I2C устройствак Arduino
Давайте посмотрим, как работать с шиной I2C с помощью Arduino.
Сначала соберём схему, как на рисунке. Будем управлять яркостью светодиода, используя цифровой 64-позиционный потенциометр AD5171 (см. техническое описание), который подключается к шине I2C. Адрес, по которому мы будем обращаться к потенциометру – 0x2c (44 в десятичной системе).
Подключение цифрового потенциометра к Arduino по шине I2C
Видео:Урок 9. Адреса модулей на шине I2C. Arduino (что такое I2C, адресация, как изменить адрес модуля)Скачать
5 Управление устройством по шине IIC
Рассмотрим диаграммы информационного обмена с цифровым потенциометром AD5171, представленные в техническом описании:
Рассмотрим диаграммы чтения и записи цифрового потенциометра AD5171
Нас тут интересует диаграмма записи данных в регистр RDAC. Этот регистр используется для управления сопротивлением потенциометра.
Откроем из примеров библиотеки «Wire» скетч: Файл Образцы Wire digital_potentiometer. Загрузим его в память Arduino.
После включения вы видите, как яркость светодиода циклически нарастает, а потом гаснет. При этом мы управляем потенциометром с помощью Arduino по шине I2C.
По ссылкам внизу статьи, в разделе похожих материалов (по тегу), можно найти дополнительные примеры взаимодействия с различными устройствами по интерфейсу IIC, в том числе примеры чтения и записи.
Видео:Лекция 308. Шина I2CСкачать
6 Дополнительно о шине I2C
Доступно и интересно рассказывает о шине I2C Джереми Блюм в своём видео:
Читайте также: Шины 335 30 r18
Видео:MCP2515, контроллер CAN шины с интерфейсом SPIСкачать
Как настроить I2C-связь на Arduino
В этом уроке мы обсудим, что такое протокол связи I2C, как он работает и как его использовать на Arduino. Для демонстрации мы построим проект, использующий I2C-соединение для обмена данными между двумя микроконтроллерами Arduino.
Видео:Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED I2C, TJA 1020Скачать
Что такое I2C?
c — это аббревиатура от Inter-Integrated Circuit (меж-интеграционная цепь или последовательная асимметричная шина).
I2C — низкоскоростной последовательный протокол связи, подходящий для передачи данных на короткие расстояния. Если вам необходимо передавать данные на большие расстояния, этот протокол не рекомендуется. Пример простой сети I2C показан ниже.
Как видно на диаграмме, преимущество использования I2C состоит в том, что для связи с несколькими устройствами требуется всего два провода.
Вся связь проходит по двум проводам к ведущему и ведомым устройствам и от них. Это очень полезно при выполнении проектов Arduino, так как Arduino имеет ограниченное количество входных/выходных контактов.
Многие датчики и модули, предназначенные для Arduino используют I2C для связи.
Видео:Управляем LCD1602 через PCF8574 по шине i2cСкачать
Сеть I2C
Сеть I2C состоит из ведущего и ведомого устройств, соединенных шиной. В сети I2C может быть несколько ведущих и ведомых устройств — мастеров и наследников.
Ведомое устройство (наследник)
Все ведомые устройства имеют I2C-адрес, который используется для идентификации устройства в сети. I2C-адрес позволяет ведущему устройству передавать данные конкретному ведомому устройству на шине.
Ведущее устройство (мастер)
Ведущие устройства могут отправлять и получать данные. Ведомые устройства реагируют на все, что посылает ведущее устройство. При отправке данных на шину только одно устройство может отправлять данные одновременно.
Шина в I2C — это просто два провода, которые соединяют все I2C-устройства в сети.
Эти два провода называются SDA и SCL. Провод SDA используется для связи между ведущим и ведомым устройствами.
Линия SCL несет тактовый сигнал, используемый для правильной синхронизации связи. Для поддержания обоих проводов в состоянии HIGH необходимы импульсные или подтягивающие (pull-up) резисторы.
Логические уровни
Будьте внимательны при подключении I2C устройств к Arduino.
Arduino выводит I2C-сигналы на 5В логическом уровне, но I2C-устройства работают с различными напряжениями логического уровня.
Таким образом, I2C устройство, которое работает на 3,3 В может быть повреждено при подключении к Arduino. В паспорте устройства должно быть указано напряжение логического уровня.
Если подтягивающие резисторы подключены к +5В, все устройства должны быть совместимы для работы с логическим уровнем +5В.
Видео:Видеоуроки по Arduino. I2C и processing (7-я серия, ч1)Скачать
Использование 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-разъемом:
Компоненты оборудования
Чтобы создать этот проект, вам понадобятся следующие компоненты:
Схема соединения
После того, как вы соберете все детали, пришло время собрать проект. Следуйте нижеприведенной электрической схеме, чтобы все подключить:
Вы могли заметить, что у нас нет подтягивающих резисторов на линиях SDA и SCL. Подтягивающие резисторы уже встроены в I2C контакты Arduino, так что они нам не нужны.
Видео:Шина I2C.Скачать
Скетч для мастера
У нас есть два Ардуино в нашей сети I2C, так что у нас есть два набора скетчей. Один для мастера Ардуино, а другой для наследника Ардуино. Между двумя эскизами нет большой разницы, как вы увидите позже.
Теперь откройте Arduino IDE и загрузите код ниже на мастер Arduino:
Видео:Arduino 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-адрес ведомого прибора, который будет принимать данные. Эта функция делает две вещи:
- Она информирует шину о том, что мы будем посылать данные.
- Он информирует предполагаемого получателя о том, что данные готовы к получению.
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 хаб — как подключить одинаковые I²C модули к одной шине. Управляем IMU, матрицами, NFC и RTC.Скачать
Скетч для наследника (ведомого)
Теперь загрузите этот код ведомому Ардуино:
Видео:Как подключить несколько I²C с одинаковыми адресами. Железки АмперкиСкачать
Объяснение скетча для ведомого
Для ведомого устройства существует небольшая разница в кодировании 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 уже обрабатывает ответы от ведомых устройств.
Видео:Установщик адресов Flash-i2cСкачать
Тестирование Arduino I2C
А вот и самая захватывающая часть — включение питания и тестирование!
Используя Arduino IDE, загрузите эскиз мастера Arduino в одну из Ардуино. Затем загрузите скетч наследника в другую Arduino.
- Отрегулируйте потенциометр на ведущем устройстве, чтобы регулировать частоту мигания светодиода ведомого устройства.
- Отрегулируйте потенциометр на ведомом устройстве, чтобы контролировать частоту мигания светодиода ведущего устройства.
Наш код принимает положение потенциометра мастера и посылает его ведомому устройству через I2C. Затем ведомое устройство использует полученное значение для настройки времени задержки мигания светодиода. То же самое происходит и с положением потенциометра ведомого.
- Свежие записи
- Нужно ли менять пружины при замене амортизаторов
- Скрипят амортизаторы на машине что делать
- Из чего состоит стойка амортизатора передняя
- Чем стянуть пружину амортизатора без стяжек
- Для чего нужны амортизаторы в автомобиле
- Правообладателям
- Политика конфиденциальности
🔥 Видео
STM32. CMSIS. Урок#06: I2C. Теория. Сканер I2C адресов. Отправка и прием данных. MemWrite, MemRead.Скачать
Урок 26.1 Соединяем две arduino по шине UARTСкачать
I2C интерфейсСкачать