sda и scl что это
Общие сведения:
Подключение:
Шина поддерживает подключение до 112 устройств (при 7-ми битной адресации) по двум проводам (плюс GND и Vcc), может иметь несколько ведущих и ведомых. При использовании нескольких ведущих, каждый из них должен поддерживать этот режим и уметь определять состояние занятой шины.
I²C на Arduino
Arduino UNO R3/Piranha UNO
На Arduino UNO R3/Piranha UNO шина I2C находится на выводах A4, A5. Также в эти выводы продублированы на колодке с цифровыми выводами рядом с кнопкой Reset.
Piranha ULTRA
На Piranha ULTRA шина I²C не занимает аналоговые выводы A4, A5 и находится на цифровой колодке рядом с кнопкой Reset, выводы обозначены SDA и SCL
Arduino MEGA R3
На Arduino MEGA R3 шина I²C находится на цифровой колодке на крайних выводах, близких к разъёму USB и на выводах 20, 21. Выводы объединены.
Примеры для Arduino
В этом примере на матрицу выводится изображение стрелки. Стоит заметить, ко всем нашим модулям написаны библиотеки с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке.
I²C на Raspberry Pi
На Raspberry Pi I²C выводы это 3-й и 5-й выводы колодки, GPIO2 и GPIO3 по номенклатуре BCM и выводы 8, 9 по номенклатуре WiringPi.
Примеры для Raspberry
Подробнее о шине I²C:
Резисторы, ёмкость и длина линий шины
В официальном описании от NXP ничего не сказано о максимальной длине шины, но не стоит этим злоупотреблять. Шина была придумана для обмена информации между интегральными схемами в пределах одной платы одного устройства. В расчёт бралась только паразитная ёмкость линии, которая сказывается на скорости нарастания фронта волны. От этой ёмкости зависит номинал подтягивающих резисторов. Можно подобрать резисторы так, чтобы фронт волны нарастал согласно спецификации и при 100-метровой длине проводов, но это не избавляет от помех, которые влечёт за собой несимметричная электрическая реализация. Опять же, при слишком маленьком сопротивлении качество сигнала улучшается, но при этом растёт ток который необходимо пропускать устройствам через выводы для притяжки линий.
При использовании шины на модулях не существует принятого стандарта установки подтягивающих резисторов на ведущем или ведомом. У Arduino подтягивающие резисторы отсутствуют и для работы с шиной нужен хотя бы один модуль с ними. У Raspberry Pi на плате установлены подтягивающие резисторы номиналом 1,7 килоОм и для неё нет необходимости в подтяжке на модулях.
Сигналы и специальные биты шины
Устанавливаемые только ведущим
Устанавливаемые ведущим и ведомым
Обмен данными
При обмене данными тактированием занимается только ведущий, а ведомый может удерживать линию тактирования только если не успевает за ведущим, так называемое растягивание тактирования (clock-stretching). Не все модули поддерживают удержание. Установка бита на линии данных может происходит в момент, когда линия тактирования прижата, а считывания, когда линия отпущена (подтянута к Vcc), но в большинстве случаев это происходит по фронту волны на линии тактирования.
Рассмотрим пример простого обмена данными:
Запись в регистры ведомого. Данные взяты из примеров, приведённых выше.
После сигнала Start и указания адреса ведущий записывает адрес регистра с которого будет производиться дальнейшая запись. Стоит заметить, что у ведомого есть внутренний счётчик и каждый последующий байт после подтверждения будет записан в следующий регистр. Таким образом байт со значением 0x00 будет записан в регистр 0x11, байт со значением 0x18 будет записан в регистр 0x12, байт со значением 0x3C будет записан в регистр 0x13 и т. д. В этом примере биты ACK устанавливает ведомый.
Вот так сигналы этого примера выглядят на осциллографе:
Чтение из регистров ведомого. Предположим, мы хотим прочитать байт из регистра 0x13.
После сигнала Start и указания адреса ведущий записывает адрес регистра, который необходимо прочитать. Далее следует сигнал Restart (или Stop, затем Start). Ведущий снова выводит адрес ведомого, но уже с битом Read (чтения). Ведомый устанавливает бит ACK и во время следующих 8-ти импульсов тактирования выводит данные на линию SDA. На девятом импульсе уже ведущий устанавливает бит ACK (или NACK, если данные не удалось прочитать) и завершает обмен сигналом Stop.
Скорость
Первоначальный стандарт I²C был реализован на скорости 100 кГц. С тех пор появились и другие реализации шины, но большинство устройств работают на этой скорости. Так же известны случаи когда скорость шины специально снижена, чтобы увеличить расстояние передачи и уменьшить чувствительность к помехам. Не все модули могут работать на сниженной скорости.
Интерфейс I2C и Arduino
Инструкция по использованию протокола I 2 C совместно с Arduino
Нам понадобится:
1 Описание интерфейса I2C
Последовательный протокол обмена данными IIC (также называемый I2C – Inter-Integrated Circuits, межмикросхемное соединение) использует для передачи данных две двунаправленные линии связи, которые называются шина последовательных данных SDA (Serial Data) и шина тактирования SCL (Serial Clock). Также имеются две линии для питания. Шины SDA и SCL подтягиваются к шине питания через резисторы.
В сети есть хотя бы одно ведущее устройство (Master), которое инициализирует передачу данных и генерирует сигналы синхронизации. В сети также есть ведомые устройства (Slave), которые передают данные по запросу ведущего. У каждого ведомого устройства есть уникальный адрес, по которому ведущий и обращается к нему. Адрес устройства указывается в паспорте (datasheet). К одной шине I2C может быть подключено до 127 устройств, в том числе несколько ведущих. К шине можно подключать устройства в процессе работы, т.е. она поддерживает «горячее подключение».
Описание интерфейса I2C
Давайте рассмотрим временную диаграмму обмена по протоколу I2C. Есть несколько различающихся вариантов, рассмотрим один из распространённых. Воспользуемся логическим анализатором, подключённым к шинам SCL и SDA.
Мастер инициирует обмен. Для этого он начинает генерировать тактовые импульсы и посылает их по линии SCL пачкой из 9-ти штук. Одновременно на линии данных SDA он выставляет адрес устройства, с которым необходимо установить связь, которые тактируются первыми 7-ми тактовыми импульсами (отсюда ограничение на диапазон адресов: 2 7 = 128 минус нулевой адрес). Следующий бит посылки – это код операции (чтение или запись) и ещё один бит – бит подтверждения (ACK), что ведомое устройство приняло запрос. Если бит подтверждения не пришёл, на этом обмен заканчивается. Или мастер продолжает посылать повторные запросы.
Это проиллюстрировано на рисунке ниже. Задача такая: подключиться к ведомому устройству с адресом 0x27 и передать ему строку «SOLTAU.RU». В первом случае, для примера, отключим ведомое устройство от шины. Видно, что мастер пытается установить связь с устройством с адресом 0x27, но не получает подтверждения (NAK). Обмен заканчивается.
Попытка мастера установить соединение с ведомым по I2C
Теперь подключим к шине I2C ведомое устройство и повторим операцию. Ситуация изменилась. На первый пакет с адресом пришло подтверждение (ACK) от ведомого. Обмен продолжился. Информация передаётся также 9-битовыми посылками, но теперь 8 битов занимают данные и 1 бит – бит подтверждения получения ведомым каждого байта данных. Если в какой-то момент связь оборвётся и бит подтверждения не придёт, мастер прекратит передачу.
Временная диаграмма обмена по протоколу I2C
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 |
3 Библиотека «Wire» для работы с IIC
Для облегчения обмена данными с устройствами по шине I2C для Arduino написана стандартная библиотека Wire. Она имеет следующие функции:
Функция | Назначение |
---|---|
begin(address) | инициализация библиотеки и подключение к шине I2C; если не указан адрес, то присоединённое устройство считается ведущим; используется 7-битная адресация; |
requestFrom() | используется ведущим устройством для запроса определённого количества байтов от ведомого; |
beginTransmission(address) | начало передачи данных к ведомому устройству по определённому адресу; |
endTransmission() | прекращение передачи данных ведомому; |
write() | запись данных от ведомого в ответ на запрос; |
available() | возвращает количество байт информации, доступных для приёма от ведомого; |
read() | чтение байта, переданного от ведомого ведущему или от ведущего ведомому; |
onReceive() | указывает на функцию, которая должна быть вызвана, когда ведомое устройство получит передачу от ведущего; |
onRequest() | указывает на функцию, которая должна быть вызвана, когда ведущее устройство получит передачу от ведомого. |
4 Подключение I2C устройствак Arduino
Давайте посмотрим, как работать с шиной I2C с помощью Arduino.
Сначала соберём схему, как на рисунке. Будем управлять яркостью светодиода, используя цифровой 64-позиционный потенциометр AD5171 (см. техническое описание), который подключается к шине I2C. Адрес, по которому мы будем обращаться к потенциометру – 0x2c (44 в десятичной системе).
Подключение цифрового потенциометра к Arduino по шине I2C
5 Управление устройством по шине IIC
Рассмотрим диаграммы информационного обмена с цифровым потенциометром AD5171, представленные в техническом описании:
Рассмотрим диаграммы чтения и записи цифрового потенциометра AD5171
Нас тут интересует диаграмма записи данных в регистр RDAC. Этот регистр используется для управления сопротивлением потенциометра.
Откроем из примеров библиотеки «Wire» скетч: Файл Образцы Wire digital_potentiometer. Загрузим его в память Arduino.
После включения вы видите, как яркость светодиода циклически нарастает, а потом гаснет. При этом мы управляем потенциометром с помощью Arduino по шине I2C.
По ссылкам внизу статьи, в разделе похожих материалов (по тегу), можно найти дополнительные примеры взаимодействия с различными устройствами по интерфейсу IIC, в том числе примеры чтения и записи.
6 Дополнительно о шине I2C
Доступно и интересно рассказывает о шине I2C Джереми Блюм в своём видео:
I2C интерфейс
Интерфейс I2C является широко распространенным и популярным стандартом передачи данных между устройствами. Данный интерфейс поддерживают множество различных датчиков и микросхем, наиболее известные это микросхемы EEPROM памяти серии 24cXX. Для передачи данных используются всего две линии, которые представляют собой шину данных, причем на одну шину можно подключать несколько различных устройств. В этой статье я приведу описание интерфейса и реализацию на программном уровне.
Описание интерфейса I2C
Способ подключения
Адресация
В интерфейсе предусмотрена программная адресация устройств подключенных к шине, наиболее распространена длина адреса в 7 бит, теоретически это позволяет подключать на шину до 127 устройств, но часть адресов по спецификации зарезервированы и не могут использоваться разработчиками. Каждое устройство имеет свой уникальный адрес, который заложен производителем и указан в технической документации. Адрес устройства может быть фиксированным, или с возможностью аппаратной настройки, в этом случае устройство имеет дополнительные входы, в зависимости от уровня напряжения на входах (высокое или низкое), можно получить различные адреса. Обычно количество входов варьируется от 1-го до 3-х, которые задают значения определенных битов 7-битного адреса. Аппаратная настройка адреса предусмотрена для возможности подключения нескольких однотипных устройств на одну шину.
Также интерфейс предусматривает более редкую 10-битную адресацию, под которую зарезервирован 7-битный адрес 11110XX (XX-зависят от значения адреса), в этом случае сначала предается зарезервированный адрес, в котором два последних бита представляют собой старшие биты 10-битного адреса, затем передаются младшие 8 бит адреса. При использовании данной адресации на шину можно подключать более 1000 устройств.
Условия “Старт” и “Стоп”
Каждый сеанс передачи данных начинается со специального условия, называемого “Старт”. В исходном состоянии, когда шина свободна, обе линии SDA и SCL подтянуты к высокому логическому уровню, условие “Старт” подразумевает переключение линии SDA с высокого логического уровня на низкий, в то время когда на линии SCL установлен высокий уровень.
Аналогично, сеанс передачи данных завершается специальным условием “Стоп”, это переключение линии SDA с низкого логического уровня на высокий, при высоком уровне на линии SCL. Данные условия генерирует ведущий (микроконтроллер).
Исходя из условий “Старт” и “Стоп”, во время передачи данных линия SDA может переключаться только при низком уровне на линии SCL, то есть установка новых данных на линии SDA возможна только после спада уровня на SCL. В течение импульса тактирования (высокий уровень на SCL), состояние линии SDA не должно меняться, в это время выполняется считывание данных на SDA.
Формат передачи данных
Данные по интерфейсу передаются побайтно, старшим битом вперед, за каждым переданным байтом (8 бит) следует бит подтверждения, устройство (ведущий или ведомый) принявшее байт данных, устанавливает низкий уровень на линии SDA на следующем тактовом импульсе SCL, тем самым подтверждая получение байта. В это время передающее устройство должно опрашивать линию SDA, ожидая ответ об успешном получении байта. Ниже на картинке представлена диаграмма передачи данных по шине I2C:
Сначала передается байт с 7-битным адресом ведомого, значение 8-го бита (R/W) определяет направление передачи данных, нулевое значение соответствует записи данных, то есть передача от ведущего к ведомому. Если бит направления равен 1, то выполняется чтение данных из ведомого.
Ведомый сравнивает переданный адрес со своим и при совпадении откликается, устанавливая низкий уровень на линии SDA (бит подтверждения). Ведущий, получив подтверждение, начинает передавать байты с данными, или принимает их, в зависимости от направления передачи. На следующей картинке более подробно представлены различные варианты передачи данных по шине I2C:
После передачи адреса ведомого, передается адрес регистра, над которым будут производиться операции чтения/записи. Каждое устройство обладает своим набором внутренних регистров, назначение которых указано в технической документации.
Запись одного байта состоит из следующей последовательности: условие “Старт” – адрес ведомого (бит R/W сброшен) – адрес внутреннего регистра ведомого – данные (1 байт) – условие “Стоп”. Запись нескольких байтов практически ничем не отличается, после отправки первого байта данных, передаются остальные байты, сеанс заканчивается условием “Стоп”. При этом данные записываются в регистры последовательно, начиная с заданного адреса, обычно ведомый выполняет автоматический инкремент адреса внутренних регистров.
Для чтения одного байта данных, необходимо сначала передать адрес ведомого и адрес требуемого регистра, при этом бит направления должен быть сброшен на запись, после чего повторно передается условие “Старт”, затем снова адрес ведомого, в этот раз с установленным битом направления на чтение. Далее выполняется прием байта данных от ведомого, для окончания сеанса передачи ведущий не выдает подтверждения, то есть на линии SDA остается высокий уровень на время бита подтверждения, далее следует условие “Стоп”. Чтение нескольких байтов выглядит аналогично, ведущий выдает подтверждение после каждого принятого байта, за исключением последнего байта. Как и в случае записи, ведомый выполняет автоматический инкремент адреса, начиная с заданного.
Во время сеанса передачи данных ведомый может принудительно удерживать на линии SCL низкий уровень, например, если ему требуется время на обработку данных. Ведущий “отпуская” линию SCL должен проверить переход от низкого логического уровня к высокому, если этого не произошло, то необходимо ожидать перехода. Таким образом, ведущий не имеет абсолютного права на управление линией SCL.
Интерфейс также предусматривает режим конкуренции, когда на шине присутствуют несколько ведущих, я не стану рассматривать этот режим, так как он редко применяется. Для предотвращения конфликтов в таких случаях используется функция арбитража и синхронизации линии тактирования SCL.
Скорость передачи данных
По спецификации интерфейс поддерживает три скоростных режима передачи:
Стандартный режим до 100 Кбит/сек поддерживают все устройства, возможность функционирования на больших скоростях необходимо уточнять в технической документации на устройство.
Программная реализация интерфейса I2C
Не у всех микроконтроллеров серии PIC16 имеется встроенный аппаратный модуль I2C, но интерфейс можно реализовать программно и использовать на любом микроконтроллере. Ниже представлен код реализующий функции ведущего применительно к микроконтроллеру PIC16F628A:
Электроника для всех
Блог о электронике
Интерфейсная шина IIC (I2C)
Логический уровень
Как передаются отдельные биты понятно, теперь о том что эти биты значат. В отличии от SPI тут умная адресная структура. Данные шлются пакетами, каждый пакет состоит из девяти бит. 8 данных и 1 бит подтверждения/не подтверждения приема.
После адресного пакета идут пакеты с данными в ту или другую сторону, в зависимости от бита RW в заголовочном пакете.
Вот, например, Запись. В квадратиках идут номера битов. W=0
Задача решается так:
С записью все понятно — записали вначале адрес, а потом следом записали данные. А умная микросхема все прекрасно поняла и рассовала по ячейкам. А с чтением? А с чтением все через задницу, в смысле через запись.
Скриншот с осциллографа RIGOL 1042CD
Вроде бы все, практический пример с AVR будет потом, а пока помедитируйте над диаграммой работы конечного автомата TWI передатчика ATmega8. Скоро я вас буду этим грузить!
Страшна? 😉 На самом деле там все не так брутально. Можно обойтись вообще парой десятков строк кода на ассемблере.
Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!
А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.
200 thoughts on “Интерфейсная шина IIC (I2C)”
(1) OpenID работает криво. Я зашёл как blacklion.livejournal.com и всё равно справа-сверху «войти» (а не «выйти») и не даю комментировать. Пришлось регистрироваться и теперь тут два меня.
(2) Софтового мастера сделать не сложно. А вот слейва как-то просто не получается.
Щас попробую с опен ид поиграться.
Более того, многие предпочитают делать софтовый И2С мастер чтобы не заморачиваться с встроенным в TWI конечным автоматом.
Более того, многие предпочитают делать софтовый И2С мастер чтобы не заморачиваться с встроенным в TWI конечным автоматом.
Я когда первый раз подходил к электронике смотрел на PIC (зачем я это делал!? Зачем на PIC?!) так реализовал мастера в качестве упражнения за вечер. А вот слейва так и не осилил…
Я сделал софтового слейва на AT89C2051, но работало жутко медленно.
плюсадин. я уже раз 5 жаловался что логины глючат 😀 нашел выход, что залогинился, пару минуток подождал и рефреш. работает, но бесит :\
DI HALT спасибо за статью. Давно ждал рассказ про I2C. 🙂
У меня их почти полный аналог ICL12008 ваще работать не хотят — не отзываются на свой адрес, не дают ACK
и у тебя, Брут? я изъебался с их инициализацией — не пашут и все. взял ds, который считал сгоревшим и не рабочим, по по недоразумению не выкинул — и он заработал. в топку эти ISL, от лукавого они..
А у меня 5 штук их лежит — сэмплы. Надо бы в ST гневный мессадж накатать. МОл чо вы за говно нам подсунули?
Да, есть такое дело 🙂 Вообще при начале работы с IIC девайсом, желательно вдоль и поперек изучить Datasheet к нему. В свое время тоже поломал голову с m41 от ST. Вроде все пишется, все читается, но часы стоят и все тут. Оказалось там есть хитрый битик, который при пропадании всего питания — Vcc и Vbat, останавливает часы и пока его не сбросишь они не пойдут.
Ну и еще обычный прикол с часами, что не все могут работать при отключенной батарейке — даже если Vcc есть, внутри у них стоит контроль, который проверяет разницу между напругой и Vbat, и если Vbat нет, то часы просто ни на что не отвечают 🙂
p.s. а про NACK в конце чтения это да, самые популярные грабли наверно. Кстати для отлаживания шины если нет крутого осцила, можно прикрутить I2C Sniffer на Atmega8 — оч удобная штука, она в консоли показывает полностью весь обмен в удобоваримом виде.
А чё с ним было голову ломать? Кстати, m41t56 рекомендую, простые и удобные I2C часы. Про битик я давно знал — он у всех часовых изделий от ST присутствует. Наверное, как совместимость с m48t08 — который с батареей на борту. Чтобы батарею не сажать, пока таймкипер лежит на складе, они глушат часы.
О)) На самом деле классная тема! Мне бы сначала с простым UARTом разобраться, а потом только к творению Philips)) Буду ждать исходников…
Отличная статья! А есть последняя диаграмма только в чуть лучшем качестве? А то буквы трудно различить.
Красные пути — нормальная работа
Синие — возможные косяки.