Интерфейс I2C (IIC)
Теория
КОМПОНЕНТЫ
- Адресуемая светодиодная лента
- Геркон
- Диод
- Зуммер
- Кнопка
- Кварцевый резонатор
- Конденсатор
- Макетная плата
- Резистор
- Реле
- Светодиод
- Светодиодные индикаторы
- Сервопривод
- Симистор
- Транзистор
ARDUINO
- Что такое Arduino?
- Среда разработки Arduino IDE
- Сравнение плат Arduino. Какую выбрать?
- Как прошить плату Arduino с помощью другой Arduino (ArduinoISP)
- Онлайн-сервис TinkerCAD – эмулятор Arduino
- Визуальная среда разработки Mixly для Arduino
- Настройка поддержки чипа STM32F103C8T6 средой Arduino IDE
RASPBERRY
ИНТЕРФЕЙСЫ ПЕРЕДАЧИ ДАННЫХ
- SDA — линия данных
- SCL — линия синхронизации.
Каждое устройство определяется как ведущее или ведомое, а также обладает уникальным (в пределах шины) адресом. Максимальное допустимое количество элементов, подсоединённых к одной шине, ограничивается максимальной емкостью шины — 400 пФ.
- Ведущее устройство — устройство, которое инициирует передачу данных и генерирует сигналы синхронизации, а также завершает передачу данных; может отправлять данные, либо запрашивать их
- Ведомое устройство — любое адресуемое устройство по отношение к ведущему устройству; может принимать данные или отправлять их по запросу ведущего
- Передатчик — устройство, передающее данные по шине
- Приемник — устройство, принимающее данные с шины.
Отношения ведущий-ведомый и приемник-передатчик не постоянны и зависят лишь от направления передачи данных в текущий момент времени. Обычно стандарт I2C подразумевает наличие в один момент времени только одного ведущего устройства, однако также допускается и наличие нескольких ведущих устройств в шине без нарушения работы системы. В этом случае для предотвращения возникновения ошибок и хаоса применяется процедура арбитража.
Принцип работы
Начало и завершение обмена данными
В исходном состоянии обе линии SDA и SCL находятся в высоком состоянии.
Процедура обмена данными начинается с формирования ведущим устройством состояния СТАРТ: переход состояния линии SDA с высокого на низкое при высоком состоянии на линии SCL.
Процедура обмена данными заканчивается, когда ведущий формирует состояние СТОП: переход состояния линии SDA с низкого на высокое при высоком состоянии на линии SCL.
Обмен данными
После формирования состояния СТАРТ и до появления состояния СТОП изменять уровень на линии SDA можно только при низком состоянии на тактирующей линии SCL. Бит информации «читается» приёмником только когда на линии SCL установлен высокий уровень сигнала, поэтому в этот момент на линии SDA сигнал должен быть неизменным и стабильным. Принятые данные считаются действительными, только если соблюдается это правило.
Подтверждение приема данных
Адресация
Как уже отмечалось выше, каждое устройство в шине I2C должно иметь уникальный адрес, но также в системе предусмотрен адрес «общего вызова» для обращения ко всем ведомым сразу. Адрес ведомого может состоять из фиксированной и программируемой частей. После отправки адресного байта по шине, каждое устройство в системе сравнивает первые семь бит после сигнала СТАРТ со своим адресом. Если адреса совпали, устройство считает себя выбранным как ведомый-приёмник или как ведомый-передатчик, в зависимости от состояния бита направления:
- низкий уровень («0») означает, что ведущий будет отправлять информацию ведомому
- высокий («1») означает, что ведущий будет получать информацию от ведомого.
Из спецификации шины следует, что допускаются не только простые форматы обмена, но и комбинированные, когда в промежутке от состояния СТАРТ до состояния СТОП ведущий и ведомый могут выступать и как приемник и как передатчик данных. Комбинированные форматы могут быть использованы, например, для управления последовательной памятью.
Типичный сеанс обмена данными по шине I2C проиллюстрирован на следующем изображении:
Как узнать I2C адрес устройства?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <Wire.h>; void setup(){ Wire.begin(); Serial.begin(9600); while (!Serial); Serial.println("\nОпределение I2C адреса"); } void loop(){ byte address, err; int devices; Serial.println("Поиск устройств..."); devices = 0; for(address = 8; address < 127; address++){ Wire.beginTransmission(address); err = Wire.endTransmission(); if (err == 0){ Serial.print("Найдено устройство по адресу 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); devices++; } else if (err==4) { Serial.print("Неизвестная ошибка по адресу 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (devices == 0) Serial.println("Устройств не найдено\n"); else Serial.println("Определение завершено\n"); delay(5000); } |