Почему не определяются устройства на шине i2c
Перейти к содержимому

Почему не определяются устройства на шине i2c

  • автор:

Arduino.ru

Время стояло и выводило все по нулям. Я перепробывал множетсво скетчей, все они заливались, но время остется неизменным. I2C сканер так же не выдает результатов, хотя скетчи с дисплеем на ssd1306 все работают и отлично. Помогите разобратся в чем может быть дело?
​Так же скетч для просмотра времени работает и без модуля RTC.

  • Войдите на сайт для отправки комментариев

При сканировании i2c устроств пишет

I2C Scanner
Scanning.

​И больше ничего, ждал очень долго.

С подключением не может быть никаких проблем, если кто сталкивался помогите пожалуйста. Уже не знаю что делать, убил два дня в поисках, решил проблему только с изменившимися командами и названиями библиотек, т.к. очень большая часть материала и скетчей 2012-13 гг и библиотеки поменялись.

  • Войдите на сайт для отправки комментариев

I2C сканер не может не работать. Модули обычно идут с мелкосхемой памяти на борту, должно родить два адреса 0х68 и 0хХЗ. Проверяйте питание, подключение, дорожки на модуле. Если светодиод на модуле горит, для начала предложил бы поменять местами SDA-SCL.

  • Войдите на сайт для отправки комментариев

Попробовал, но ничего не изменилось, сначала так же и дисплеи не определял, затем начал показывать фигню всякую при перетыкании, затем стал выдавать стабильно адрес у одного и второго дисплея, а ds1307 так и не видит. Ну хоть теперь дисплееи видит. При совместном подключении и RTC модуля и дислпея так же ничего не видит, может быть так что модуль косяченый? Хотя отзывы на али хорошие, и пишут что все работает, диод выпаял с резистором, R6 замкнут, кварц заменил из радиоприемника на rda5807 тоже 32кГц, заказывал сразу 2 модуля, второй точно так же не работает.

Почему не определяются устройства на шине i2c

Почему i2c сканер не видит ЖК дисплей с модулем i2c?

Всем привет! Заказал с Китая ЖК дисплей 1602A с модулем для подключения по i2c. Загрузил скетч(ошибок не было), но ничего не выходит. Регулировал контрастность, но ничего. Запустил i2c сканер, но пишет «No I2C devices found». Почему он не видит дисплей? Разъемы подключил правильно.
+ при регулировании контрастности горит только верхняя строчка, нижняя ели ели виден. Это получается неисправен дисплей или что?

P.S Модуль к дисплею припаял сам, замыкании нет.
5f893d7ec8608602524360.jpeg
5f893d726fa3a233319761.jpeg

Обнаружение неисправности шины i2c

Поиск неисправностей в системной шине I2С Напряжение питания как к линии SDA, так и к линии SCL подводится через нагрузочные резисторы. Значение этого напряжения обычно составляет от 4,5 В до 5,5 В и должно точно соответствовать приведенному в сервисной документации уровню. Поиск неисправностей поэтому следует начинать с измерения питающего шину напряжения. К прекращению обмена информацией в шине могут привести также колебания питающего напряжения. Поэтому особое внимание следует обратить на наличие пульсаций напряжения питания, особенно в тех случаях, когда

Рис. 14.2. Осциллограмма сигналов в линии данных (SDA) шины 12C
Рис. 14.3. Осциллограмма тактового сигнала в линии синхронизации (SCL) шины 12C появляется какая-нибудь нерегулярная неисправность.
Пульсации могут составлять всего лишь несколько милливольт, поэтому в сомнительных случаях проверку питающего системную шину напряжения надо проводить с помощью осциллографа. Обычно на входах блоков, подключаемых к системной шине, или перед микросхемами в этих блоках располагают еще и развязывающие резисторы. С помощью измерения напряжения на этих резисторах можно установить наличие короткого замыкания в соответствующем блоке. Если такая неисправность присутствует, то измеренное напряжение на выводе резистора, со стороны подключенного блока или микросхемы, имеет существенно более низкое значение, чем на другом выводе резистора. Если же в проверяемых узлах короткое замыкание отсутствует, то падение амплитуды сигнала на соответствующих развязывающих резисторах незначительное из-за достаточно низкого их номинала (от 100 Ом до 1 кОм). Поиск неисправностей усложняется, когда отдельные узлы и схемы подключены к системной шине без развязывающих резисторов, так как в этом случае любой неисправный узел может полностью заблокировать обмен информацией по системной шине. В этом случае придется последовательно отсоединять подключенные к шине отдельные узлы и схемы. Уже измерение напряжения до и после нагрузочных резисторов может дать указание на вероятную неисправность в одном из устройств, подключенных к системной шине, если падение напряжения на этих резисторах слишком велико. Необходима также проверка наличия сигналов в линиях SCL и SDA шины. Отсутствие сигнала синхронизации в линии SCL указывает на необходимость проверки работоспособности центрального управляющего устройства, а также внешнего кварцевого резонатора тактового генератора ЦУУ. Неисправности частотозадающих элементов тактового генератора могут быть причиной отличия тактовой частоты от номинальной, что также может привести к нарушению обмена информацией в шине. Тактовая частота может представлять собой синусоидальный сигнал, либо сигнал прямоугольной или трапециевидной формы. На рис. 14.3 представлен сигнал тактовой частоты. Наличие импульсных сигналов номинальной амплитуды в линии SDA-шины (рис. 14.2)само по себе не дает достоверной информации о правильности обмена данными между узлами ВМ, подключенными к системной шине, но при их наличии можно условно считать, что обмен данными в системе происходит правильно.

Не определяется адрес дисплея по шине i2c

Время стояло и выводило все по нулям. Я перепробывал множетсво скетчей, все они заливались, но время остется неизменным. I2C сканер так же не выдает результатов, хотя скетчи с дисплеем на ssd1306 все работают и отлично. Помогите разобратся в чем может быть дело?
​Так же скетч для просмотра времени работает и без модуля RTC.

При сканировании i2c устроств пишет

​И больше ничего, ждал очень долго.

С подключением не может быть никаких проблем, если кто сталкивался помогите пожалуйста. Уже не знаю что делать, убил два дня в поисках, решил проблему только с изменившимися командами и названиями библиотек, т.к. очень большая часть материала и скетчей 2012-13 гг и библиотеки поменялись.

I2C сканер не может не работать. Модули обычно идут с мелкосхемой памяти на борту, должно родить два адреса 0х68 и 0хХЗ. Проверяйте питание, подключение, дорожки на модуле. Если светодиод на модуле горит, для начала предложил бы поменять местами SDA-SCL.

Попробовал, но ничего не изменилось, сначала так же и дисплеи не определял, затем начал показывать фигню всякую при перетыкании, затем стал выдавать стабильно адрес у одного и второго дисплея, а ds1307 так и не видит. Ну хоть теперь дисплееи видит. При совместном подключении и RTC модуля и дислпея так же ничего не видит, может быть так что модуль косяченый? Хотя отзывы на али хорошие, и пишут что все работает, диод выпаял с резистором, R6 замкнут, кварц заменил из радиоприемника на rda5807 тоже 32кГц, заказывал сразу 2 модуля, второй точно так же не работает.

Arduino.ru

LCD I2C arduino не могу подключить

попробовать опредилить адрес заливаю его а мне только показывает Scanning. и дальше ничего. Что подскажете сделать?

а почему дисплей подключен сразу к 3,3 В и к 5 В?

там просто плохо видно он подключен к 5 и к земле

Все вы правильно делаете. Ищите контакт со стороны UNO, попробуйте разъемы SCL и SDA на UNO рядом с кварцем.

Можете рассмотреть чип на переходнике. Маркировка PCF8574T даст I2C адрес по умолчанию 0x27, PCF8574AT — адрес 0x3F.

Я это все уже пробовал к сожалению ничего не помогло, а маркировка ida8574p n2k0h5

сканер I2C какой адрес выдает?

в том и дело что сканер ничего не выдает пишет что началось сканирование и все ничего более не происходит

Код сканера корректно обрабатывает ситуации, когда вообще никакое устройство не подключено к I2C. Был неправ, дело не в контакте. Что-то у вас с программной средой.

Маркировкой чипа адаптера сильно озадачили. Но дело все равно не в этом.

и что посоветуете сделать? уже куча всего перепробовал

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

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

Если правильно вас понял, вы видите в окне терминала слово Scanning. и на этом все заканчивается. Но чудес не бывает (только если очень редко). Из цикла for вы не выходите, зависнуть там можно только при входе в Wire (ну или в twi.h, которая под ней), никто из них не зависает (у меня, специально мучил).

Какой вывод? Разбирайтесь со средой, с ее установками или что там. Вообще что-нибудь, не требующее перефирии, запускается?

И вам спасибо. Благодаря вам посмотрел библиотеки, twi.h забавно написана, хорошо.

I2C-адрес устройства и как его узнать

Для подключения различных модулей к Arduino, например, датчиков, дисплеев и АЦП удобно пользоваться шиной I2C (Inter-Integrated Circuit).

Каждое подключенное устройство имеет свой адрес, к одной шине может быть подключено до 119 устройств (всего адресов 127, 8 из них –зарезервированные служебные).

Самая распространённая проблема при использовании I2C – незнание адреса подключаемого устройства (хотя обычно производитель указывает их). Особенно это заметно при использовании дешёвых китайских устройств разных производителей, например, символьного LCD дисплея с I2C адаптером (их адреса обычно 0x27 или 0x3F). Решение этой проблемы мы и разберём в статье.

Для начала подключаем проверяемое устройство к плате Arduino:

  • VCC к 5v;
  • GND к GND, земле;
  • SDA к SDA или A4 (UNO/Nano) либо к 20 (Mega) и подтягивающий резистор на 10 кОм к плюсу питания (опционально);
  • SCL к SCL или A5 либо к 21 и подтягивающий резистор на 10 кОм к плюсу питания.

Для того, чтобы проверить наличие подключенных к Arduino I2C-устройств, нужно просто просканировать каждый доступный адрес с 8 до 127. Успешно прошедшая отправка данных – верный признак наличия ведомого устройства на шине. Итак, подключаем плату Arduino к компьютеру и загружаем следующий скетч:

Подключить несколько устройств i2c на Arduino

IIC Arduino (I2C – Inter-Integrated Circuits, межмикросхемное соединение) — это последовательный протокол обмена данными по двум двунаправленным линиям связи. Эти линии называют также: SDA (Serial Data) — шина последовательных данных и SCL (Serial Clock) — шина тактирования. Шины SDA и SCL Arduino подтягиваются к шине питания через резисторы. Рассмотрим подробнее, что это такое шина i2c arduino.

Шина I2C Ардуино описание

Микроконтроллеры Arduino используют два пина для работы по интерфейсу I2C. В Arduino Uno и Nano линии SDA соответствует аналоговый порт A4, а SCL соответствует аналоговый порт A5. На Ardunio Mega SDA — 20 пин, SCL — 21 пин. Для облегчения работы с шиной I2C и обмена данными между устройствами для Arduino IDE написана стандартная библиотека Wire (скачивать и устанавливать ее не надо).

Для каждого устройства, при подключении к микроконтроллеру, присваивается уникальный адрес (максимум можно подключить 127 устройств). Поменять адрес устройства на шине нельзя, так как он вшит в микросхему. Часто производители предоставляют возможность поменять адрес устройства в небольшом диапазоне, что дает возможность подключить к шине IIC Ардуино несколько одинаковых устройств.

Сканер I2C интерфейса (шины) Ардуино

Для этого занятия нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • макетная плата;
  • два текстовых дисплея 1602 I2C;
  • любое устройство с I2C интерфейсом;
  • провода «папа-папа», «папа-мама».

Перед тем, как управлять несколькими объектами, подключенных к IIC шине, необходимо узнать их адреса. Для этого используется программа — сканер I2C Arduino, которая позволяет узнать адреса всех устройств, подключенных в данный момент к шине. Соберите схему из двух текстовых экранов с IIC модулем (можно подключить только одно устройство), подключенных к Ардуино Уно, и загрузите следующий скетч.

Скетч. Сканер шины i2c для Arduino
Пояснения к коду:
  1. данный код позволяет узнать все адреса устройств, подключенных к шине IIC. Если устройство не было подключено или подключено неправильно — на мониторе порта будет выходить сообщение, что устройства не найдены;
  2. ниже, на скриншоте монитора порта Arduino IDE, выводится адрес LCD 1602.

Сканер шины i2c для Arduino с LCD дисплеем

Как подключить нескольких устройств по I2C Arduino

В следующем примере к шине IIC Arduino будет подключено сразу три устройства — текстовый дисплей 1602, датчик давления bmp180 и RTC модуль часов. После сборки схемы можно сделать предварительное сканирование шины, но адреса у всех устройств разные и изменить адрес можно только у дисплея. У других устройств адреса «вшиты» производителем и используются в библиотеках по умолчанию.

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

После сборки схемы, убедитесь, что у вас установлены необходимые библиотеки для работы с устройствами по IIC протоколу, и загрузите следующий пример кода в микроконтроллер. Данная программа будет выводить на текстовый экран текущую дату и время суток (устанавливаются в процедуре void setup и время можно поменять), а также данные о температуре воздуха и атмосферном давлении.

Пояснения к коду:
  1. обновление информации на текстовом экране происходит каждую секунду, данный интервал можно увеличить по своему желанию;
  2. время выводится с секундами, формат вывода времени и даты также можно изменить в строчке LCD.print(time.gettime(«H:i:s — d.m»));

Заключение. Мы рассмотрели возможность подключения нескольких устройств по протоколу IIC к плате Arduino, что будет полезно знать при проектировании различных DIY поделок своими руками, например метеостанции на Ардуино с датчиком давления. Если у вас остались вопросы по сканеру IIC интерфейсной шины или подключении устройств по данному протоколу — смело оставляйте их в комментариях к этой записи.

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

В этом уроке мы научимся определять адреса устройств на шине I2C, аппаратно устанавливая состояния Start/Stop на шине I2C и передавая байт данных с адресом устройства и битом RW.

Нам понадобится:
  • Arduino х 1шт.
  • LCD дисплей LCD1602 IIC/I2C(синий) или LCD1602 IIC/I2C(зелёный) х 1шт.
  • Trema Shield х 1шт.
  • Trema-модуль i2C Hub х 1шт.
  • Trema-модуль кнопка c проводом х 1шт.
  • Шлейф «мама-мама»для шины I2С х 2шт.
  • Устройства и модули с шиной I2C, адреса которых Вы хотите узнать, до 126 шт.

Для реализации проекта нам необходимо установить одну библиотеку:

  • Библиотека LiquidCrystal_I2C_V112 (для работы с дисплеем LCD1602 по шине I2C)

О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki — Установка библиотек в Arduino IDE, а о том, как работать с LCD дисплеями, на странице Wiki — Работа с символьными ЖК дисплеями.

Видео:
Схема подключения:

Алгоритм работы:
  • При однократном нажатии на кнопку — выводится очередной адрес.
  • При удержании кнопки — производится чтение адресов, всех подключенных к шине I2C устройств.
Код программы:
Алгоритм работы программы:

Код в функции loop() начинает выполняться только при условии, если нажата кнопка. Если таковое событие произошло, то начинает исполняться цикл while() выход из которого осуществляется при отпускании кнопки. В самом цикле происходит подсчёт времени удержания кнопки.

После отпускания кнопки, программа выполняет одно из двух действий:

  • Если кнопка удерживалась меньше 1 секунды, то происходит увеличение порядкового номера выводимого адреса.
  • Если кнопка удерживалась дольше 1 секунды, то происходит чтение всех доступных адресов на шине I2C.

Чтение адресов на шине I2C происходит в цикле for() от 1 до 127, где индекс цикла соответствует проверяемому адресу. Проверка на существование адреса осуществляется следующим образом:

  • Вызывается функция func_START, которая устанавливает состояние СТАРТ на шине I2C и возвращает результат установки данного состояния.
  • Если состояние СТАРТ установлено, то вызывается функция func_SEND, которая передает свой аргумент как байт адреса с битом RW=0 и если на шине зафиксирован ответ ACK, то возвращает результат true, иначе false.
  • Если на шине зафиксирован результат ACK, то переданный адрес сохраняется в массив найденных адресов, за исключением адреса 0x27 который является адресом LCD дисплея.
  • Вызывается функция func_STOP, которая устанавливает состояние СТОП на шине I2C.

И последнее действие программы — вывод данных на дисплей, не зависимо от того, как долго удерживалась кнопка.

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

I2C сканер на Arduino

Автор: Сергей · Опубликовано 26.10.2017 · Обновлено 27.09.2019

В этой статье расскажу как с помощью Arduino сделать I2C сканер, в качестве примера определю адрес LCD1602 дисплей, работающего по интерфейсу I2C.

I2C сканер на Arduino

Немного теории, I2C — это протокол, который позволяет различным устройствам взаимодействовать друг с другом используя одну шину данных SDA и SCL (всего два проводника), так же, для каждого устройства присваивается свой уникальный адрес (максим 127 устройств). Поменять адрес устройства нельзя, он намертво вшит в микросхему, но некоторые производитель предоставил возможность изменять адрес в небольшом диапазоне, это дает возможность подключить несколько одинаковых устройств (с одинаковым чипом) к одной шине.
Иногда, нет возможности найти документацию на микросхему или микросхема не имеет адрес схожий от документации (такое то же бывало), тогда поможет данный скетч. В примере используется Arduino UNO и LCD модуль I2C (который имеет брак и другой адрес, не 0x27), так-же, интерфейс I2C работает только на определенные выводах (в arduino UNO это A4 и A5), приведу таблицу подключения для различных платформ Arduino.

Собираем принципиальную схему

Открываем среду разработки IDE Arduino, копируем скетч и загружаем его в платформу Arduino.

Устройство HID на шине I2C что это такое?

Устройство HID на шине I2C что это такое

Запуск устройства HID на шине I2C невозможен. Код 10. Что делать?

Asus TUF Gaming не работает тачпад

Asus TUF Gaming не работает тачпад

Ошибка Access Denied на сайте Lenovo. Что делать?

Ошибка Access Denied на сайте Lenovo. Что делать?

Не регулируется яркость экрана на Lenovo Z500/Z400

Не регулируется яркость экрана на Lenovo Z500/Z400

Устройство HID на шине I2C в диспетчере устройств

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

В данной статье мы расскажем какое устройство обычно скрывается под данным названием и что можно попробовать сделать самостоятельно для устранения этой проблемы.

Запуск устройства HID на шине I2C невозможен (Код 10)

Для начала разберемся что это за устройство. В 80% случаев им является тачпад. В оставшихся 20% – клавиатура, подключенная по USB мышка или тачскрин (Сенсор экрана, если экран в вашем ноутбуке сенсорный).

что такое Устройство HID на шине I2C

Ошибка запуска устройства с кодом 10

Первым делом нужно проверить работоспособность всех этих устройств: ввести что-либо с клавиатуры, поводить пальцем по тачпаду и т.д.

То, что окажется нерабочим, и будет являться тем самым устройством HID на шине I2C.

Что делать, чтобы устройство заработало?

Самый верный путь – определить модель ноутбука, перейти на официальный сайт, скачать драйвера на все устройства ввода (тачпад, тачскрин, клавиатура) и установить их.

Второй вариант заключается в поиске драйвера для устройства по его идентификатору. Для этого в диспетчере устройств нужно дважды кликнуть мышкой по устройству HID на шине I2C.

что такое Устройство HID на шине I2C

Определение ИД оборудования

В открывшемся окне перейти на вкладку “Сведения” и выбрать свойство “ИД оборудования”.

Далее скопировать самое верхнее значение и вставить его в поиск гугла или яндекса.

Устройство HID на шине I2C что это такое

Поиск драйвера к устройству по его ИД

В полученных результатах выдачи останется отыскать драйвер под ваше устройство.

Если ничего из вышеописанного не помогло и устройство HID на шине I2C все равно отображается в диспетчере устройств с восклицательным знаком и статусом “Запуск этого устройства невозможен. Код 10”, то это означает, что с этим устройством имеются проблемы на аппаратном уровне.

Например, поврежден или отсоединился шлейф или само устройство повреждено, например падением ноутбука или его залитием жидкостью. В этом случае лучше обратиться в сервис. А если все нормально работает, то и вовсе не обращать на него внимание.

Почему не определяются устройства на шине i2c

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

В данной статье мы расскажем какое устройство обычно скрывается под данным названием и что можно попробовать сделать самостоятельно для устранения этой проблемы.

Запуск устройства HID на шине I2C невозможен (Код 10)

Для начала разберемся что это за устройство. В 80% случаев им является тачпад. В оставшихся 20% – клавиатура, подключенная по USB мышка или тачскрин (Сенсор экрана, если экран в вашем ноутбуке сенсорный).

что такое Устройство HID на шине I2C

Ошибка запуска устройства с кодом 10

Первым делом нужно проверить работоспособность всех этих устройств: ввести что-либо с клавиатуры, поводить пальцем по тачпаду и т.д.

То, что окажется нерабочим, и будет являться тем самым устройством HID на шине I2C.

Что делать, чтобы устройство заработало?

Самый верный путь – определить модель ноутбука, перейти на официальный сайт, скачать драйвера на все устройства ввода (тачпад, тачскрин, клавиатура) и установить их.

Второй вариант заключается в поиске драйвера для устройства по его идентификатору. Для этого в диспетчере устройств нужно дважды кликнуть мышкой по устройству HID на шине I2C.

что такое Устройство HID на шине I2C

Определение ИД оборудования

В открывшемся окне перейти на вкладку “Сведения” и выбрать свойство “ИД оборудования”.

Далее скопировать самое верхнее значение и вставить его в поиск гугла или яндекса.

Устройство HID на шине I2C что это такое

Поиск драйвера к устройству по его ИД

В полученных результатах выдачи останется отыскать драйвер под ваше устройство.

Если ничего из вышеописанного не помогло и устройство HID на шине I2C все равно отображается в диспетчере устройств с восклицательным знаком и статусом “Запуск этого устройства невозможен. Код 10”, то это означает, что с этим устройством имеются проблемы на аппаратном уровне.

Например, поврежден или отсоединился шлейф или само устройство повреждено, например падением ноутбука или его залитием жидкостью. В этом случае лучше обратиться в сервис. А если все нормально работает, то и вовсе не обращать на него внимание.

Интерфейсная шина IIC (I2C)

Один из моих самых любимых интерфейсов. Разработан в компании Philips и право на его использование стоит денег, но все на это дружно положили и пользуют в свое удовольствие, называя только по другому. В Atmel его зовут TWI , но от этого ничего не меняется �� Обычно при разборе IIC во всех книгах ограничиваются примером с EEPROM на этом и ограничиваются. Да еще юзают софтверный Master. Не дождетесь, у меня будет подробный разбор работы этой шины как в режиме Master так и Slave, да еще на аппаратных блоках с полным выполнением всей структуры конечного автомата протокола. Но об этом после, а сейчас основы.

Физический уровень.
Данные передаются по двум проводам — провод данных и провод тактов. Есть ведущий (master) и ведомый (slave), такты генерирует master, ведомый лишь поддакивает при приеме байта. Всего на одной двупроводной шине может быть до 127 устройств . Схема подключения — монтажное И

Передача/Прием сигналов осуществляется прижиманием линии в 0 , в единичку устанавливается сама, за счет подтягивающих резисторов . Их ставить обязательно всегда ! Стандарт! Резисторы на 10к оптимальны. Чем больше резистор, тем дольше линия восстанавливается в единицу (идет перезаряд паразитной емкости между проводами) и тем сильней заваливаются фронты импульсов, а значит скорость передачи падает. Именно поэтому у I 2 C скорость передачи намного ниже чем у SPI . Обычно IIC работает либо на скорости 10кбит/с — в медленном режиме, либо на 100кбит/с в быстром. Но в реальности можно плавно менять скорость вплоть до нуля.
Ни в коем случае нельзя переключать вывод микроконтроллера в OUT и дергать ногу на +5. Можно запросто словить КЗ и пожечь либо контроллер либо какой-нибудь девайс на шине. Мало ли кто там линию придавит.

Вся передача данных состоит из Стартовой посылки , битов и стоповой посылки . Порядок изменения уровня на шинах задает тип посылки.

После старта передача одного бита данных идет по тактовому импульсу. То есть когда линия SCL в нуле master или slave выставляют бит на SDA (прижимают — если 0 или не прижимают — если 1 линию SDA ) после чего SCL отпускается и master/slave считывают бит. Таким образом, у нас протокол совершенно не зависит от временных интервалов , только от тактовых битов. Поэтому шину I 2 C очень легко отлаживать — если что то не так, то достаточно снизить скорость до байта в минуту и спокойно, обычными вольтметрами, смотреть что у нас происходит. Правда это не прокатит с железным I 2 C , там нет таких низких скоростей. Но что нам мешает затактовать микроконтроллер от ОЧЕНЬ медленного тактового генератора и отладить все по шагам? ��

Логический уровень
Как передаются отдельные биты понятно, теперь о том что эти биты значат. В отличии от SPI тут умная адресная структура. Данные шлются пакетами, каждый пакет состоит из девяти бит. 8 данных и 1 бит подтверждения/не подтверждения приема.

Первый пакет шлется от ведущего к ведомому это физический адрес устройства и бит направления .
Сам адрес состоит из семи бит (вот почему до 127 устройств на шине), а восьмой бит означает что будет делать Slave на следующем байте — принимать или передавать данные . Девятым битом идет бит подтверждения ACK . Если Slave услышал свой адрес и считал полностью, то на девятом такте он придавит линию SDA в 0, сгенерировав ACK — то есть Понял! Мастер, заметя это, понимает, что все идет по плану и можно продолжать. Если Slave не обнаружился, прозевал адрес, неправильно принял байт, сгорел или еще что с ним случилось, то, соответственно, SDA на девятом такте будет прижать некому и ACK не получится. Будет NACK . Мастер с горя хлопнет водки и прекратит свои попытки до лучших времен.

После адресного пакета идут пакеты с данными в ту или другую сторону, в зависимости от бита RW в заголовочном пакете.
Вот, например, Запись. В квадратиках идут номера битов. W=0

Чтение практически также, но тут есть одна тонкость из-за которой я когда то убил кучу времени. При приеме последнего байта надо дать ведомому понять, что в его услугах больше не нуждаемся и отослать NACK на последнем байте. Если отослать ACK то после стопа Master не отпустит линию — такой уж там конечный автомат. Так что прием двух байтов будет выглядеть так (R=1):
Есть еще одно состояние, как повторный старт .
Это когда мы не обьявляя STOP вкатываем на шину еще один START . После него мы можем обратиться к другому устройству не освобождая шину. Но чаще идет обращение к тому же самому устройству и это связано с особенностями организации памяти.

Организация памяти.
Это относится уже не столько к самому протоколу I 2 C , сколько к заморочкам создателей разных EEPROM и прочих I 2 C устройств. Но встречается это повсеместно, поэтому я расскажу про этот момент. Но, повторюсь, это не аксиома, не стандарт и вообще зависит от конкретного Slave устройства. Так что датит в зубы и вкуривать, но обычно так принято.

Итак, о чем речь.
Как видно из протокола, в первом байте мы адресовываем само устройство , а их может быть до 127 штук. Но в самом устройстве вполне может быть очень сложная структура, с кучей ячеек. Например EEPROM с килобайтами данных внутри. Как обращаться с этими данными? Не считывать же все по очереди от нуля до конца — это долго. Поэтому приняли хитрый формат. Это не стандарт, но юзается повсеместно.

Поясню на примере:
Есть микросхема часов реального времени PCF8583 (я про нее еще напишу, следите за обновлениями), общающася по протоколу I 2 C . Внутри нее ячейки памяти, в которых хранятся часы, минуты, секунды, дата, состояние флагов и куча еще всего. До кучи там еще 240 байт просто так, для свободного пользования. Карта адресов этой микросхемы выглядит так:

И вот надо мне установить дату. Для этого надо мне записать две ячейки памяти с адресами 0х05 и 0x06 . Как это сделать? Из даташита я узнаю, что первый байт данных это адрес куда мы будем обращаться, а потом уже идут данные и со следующим байтом счетчик адреса увеличивается на 1. Там же, в даташите, написано что эти часы откликаются на Slave-адрес 1010000х где х — состояние ноги А0 микросхемы . Я эту ногу сразу посадил на 0 так что Slave-адрес у меня 10100000. Очевидно, что на одной шине может быть не более двух экземпляров этой микросхемы с адресами 10100000 и 10100001.

Задача решается так:
Вот и славно. Часы установлены и начали тикать. Но вот надо нам считать те же данные, а вдруг изменились?
С записью все понятно — записали вначале адрес, а потом следом записали данные. А умная микросхема все прекрасно поняла и рассовала по ячейкам. А с чтением? А с чтением все через задницу, в смысле через запись.

То есть, мы, вначале, записываем один байт — адрес. Потом делаем повторный старт, затем снова обращаемся к часам по ее Slave-адресу , но уже с битом R , на чтение. И умная микруха выдает нам байты с адреса который мы в нее вот только что записали. Выглядит это так:
В этих часах так, у других микрух может быть все по другому, но в 99% очень похоже. Адрес, например, может быть двухбайтным или страницу надо будет указать, но сути это не меняет. Цепочка запись-повстарт-чтение это повсеместно.
Вот так, кстати, выглядит чтение данных из часов PCF8583 на экране моего логического анализатора. Тут не полная посылка (все 5 байт просто не влезли в экран), но тут четко видно запись начального адреса, потом повторный старт, и чтение из девайса.

Скриншот с осциллографа RIGOL 1042CD

Арбитраж шины I 2 C.
Почему то все мануалы для начинающих в которых рассматривалась тема протокола IIC как то ссыкливо замалчивают возможность работы двух ведущих на линии. Master-Slave и все тут. А если у нас демократия? И каждый сам себе Master и сам себе Slave ? Согласен, редкий случай, но тем не менее, описывать так описывать. Короче, в случае подобного садо-мазо варианта действует железное правило — кто раньше встал того и тапки. В смысле кто первый начал вещать тот и текущий Master .
Но вот случилось вообще невероятное — два Ведущих начали вещать одновременно . Прям совсем одновременно. Как быть? А тут нам поможет свойство монтажного И — где против лома нуля нет приема. Короче, оба мастера бит за битом играют в простую игру ножик-камень(1 и 0 соответственно). Кто первый выкинет камень против ножика тот и побеждает арбитраж, продолжая вещать дальше. Так что очевидно, что самый важный адрес должен начинаться с нулей, чтобы тот кто к нему пытался обращаться всегда выигрывал арбитраж. Проигравшая же сторона вынуждена ждать пока шина не освободится.

Вроде бы все, практический пример с AVR будет потом, а пока помедитируйте над диаграммой работы конечного автомата TWI передатчика ATmega8. Скоро я вас буду этим грузить!

Страшна? �� На самом деле там все не так брутально. Можно обойтись вообще парой десятков строк кода на ассемблере.

Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!

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

202 thoughts on “Интерфейсная шина IIC (I2C)”

(1) OpenID работает криво. Я зашёл как blacklion.livejournal.com и всё равно справа-сверху «войти» (а не «выйти») и не даю комментировать. Пришлось регистрироваться и теперь тут два меня.

(2) Софтового мастера сделать не сложно. А вот слейва как-то просто не получается.

Щас попробую с опен ид поиграться.

Более того, многие предпочитают делать софтовый И2С мастер чтобы не заморачиваться с встроенным в TWI конечным автоматом.

Более того, многие предпочитают делать софтовый И2С мастер чтобы не заморачиваться с встроенным в TWI конечным автоматом.
Я когда первый раз подходил к электронике смотрел на PIC (зачем я это делал!? Зачем на PIC?!) так реализовал мастера в качестве упражнения за вечер. А вот слейва так и не осилил…

Я сделал софтового слейва на AT89C2051, но работало жутко медленно.

плюсадин. я уже раз 5 жаловался что логины глючат �� нашел выход, что залогинился, пару минуток подождал и рефреш. работает, но бесит :\

DI HALT спасибо за статью. Давно ждал рассказ про I2C. ��

Могу поделицца опытом работы конкретно с DS1307. Он, сука, еще тот глючный девайс. Вроде просто, но не все просто. ПРопиши бит СН, запусти часы, не забудь про бит снова, ой а чо горим — а мы забыли Vbat на землю положить…

У меня их почти полный аналог 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)) Буду ждать исходников…

Отличная статья! А есть последняя диаграмма только в чуть лучшем качестве? А то буквы трудно различить.

Красные пути — нормальная работа
Синие — возможные косяки.

Почему не определяются устройства на шине i2c

  • />Суббота в 13:30
  • Тема:Каково назначение опции форума "Создать Статус"?
  • От:byRAM
  • />Суббота в 13:30
  • Тема:Каково назначение опции форума "Создать Статус"?
  • От:byRAM
Другие известные форумы и сайты по электронике

все что посвящено электронике и общению специалистов. реклама других ресурсов.

  • Магазины
  • Форумы и конференции
  • Производители
  • Информационные ресурсы
  • Поисковики
  • FTP-серверы
  • />24 августа
  • Тема:Кто закупался в www.zoom-ec.ru?
  • От:gte
  • />24 августа
  • Тема:Кто закупался в www.zoom-ec.ru?
  • От:gte
В помощь начинающему

вопросы начального уровня

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 fill Vasily_ Егоров Walrus

  • ARM, 32bit
  • MCS51, AVR, PIC, STM8, 8bit
  • Программирование
  • Схемотехника
  • Интерфейсы
  • />46 минут назад
  • Тема:Сопротивление изоляции инвертора
  • От:Plain
  • />46 минут назад
  • Тема:Сопротивление изоляции инвертора
  • От:Plain
International Forum

This is a special forum for English spoken people, read it first.

  • />23 июня
  • От:OwlSurf
  • />23 июня
  • От:OwlSurf
Образование в области электроники

все что касается образования, процесса обучения, студентам, преподавателям.

Модераторы раздела des00

  • />16 августа
  • Тема:Ищу книги по теории систем автор Шуремов
  • От:Fynjisx
  • />16 августа
  • Тема:Ищу книги по теории систем автор Шуремов
  • От:Fynjisx
Обучающие видео-материалы и обмен опытом

Обсуждение вопросов создания видео-материалов

Модераторы раздела iosifk

  • />29 августа
  • Тема:Интеграция CADLib Модель и Архив с Artlantis
  • От:Paola Shar
  • />29 августа
  • Тема:Интеграция CADLib Модель и Архив с Artlantis
  • От:Paola Shar

Cистемный уровень проектирования

    Последнее сообщение
Вопросы системного уровня проектирования

Применение MATLAB, Simulink, CoCentric, SPW, SystemC ESL, SoC

Модераторы раздела Rst7

  • />6 минут назад
  • Тема:Вопрос по модулятору АМ
  • От:_sda
  • />6 минут назад
  • Тема:Вопрос по модулятору АМ
  • От:_sda
Математика и Физика

Модераторы раздела Rst7

  • />Суббота в 09:19
  • Тема:модель 8PSK модема
  • От:petrov
  • />Суббота в 09:19
  • Тема:модель 8PSK модема
  • От:petrov
Операционные системы

Linux, Win, DOS, QNX, uCOS, eCOS, RTEMS и другие

Модераторы раздела Rst7

  • Программирование
  • Linux
  • uC/OS-II
  • scmRTOS
  • FreeRTOS
  • Android
  • />3 минуты назад
  • Тема:FreeRTOS проба семафора.
  • От:Arlleex
  • />3 минуты назад
  • Тема:FreeRTOS проба семафора.
  • От:Arlleex
Документация

оформление документации и все что с ней связано

Модераторы раздела Rst7

  • />Воскресенье в 19:44
  • Тема:децимальные номера
  • От:MrGalaxy
  • />Воскресенье в 19:44
  • Тема:децимальные номера
  • От:MrGalaxy
Системы CAD/CAM/CAE/PLM

обсуждение САПР AutoCAD, Компас, SolidWorks и др.

  • />4 августа
  • Тема:Итоги Практической конференции 4.0 «Опыт цифрово…
  • От:Maxim_S
  • />4 августа
  • Тема:Итоги Практической конференции 4.0 «Опыт цифрово…
  • От:Maxim_S
Разработка цифровых, аналоговых, аналого-цифровых ИС

Модераторы раздела Rst7

  • />18 августа
  • Тема:Genus 15.2 ошибка syn_opt
  • От:Aleх
  • />18 августа
  • Тема:Genus 15.2 ошибка syn_opt
  • От:Aleх
Электробезопасность и ЭМС

Обсуждение вопросов электробезопасности и целостности сигналов

Модераторы раздела Rst7

  • ЭМС
  • Электробезопасность
  • />20 часов назад
  • Тема:НИП по ГОСТ 30804.4.4: чем развязать RS-485, CAN…
  • От:Arlleex
  • />20 часов назад
  • Тема:НИП по ГОСТ 30804.4.4: чем развязать RS-485, CAN…
  • От:Arlleex
Управление проектами

Управление жизненным циклом проектов, системы контроля версий и т.п.

Модераторы раздела Rst7

  • />17 марта
  • Тема:Не проходит авторизацию при push после смены пра…
  • От:KARLSON
  • />17 марта
  • Тема:Не проходит авторизацию при push после смены пра…
  • От:KARLSON
Нейронные сети и машинное обучение (NN/ML)

Форум для обсуждения вопросов машинного обучения и нейронных сетей

Модераторы раздела Rst7

  • />10 июля
  • Тема:Задачка про побор алгоритма управления синтезато…
  • От:Cach
  • />10 июля
  • Тема:Задачка про побор алгоритма управления синтезато…
  • От:Cach

Программируемая логика ПЛИС (FPGA,CPLD, PLD)

    Последнее сообщение
Среды разработки — обсуждаем САПРы

Quartus, MAX, Foundation, ISE, DXP, ActiveHDL и прочие.
возможности, удобства.

Модераторы раздела vetal />des00 />

  • />Суббота в 19:06
  • Тема:Моделирование ip ядра nco в modelsim-altera
  • От:Zversky
  • />Суббота в 19:06
  • Тема:Моделирование ip ядра nco в modelsim-altera
  • От:Zversky
Работаем с ПЛИС, области применения, выбор

на чем сделать? почему не работает? кто подскажет?

Модераторы раздела vetal />des00 />

  • />3 часа назад
  • Тема:ПЛИС наши (Россия)
  • От:AlexG
  • />3 часа назад
  • Тема:ПЛИС наши (Россия)
  • От:AlexG
Языки проектирования на ПЛИС (FPGA)

Verilog, VHDL, AHDL, SystemC, SystemVerilog и др.

Модераторы раздела aosp vetal des00

  • />42 минуты назад
  • Тема:Красивое решение с использованием DSP48
  • От:alexPec
  • />42 минуты назад
  • Тема:Красивое решение с использованием DSP48
  • От:alexPec
Системы на ПЛИС — System on a Programmable Chip (SoPC)

разработка встраиваемых процессоров и периферии для ПЛИС

Модераторы раздела vetal des00 Omen_13

  • />22 часа назад
  • Тема:Появилась ошибка при сборке проекта НИОС
  • От:_sda
  • />22 часа назад
  • Тема:Появилась ошибка при сборке проекта НИОС
  • От:_sda

Цифровая обработка сигналов — ЦОС (DSP)

    Последнее сообщение
Сигнальные процессоры и их программирование — DSP

Обсуждение различных сигнальных (DSP) процессоров, возможностей, совместимости и связанных с этим тем.

Модераторы раздела des00

  • />19 июля
  • Тема:Вопросы новичка
  • От:mars_208
  • />19 июля
  • Тема:Вопросы новичка
  • От:mars_208
Алгоритмы ЦОС (DSP)

Обсуждение вопросов разработки и применения (программирования) алгоритмов цифровой обработки сигналов.

Модераторы раздела des00

  • />2 минуты назад
  • Тема:JPEG: определить величину качества для сжатия, п…
  • От:lexx
  • />2 минуты назад
  • Тема:JPEG: определить величину качества для сжатия, п…
  • От:lexx

Микроконтроллеры (MCs)

    Последнее сообщение
Cредства разработки для МК

FAQ, How-to, тонкости работы со средствами разработки

  • IAR
  • Keil
  • GNU/OpenSource средства разработки
  • />Среда в 12:56
  • Тема:IAR не поддерживает typeof ?
  • От:repstosw
  • />Среда в 12:56
  • Тема:IAR не поддерживает typeof ?
  • От:repstosw
  • STM
  • NXP
  • Microchip (Atmel)
  • TI, Allwinner, Nordic Semiconductor, Espressif Systems и другие
  • />2 часа назад
  • Тема:stm32 защитный бит.
  • От:dimir
  • />2 часа назад
  • Тема:stm32 защитный бит.
  • От:dimir
  • />8 часов назад
  • Тема:Не подключается кварц, Atmega8
  • От:astral_
  • />8 часов назад
  • Тема:Не подключается кварц, Atmega8
  • От:astral_
MSP430

Модераторы раздела VAI

  • />21 апреля
  • Тема:MSP430F5172 XT1
  • От:k155la3
  • />21 апреля
  • Тема:MSP430F5172 XT1
  • От:k155la3
Все остальные микроконтроллеры

и все что с ними связано

  • PIC
  • MCS51
  • PowerQUICC
  • HC(S)08
  • AVR32
  • STM8
  • MIPS
  • />12 часов назад
  • Тема:как указать в линкере размер стека/хипа с указан…
  • От:jcxz
  • />12 часов назад
  • Тема:как указать в линкере размер стека/хипа с указан…
  • От:jcxz
Отладочные платы

Вопросы, связанные с отладочными платами на базе МК: заказ, сборка, запуск

  • Arduino
  • Raspberry Pi
  • Rainbow
  • Siberia
  • EVMxxxx
  • />30 августа
  • Тема:China-Link, Вариант отладчика из Китая
  • От:Galf
  • />30 августа
  • Тема:China-Link, Вариант отладчика из Китая
  • От:Galf

Печатные платы (PCB)

    Последнее сообщение
Разрабатываем ПП в САПР — PCB development

FAQ, вопросы проектирования в ORCAD, PCAD, Protel, Allegro, Spectra, DXP, SDD, WG и др.

Модераторы раздела SergM />fill />

  • Библиотеки компонентов
  • Altium Designer, DXP, Protel
  • P-CAD 200x howto
  • Эремекс, Delta Design
  • Cadence
  • Примеры
  • Zuken CADSTAR
  • Siemens EDA — Xpedition, PADS (ex. Mentor)
  • Бесплатные САПР: KiCAD, EasyEDA, EAGLE и др.
  • />18 часов назад
  • Тема:Altium Designer для начинающих
  • От:Bobrik
  • />18 часов назад
  • Тема:Altium Designer для начинающих
  • От:Bobrik
Работаем с трассировкой

тонкости PCB дизайна, от Spectra и далее.

Модераторы раздела fill

  • />25 августа
  • Тема:Коммутатор VGA
  • От:DAV
  • />25 августа
  • Тема:Коммутатор VGA
  • От:DAV
Изготовление ПП — PCB manufacturing

Фирмы, занимающиеся изготовлением, качество, цены, сроки

Модераторы раздела fill

  • ПСБ Технолоджи
  • ТеПро
  • PS-Electro
  • Резонит
  • PCB Professional
  • Абрис
  • ОАО "НИЦЭВТ"
  • ООО "М-Плата"
  • в домашних условиях
  • />18 августа
  • Тема:ООО "АтонЭл", изготовление печатных плат
  • От:Anastasiaaa123
  • />18 августа
  • Тема:ООО "АтонЭл", изготовление печатных плат
  • От:Anastasiaaa123

Сборка РЭУ

    Последнее сообщение
Пайка и монтаж

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

  • />Пятница в 15:22
  • Тема:Варианты установщиков SMT
  • От:byRAM
  • />Пятница в 15:22
  • Тема:Варианты установщиков SMT
  • От:byRAM
Корпуса

обсуждаем какие есть копруса, где делать и прочее

  • />16 августа
  • Тема:Покрытие фрезерованного стеклотекстолита
  • От:k155la3
  • />16 августа
  • Тема:Покрытие фрезерованного стеклотекстолита
  • От:k155la3
Вопросы надежности и испытаний

расчеты, методики, подбор компонентов

  • />22 августа
  • Тема:Полнота и достоверность информации при расчёте э…
  • От:В. Алёна
  • />22 августа
  • Тема:Полнота и достоверность информации при расчёте э…
  • От:В. Алёна

Аналоговая и цифровая техника, прикладная электроника

    Последнее сообщение
Вопросы аналоговой техники

разработка аналоговых схем, моделирование схем в SPICE, расчёты и анализ, выбор элементной базы

Модераторы раздела Alexandr ViKo Tanya Егоров

  • />2 часа назад
  • Тема:Подскажите какой нибудь доступный многоканальный…
  • От:arhiv6
  • />2 часа назад
  • Тема:Подскажите какой нибудь доступный многоканальный…
  • От:arhiv6
Цифровые схемы, высокоскоростные ЦС

High Speed Digital Design

  • />12 августа
  • Тема:Непонятна микросхема
  • От:aaarrr
  • />12 августа
  • Тема:Непонятна микросхема
  • От:aaarrr
RF & Microwave Design

wireless технологии и не только

Модераторы раздела l1l1l1

  • />Только что
  • Тема:Вопросы по CST
  • От:Turgenev
  • />Только что
  • Тема:Вопросы по CST
  • От:Turgenev
Метрология, датчики, измерительная техника

Все что связано с измерениями: измерительные приборы (осциллографы, анализаторы спектра и пр.), датчики, обработка результатов измерений, калибровка, технологии измерений и др.

Модераторы раздела ViKo />Tanya />

  • />Четверг в 17:45
  • Тема:CMOS сенсор PYTHON (NOIP1SN1300/500/300) — режим…
  • От:svedach
  • />Четверг в 17:45
  • Тема:CMOS сенсор PYTHON (NOIP1SN1300/500/300) — режим…
  • От:svedach
АВТО электроника

особенности электроники любых транспортных средств: автомашин и мотоциклов, поездов, судов и самолетов, космических кораблей и летающих тарелок.

Модераторы раздела Vasily_

  • />6 июля
  • Тема:Mazda Premacy Crew проблема с EBU АКПП
  • От:Михаил99999
  • />6 июля
  • Тема:Mazda Premacy Crew проблема с EBU АКПП
  • От:Михаил99999
Умный дом
  • />9 августа
  • Тема:Сломалась плита AEG 47056VS-MN
  • От:Fynjisx
  • />9 августа
  • Тема:Сломалась плита AEG 47056VS-MN
  • От:Fynjisx
3D печать

3D принтеры, наборы, аксессуары, ПО

  • />29 июля
  • Тема:Кто- нибудь пробовал Klipper ?
  • От:muravei
  • />29 июля
  • Тема:Кто- нибудь пробовал Klipper ?
  • От:muravei
Робототехника

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

  • />31 марта
  • Тема:Подключение дисплея 3.2inch 320×240 Touch LCD (А…
  • От:Aaronli
  • />31 марта
  • Тема:Подключение дисплея 3.2inch 320×240 Touch LCD (А…
  • От:Aaronli
Ремонт и отладка

обсуждение вопросов ремонта и отладки различных устройств и готовых изделий

Модераторы раздела Herz

  • />17 часов назад
  • Тема:Микросхема DCDC LN3492P6MR 8A6D SOT23-6
  • От:Alex1603
  • />17 часов назад
  • Тема:Микросхема DCDC LN3492P6MR 8A6D SOT23-6
  • От:Alex1603

Силовая Электроника — Power Electronics

    Последнее сообщение
Силовая Преобразовательная Техника

Источники питания электронной аппаратуры, импульсные и линейные регуляторы. Топологии AC-DC, DC-DC преобразователей (Forward, Flyback, Buck, Boost, Push-Pull, SEPIC, Cuk, Full-Bridge, Half-Bridge). Драйвера ключевых элементов, динамика, алгоритмы управления, защита. Синхронное выпрямление, коррекция коэффициента мощности (PFC)

Модераторы раздела Herz />Егоров />

  • />15 часов назад
  • Тема:Горят транзисторы в мостовой схеме.
  • От:tolya86
  • />15 часов назад
  • Тема:Горят транзисторы в мостовой схеме.
  • От:tolya86
Обратная Связь, Стабилизация, Регулирование, Компенсация

Организация обратных связей в цепях регулирования, выбор топологии, обеспечение стабильности, схемотехника, расчёт

Модераторы раздела Herz />Егоров />

  • />28 июня
  • Тема:Писк трансформатора Flyback при малой нагрузке
  • От:Ioann_II
  • />28 июня
  • Тема:Писк трансформатора Flyback при малой нагрузке
  • От:Ioann_II
Первичные и Вторичные Химические Источники Питания

Li-ion, Li-pol, литиевые, Ni-MH, Ni-Cd, свинцово-кислотные аккумуляторы. Солевые, щелочные (алкалиновые), литиевые первичные элементы. Применение, зарядные устройства, методы и алгоритмы заряда, условия эксплуатации. Системы бесперебойного и резервного питания

Модераторы раздела Herz />Егоров />

  • />31 августа
  • Тема:подскажите простой способ сделать зарядку двух L…
  • От:dlsh
  • />31 августа
  • Тема:подскажите простой способ сделать зарядку двух L…
  • От:dlsh
Высоковольтные Устройства — High-Voltage

Высоковольтные выпрямители, умножители напряжения, делители напряжения, высоковольтная развязка, изоляция, электрическая прочность. Высоковольтная наносекундная импульсная техника

Модераторы раздела Herz

  • />5 апреля
  • Тема:Маломощный трансформатор 220В -> 6000
  • От:Алексей Р
  • />5 апреля
  • Тема:Маломощный трансформатор 220В -> 6000
  • От:Алексей Р
Электрические машины, Электропривод и Управление

Электропривод постоянного тока, асинхронный электропривод, шаговый электропривод, сервопривод. Синхронные, асинхронные, вентильные электродвигатели, генераторы

Модераторы раздела Herz

  • />25 августа
  • Тема:Асинхронный мотор-колесо.
  • От:Oleg.normalniy
  • />25 августа
  • Тема:Асинхронный мотор-колесо.
  • От:Oleg.normalniy
Индукционный Нагрев — Induction Heating

Технологии, теория и практика индукционного нагрева

Модераторы раздела Herz

  • />31 июля
  • Тема:Математическая модель индуктора.
  • От:Fynjisx
  • />31 июля
  • Тема:Математическая модель индуктора.
  • От:Fynjisx
Системы Охлаждения, Тепловой Расчет – Cooling Systems

Охлаждение компонентов, систем, корпусов, расчёт параметров охладителей

Модераторы раздела Herz

  • />1 июня
  • Тема:Сравнение экспериментальных данных с расчетом
  • От:ZodiaC
  • />1 июня
  • Тема:Сравнение экспериментальных данных с расчетом
  • От:ZodiaC
Моделирование и Анализ Силовых Устройств – Power Supply Simulation

Моделирование силовых устройств в популярных САПР, самостоятельных симуляторах и специализированных программах. Анализ устойчивости источников питания, непрерывные модели устройств, модели компонентов

Модераторы раздела Herz />Егоров />

  • />1 августа
  • Тема:Моделирование в LTSpice, достоверность результат…
  • От:rp2004
  • />1 августа
  • Тема:Моделирование в LTSpice, достоверность результат…
  • От:rp2004
Компоненты Силовой Электроники — Parts for Power Supply Design

Силовые полупроводниковые приборы (MOSFET, BJT, IGBT, SCR, GTO, диоды). Силовые трансформаторы, дроссели, фильтры (проектирование, экранирование, изготовление), конденсаторы, разъемы, электромеханические изделия, датчики, микросхемы для ИП. Электротехнические и изоляционные материалы.

Модераторы раздела Herz />Егоров />

  • />27 августа
  • Тема:Расчет индуктивности
  • От:k155la3
  • />27 августа
  • Тема:Расчет индуктивности
  • От:k155la3

Интерфейсы

    Последнее сообщение
Форумы по интерфейсам

все интерфейсы здесь

  • ISDN/G.703/E1
  • ISA/PCI/PCI-X/PCI Express
  • Wireless/Optic
  • RS232/LPT/USB/PCMCIA/FireWire
  • Fast Ethernet/Gigabit Ethernet/FibreChannel
  • Интерфейсы для "интеллектуального дома"
  • от ТТЛ до LVDS здесь
  • IDE/ATA/SATA/SAS/SCSI/CF
  • Аудио/Видео интерфейсы
  • Сотовая связь и ее приложения
  • FAQ по XPort/WiPort
  • Controller Area Network (CAN)
  • />8 минут назад
  • Тема:уйти от проводной связи к WiFi? или что то еще?
  • От:nanorobot
  • />8 минут назад
  • Тема:уйти от проводной связи к WiFi? или что то еще?
  • От:nanorobot

Поставщики компонентов для электроники

    Последнее сообщение
Поставщики всего остального

от транзисторов до проводов

  • />29 августа
  • Тема:Порекомендуйте вибростойкий DIP-переключатель
  • От:vladec
  • />29 августа
  • Тема:Порекомендуйте вибростойкий DIP-переключатель
  • От:vladec
Компоненты

Закачка тех. документации, обмен опытом, прочие вопросы.

  • Тех. документация
  • Микросхемы
  • Транзисторы
  • Диоды
  • Резисторы
  • Средства индикации
  • />Суббота в 16:51
  • Тема:Помогите опознать микросхему по функционалу
  • От:Plain
  • />Суббота в 16:51
  • Тема:Помогите опознать микросхему по функционалу
  • От:Plain

Майнеры криптовалют и их разработка, BitCoin, LightCoin, Dash, Zcash, Эфир

    Последнее сообщение
Обсуждение Майнеров, их поставки и производства

наблюдается очень большой спрос на данные устройства.

  • />16 июля, 2021
  • Тема:Материнские платы для майнинга
  • От:Doka
  • />16 июля, 2021
  • Тема:Материнские платы для майнинга
  • От:Doka

Дополнительные разделы — Additional sections

    Последнее сообщение
Встречи и поздравления

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

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />14 декабря, 2021
  • Тема:С Праздником !
  • От:makc
  • />14 декабря, 2021
  • Тема:С Праздником !
  • От:makc
Ищу работу

ищу работу, выполню заказ, нужны клиенты — все это сюда

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />Воскресенье в 11:15
  • Тема:Ищу возможность поработать c платой Zynq в реаль…
  • От:baumanets
  • />Воскресенье в 11:15
  • Тема:Ищу возможность поработать c платой Zynq в реаль…
  • От:baumanets
Предлагаю работу

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

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />14 часов назад
  • Тема:Сургут, нужен удаленный помощник
  • От:born.work
  • />14 часов назад
  • Тема:Сургут, нужен удаленный помощник
  • От:born.work
Куплю

микросхему; устройство; то, что предложишь ты ��

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />Воскресенье в 18:55
  • Тема:Куплю микросхему 373AL/CL
  • От:at90
  • />Воскресенье в 18:55
  • Тема:Куплю микросхему 373AL/CL
  • От:at90
Продам

есть что продать за деньги, пиво, даром ?
Реклама товаров и сайтов также здесь.

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />Вчера в 06:07
  • Тема:STM32G030C8T6 — 2400 шт (катушка) 150 р/шт с НДС
  • От:Andrey190
  • />Вчера в 06:07
  • Тема:STM32G030C8T6 — 2400 шт (катушка) 150 р/шт с НДС
  • От:Andrey190
Объявления пользователей

Тренинги, семинары, анонсы и прочие события

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />19 часов назад
  • Тема:А-КОНТРАКТ приглашает на выставку РОС-ГАЗ-ЭКСПО
  • От:А-КОНТРАКТ
  • />19 часов назад
  • Тема:А-КОНТРАКТ приглашает на выставку РОС-ГАЗ-ЭКСПО
  • От:А-КОНТРАКТ
Общение заказчиков и потребителей электронных разработок

Обсуждение проектов, исполнителей и конкурсов

Модераторы раздела VAI aosp SergM vetal KRS Alexandr des00 Uladzimir Rst7 iosifk ViKo Herz l1l1l1 Tanya Сергей Борщ Omen_13 Vasily_ Егоров Walrus

  • />16 часов назад
  • Тема:Скрытое видео наблюдение
  • От:btb74
  • />16 часов назад
  • Тема:Скрытое видео наблюдение
  • От:btb74

Нестабильная работа с I2C под STM32

Волею судеб мне пришлось разрабатывать прошивку для одного устройства на основе микроконтроллера STM32F103. Функций у устройства много, в том числе и общение с EEPROM подключенным посредством протокола I 2 C. Кто не знает, микроконтроллеры STM32 во многих своих версиях поддерживают работу по данному протоколу на аппаратном уровне. Это значит, что у микросхемы микроконтроллера присутствуют специальные выводы, которые можно использовать в том числе и для работы по протоколу I 2 C, а все издержки по этому протоколу выполняются «железом» микроконтроллера.

микросхема, eeprom

Вообще, I 2 C — штука популярная. Реализуется не так сложно, для его работы требуется всего два сигнальных провода. По одному подаются тактовые импульсы, по второму происходит передача данных, привязанная к тактам первого провода. К шире или выводам I 2 C можно подключить несколько устройств, они не будут мешать друг-другу, т.к. при обращении к конкретному устройству указывается его уникальный адрес.

Шина I 2 C не высокоскоростная и предназначена в первую очередь для обмена данными с различными датчиками, модулями и внешними системами. Через шину прокачать много информации не выйдет, но этого и не требуется. Главное, что она проста, дешева и универсальна. Ну много ли данных передает в секунду датчик температуры или давления? Сущие байты. Этого вполне достаточно.

Как правило в шине I 2 C применяется система с одним ведущим устройством и подключаемыми к нему ведомыми. В качестве ведущего устройства, разумеется, используется микроконтроллер. И он опрашивает подключенные устройства, в надежде получить с них данные. Каким же образом передаются данные по-фактически одному проводу? Конечно, передача данных по одному проводу в I 2 C не является полнодуплексной. Нет возможности в стандарте по одному проводу передавать и принимать данные одновременно. Поэтому, команды на передачу дает ведущее устройство, а все остальные слушают и отвечают, когда это им позволяется.

Простота протокола I 2 C иногда оборачивается и обратной стороной. Отлаживать проблемы, возникающие в коммуникации с внешними устройствами зачастую очень не просто. Ведь в цифровом мире либо устройство работает, либо нет. А еще больше усложняет проблему случай, когда вроде бы работает, а потом, по какой-то причине не совсем работает. Вот именно такая петрушка и произошла в моем случае.

Для реализации микропрограммы был выбран фреймворк STM32Arduino, так как требовалось использовать некоторые библиотеки, которые легче взять готовые, нежели разрабатывать их заново. К чипу же STM32 подключена обычная микросхема EEPROM на несколько килобит. EEPROM используется для частых записей, для чего не предназначена Flash-память на чипе STM32. Все аппаратные подключения проведены в строгом соответствии с документацией как производителя микроконтроллера, так и микросхемы EEPROM. И именно проверка того, как сделаны аппаратные подключения, надежно ли питание, есть ли все необходимые подтяжки и прочее, должна происходить в самую первую очередь, если возникла проблема. Иначе можно потратить годы на то, чтобы найти программную причину ошибки, особенно там, где ее нет.

В моем случае проблема заключалась в выдаче недостоверных результатов с EEPROM и невозможность записи. Точнее запись проходила, но на конечный осмысленный результат они никак не влияла. Причем неполадка появлялась только после аппаратного перезапуска устройства и примерно один раз из десяти. Присутствие какой-либо адекватной реакции от всех программах слоев, на которые опирается STM32Duino ожидать не стоит. I 2 C протокол простой и он либо работает, либо нет. И он работал, выдавал данные, причем даже если данные с EEPROM приходили откровенно левые, то никакие ошибки обращения с библиотекой Wire не возникало. Пришлось начать копать интернет в поисках похожих ошибок и методов их решения.

Как оказалось, проблема при работе с I 2 C на чипах STM32, особенно семейства F103, возникает чуть ли не у каждого второго пользователя чипов. Причем независимо от того, на чем он пишет свой код: HAL, Arduino, Mbed или еще чего. Проблем возникает много, у кого-то ничего не работает сразу, что несколько легче, так как искать ошибку проще, а у других все работает из коробки, но не постоянно. Основные проблемы, на которые натыкаются пользователи кроются в некоторых, назовем их так, особенностях структуры чипов STM32F10x, да ошибках, которые присутствуют в HAL.

Приведу основные причины возникновения неполадок с I 2 C, полученные после изучения «всего интернета»:

  • Ненадежное аппаратное подключение, ненадежное неверное питание, несоблюдение рекомендаций по подключению.
  • Блокировка шины на стороне микроконтроллера со статусом Busy.
  • Перепутанные выходы, перепутанная инициализация при добавлении второго канала I 2 C на многоканальных чипах. Ошибка из серии «Я скопировал оттуда, где работало, а тут не работает».

Кстати, последняя ошибка встречается не столько при простом копировании кода, завязанного на работу через I 2 C, а сколько на его инициализацию. STM32 штука сложная и если невнимательно работать с Cube или писать инициализацию своими руками, то наверняка куда-то может затесаться мизерная ошибочка, которую замыленный глаз уже не в состоянии разглядеть. Вторая же ошибка по большей части связана с неверной (а зачастую с бездумной) инициализацией микроконтроллера, но присутствуют и особенности реализации (читай ошибки) в самом чипе. С ними (обнаруженными и признанными) и объясняется что делать в замечательном документе Errata sheet (ссылка внизу статьи).

В общем наилучшее, что мог создать коллективный разум, это код принудительной переинициализации функции I 2 C через HAL с дополнительными задержками:

/* USER CODE BEGIN SysInit */
HAL_RCC_I2C1_CLK_ENABLE();
HAL_Delay(100); HAL_RCC_I2C1_FORCE_RESET();
HAL_Delay(100);
__HAL_RCC_I2C1_RELEASE_RESET();
HAL_Delay(100);
/* USER CODE END SysInit */

В Arduino на STM32 данный блок так же можно применить, но он не помогает, по крайней мере, в моем случае. Пришлось еще немного пораскинуть мозгами и попытаться докопаться до причины проблемы, а потом попытаться ее решить. В моем случае обмен данными с EEPROM по I 2 C идет без каких-либо проблем. Данные читаются, записываются, никаких ошибок не возникает. Только вот в одном разе из 10 после аппаратной перезагрузки всей системы, EEPROM начинает выдавать совершенно левые данные, при этом никаких ошибок не возникает. С записью тоже в такие моменты не все гладко, проверить-то никак.

Как известно, чипы STM32 многофункциональны и многие из выводов микросхем могут быть использованы под различные функции. У многих микроконтроллеров, не только у STM32, после перезагрузки, некоторые выводы могут переключиться в так называемые неинициализированные состояния. Обычный софтверный разработчик, как правило не задумывается над тем, какой у него уровень на выводах микроконтроллера после его перезагрузки. Высокий? Низкий? Серединный? При использовании фирменного конфигуратора STM32Cube есть возможность настроить инициализацию выводов и некоторых других функций микроконтроллера путем относительно простого конфигурирования. Но данная процедура может быть опущена, а инициализацию можно провести позже, например, при процедуре вызова той или иной функции. Именно последним путем и пошли разработчики STM32Duino. При загрузке микроконтроллера происходит так называемая базовая инициализация функций микроконтроллера, ножки выводов принимают значения по умолчанию. А вот если с данной конкретной ножки требуется другая функция, то ее инициализация происходит при первом вызове соответствующей функции.

В чипах STM32 инициализация происходит очень быстро, ну сами чипы скоростные, это, во-первых, а во-вторых, загрузчик не тормозит загрузку пользовательского кода, так как вызывается при соответствующей аппаратной комбинации. Значит, проблема неинициализированных «ног», когда на них болтается неизвестно что, встает не в полный рост. А вот на других чипах микроконтроллеров, где загрузчик некоторое время ожидает подачу ему сигнала и только потом переходит на пользовательский код, проблема может существенно попортить жизнь. Представьте, что на такой «ноге», которая еще не определилась с уровнем своего сигнала, «висит» управляющий контакт реле. И вот на реле идет жуткая последовательность непонятных сигналов. Что ему делать? Дергаться туда-сюда, пока микроконтроллер не определиться со своим выводом?

Опытный читатель или электронщик, уже догадался, в чем изюминка порылась. Микросхема EEPROM возвращает неверные данные, а библиотека, работающая с I 2 C, говорит, что все нормально, ошибок нет. Суть нестабильного поведения кроется в следующем. На универсальных чипах STM32F103 многие из выводов многофункциональны. При неверной инициализации или отсутствии инициализации, на «ногах», подключенных к микросхеме EEPROM, может появиться произвольный сигнал, который «сведет с ума» саму микросхему EEPROM (команды на обмен данными с EEPROM та еще китайская азбука, куча условностей, задержек и прочего). Да, она будет как-то реагировать на команды, но вот выдавать данные может совсем не те, что должна. Повторная инициализация I 2 C в микроконтроллере ничего не даст, так как ведомое устройство уже не в себе и вывести его из себя можно только аппаратной перезагрузкой микросхемы EEPROM (перезагрузка микроконтроллера тут не помогает, по той же причине, что и переинициализация через HAL).

Именно такая ситуация возникла в моем случае. Проблема возникала случайным образом, но статистически она присутствовала. Если код инициализации Wire поместить ближе к началу программного кода, то вероятность возникновения ошибки уменьшается, если отодвинуть его куда-то подальше, то ошибка будет возникать чаще. И спастись от проблемы можно только аппаратным сбросом всего оборудования (передергиванием питания).

Так как же можно избавиться от проблемы «сумасшествия» ведомой микросхемы EEPROM? Очевидно, что нужно максимально быстро проинициализировать соответствующие терминалы ввода-вывода, дабы успеть в тот момент времени, пока EEPROM не начнет жить по своим собственным законам, повинуясь непонятным сигналам с микроконтроллера. Другими словами, подвинуть код инициализации Wire в самое начало программы. Но… Данный трюк не решает полностью описанное поведение EEPROM. Все еще остается вероятность отказа EEPROM (и опыты это подтверждают). Почему? Потому, что выполнение кода инициализации Wire занимает какое-то время, бесценные микросекунды, которых хватает на то, чтоб EEPROM удалились в мир грез и фантазий. Что в этом случае можно сделать?

pinMode(I2C_SCL, OUTPUT);
pinMode(I2C_SDA, OUTPUT);

Оказалось, что достаточно только проинициализировать порты микроконтроллера, ответственные за I 2 C как выходные цифровые выводы, как можно быстрее. В этом случае цифровое, а скорее аналоговое, шатание отменяется и невменяемость EEPROM тоже. В STM32Duino при инициализации пина как выходящего, он автоматически включается на низкий уровень. Если этого не происходит, например, поменялась идеология разработчиков фреймворка или вышла новая плата, на которой все не так, то дополнительно можно принудительно установить низкий уровень, что должно обеспечить нормальную работоспособность всей связки.

А что же до любителей HAL и особенно STM32Cube? Если работать только на HAL и не прибегать к Cube, как к средству конфигурирования, то проблема будет ровно такой же. Если не применить четкую инициализацию «ног» I 2 C как можно быстрее, то нормально с EEPROM не поработаешь. Впрочем, с Cube тоже не все так гладко как хотелось бы. Да, утилита помогает провести инициализацию микроконтроллера, которая сама по себе не отличается простотой. Но и тут могут быть нюансы. Во-первых, код инициализации I 2 C из Cube может быть выполнен в самую последнюю очередь, когда уже поздно, во-вторых, могут наступить и прочие конфликты, связанные с неверной инициализацией (Cube только выглядит просто, на самом деле без понимания туда лезть не стоит). Более подробно о потенциальных проблемах можно почитать в ссылках ниже.

Почему не определяются устройства на шине i2c

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

Доска объявлений

Объявления о покупке и продаже радиокомпонентов. Спрос и предложение на различные радиодетали и приборы.

Программы

Полезные программы для радиолюбителей и разработчиков радиоэлектроники.

Ссылки
Мы в соцсетях
Рекомендуем
Измерения

Диагностика последовательных шин I 2 C

I 2 С

Исходные данные

I 2 С или "I квадрат C" — шина связи IС. Эта шина была разработана в начале 1980-x компанией Philips и предназначалась для предоставления недорогого способа подключения контроллеров к периферийным микросхемам в телевизорах, a затем была принята в качестве мирового стандарта для обмена данных между устройствами во встроенных системах. Простая двухпроводная конструкция нашла применение в различных микросхемах, таких как микросхемы ввода/вывода, АПЦ, ЦАП, датчиках температуры, микроконтроллерах и микропроцессорах различных ведущих производителей, включая: Analog Devices, Atmel, lnfineon, Cyprus, Intel, Maxim, Philips, Silicon Laboratories, STMicroelectronics, Texas Instruments, Xicor и др.

Принцип работы

Физически шина I 2 С представляет собой двухпроводный интерфейс с двунаправленными линиями последовательной синхронизации (SCL) и линии передачи данных (SDA). Шина I 2 С поддерживает несколько ведомых и ведущих устройств, но одновременно может быть активно только одно ведущее устройство. Любое устройство I 2 С можно подключить к шине и осуществлять обмен данными c ведущим устройством. Все устройства распознаются по уникальному адресу и могут использоваться в качестве передатчика или приемника, в зависимости от их функций. Изначально в шине I 2 С использовались 7-разрядные адреса, сейчас — 10-разрядные. Поддерживается три скорости передачи бытов: 100 кбит/c (стандартный режим), 400 кбит/c (быстрый режим) и 3,4 Мбит/с (быстродействующий режим). Максимальное количество подключаемых устройств определяется максимальной емкостью 400 пФ или примерно 20-30 устройств. Стандарт I 2 С определяет следующий формат, представленный на рис. 4:
Start (Старт) — указывает, что управление шиной передано устройству и будет передано сообщение.
Address (Адрес) — 7- или 10-разрядный номер, соответствующий адресу устройства, с которого будут считываться данные или на которое будут записываться данные.
R/W Bit (Бит чтения/записи) — один бит, указывающий, что данные будут считываться c одного устройства или записываться в другое устройство.
Ack (Подтверждение) — один бит с ведомого устройства c подтверждением действия ведущего устройства. Как правило, подтверждение требуется для каждого адреса и байта данных, но не всегда.
Data (Данные) — целое число байт, считываемых или записываемых устройством.
Stop (Стоп) — указывает на завершение сообщения, ведущее устройство освобождает шину.

Структура сообщения I2C
Рис. 4. Структура сообщения I 2 C.

Меню настройки шины I2C
Рис. 5. Меню настройки шины I 2 C.

Пример шины I2C
Рис. 6. Пример шины I 2 C.

Работа с шиной I 2 С

Благодаря модулю последовательного запуска DPO4EMBD и приложению анализа, осциллографы серии DPO4000 представляют собой эффективный инструмент для разработчиков встроенных систем c шинами I 2 C. На передней панели имеются две кнопки шины (В1 и В2), позволяющие пользователям определить входы осциллографа в качестве шины. На рис. 5 показано меню настройки шины I 2 C. Определяя, какие каналы синхросигналов и данных включены, a также пороги определения логической 1 и О, можно использовать осциллограф для анализа протокола передачи. Благодаря этому осциллограф может выполнять запуск по любой заданной информации на уровне сообщения, a затем декодировать зарегистрированную осциллограмму и выводить понятные результаты. Времена запуска по фронту в надежде обнаружить нужное событие и последующее ручное декодирование сообщения ушли в прошлое. B качестве примера рассмотрим встроенную систему, представленную на рис. 6. Шина I 2 C подключена к нескольким устройствам, включая CPU (ЦПУ), память EEPROM, контроллер скорости вентилятора, DAC (ЦАП) и пару датчиков температуры. Инструмент вернули на доработку и анализ неисправностей, так как он постоянно грелся и самопроизвольно отключался. Первое, что необходимо проверить, — контроллер вентилятора и сам вентилятор, но они работают нормально. Далее нужно проверить датчик температуры. Контроллер скорости вентилятора периодически опрашивает два датчика температуры (расположенные в различных зонах инструмента) и регулирует скорость вентилятора для поддержания температуры внутри инструмента. Имеется подозрение, что один или оба датчика температуры работают c ошибкой. Чтобы просмотреть взаимодействие между датчиками и контроллером скорости, необходимо подключиться к линиям синхронизации и данных шины I 2 С и выполнить настройку шины на осциллографе DPO4000. Известно, что адреса датчиков в шине I 2 С — 18 и 19, поэтому настройка события запуска выполняется по записи в адрес 18 (контроллер скорости вентилятора запрашивает датчик o текущей температуре). На рис. 7 представлена зарегистрированная осциллограмма c запуском. B этом случае канал 1 (желтый) подключен к SCLK, канал 2 (голубой) — к SDA. Фиолетовая осциллограмма соответствует шине I 2 С, настроенной c помощью ввода на осциллографе нескольких параметров. B верхней части дисплея показана вся зарегистрированная осциллограмма. B этом случае было зафиксировано, что после длительного ожидания в шине возник всплеск активности в середине участка, этот участок был затем увеличен. B нижней большой части экрана представлено окно увеличения. Можно заметить, что осциллограф декодировал содержимое всех сообщений, передаваемых по шине. B осциллографах серии DPO4000 для выделения важных участков сообщения используется выделение цветом или маркеры. Рассматривая зарегистрированные осциллограммы, можно заметить, что осциллограф на самом деле выполнил запуск при записи по адресу 18 (см. левый нижний угол дисплея). Фактически контроллер скорости вентилятора пытается выполнить запись по адресу 18 два раза, но в обоих случаях не получает подтверждение приема. Затем выполнена проверка датчика температуры по адресу 19. Почему первый датчик температуры не отвечает на вызов контроллера вентилятора? Посмотрев на плату, можно обнаружить, что одна из адресных линий плохо припаяна. Датчик температуры не может обмениваться данными по шине, в результате устройство перегревается. Благодаря функциональным возможностям осциллографов серии DPO4000 запуска по событию и декодированию данных в шине I 2 C, поиск трудно определимой проблемы был выполнен всего за несколько минут.

Декодирование осциллограммы адресной линии и линии данных I2C
Рис. 7. Декодирование осциллограммы адресной линии и линии данных I 2 C.

Условие в шине Указано :
Запуск указан вертикальной зеленой полосой. Повторным запуском считается другой запуск без предыдущей остановки. Меню настройки шины I2C
Адреса отмечены желтыми прямоугольниками c буквами [W] (запись) или [R] (чтение). Значения адресов могут отображаться в двоичной или шестнадцатеричной форме. Меню настройки шины I2C
Данные представлены в голубых прямоугольниках. Значения данных могут быть представлены в двоичном или шестнадцатеричном формате. Меню настройки шины I2C
Отсутствие подтверждения указано восклицательным знаком в красной рамке. Меню настройки шины I2C
Остановки отмечены красными вертикальными полосами. Меню настройки шины I2C

Таблица 1. Условия в шине.

B примере на рис. 7 выполнялся запуск по записи, но функциональные возможности осциллографов серии DPO4000 включают и другие возможности по запуску при тестировании шины I 2 С.
Старт — запуск, если значение SDA низкое, a значение SCL высокое.
Повторный старт — запуск, если условию запуска не предшествует остановка. Как правило, ведущее устройство отправляет несколько сообщений и только затем освобождает шину.
Остановка — запуск, если значение SDA высокое и значение SCL высокое.
Отсутствие подтверждения — ведомые устройства часто конфигурируются для передачи подтверждения после приема каждого байта адреса или данных. Осциллограф может использовать запуск в случаях, если ведомые устройства не формируют бит подтверждения.
Адрес — запуск по указанному пользователем адресу или по любому предварительно запрограммированному адресу, включая общий вызов, начальный байт, быстродействующий режим, память EEPROM или CBUS. Адресация использует 7 или 10 бит и вводится в двоичном или шестнадцатеричном формате.
Данные — запуск по 12 байтам заданных пользователем значений данных, введенных в двоичном или шестнадцатеричном формате.
Адрес и данные — это позволяет вводить значения адресов и данных, a также чтение или запись для регистрации нужного события.

Такие триггеры позволяют выделить нужный трафик в шине, функция декодирования позволяет постоянно просматривать содержимое каждого передаваемого по шине сообщения.

Как узнать I2C адрес устройства?

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

Шина является адресной, так что каждое подключаемое устройство имеет свой адрес в диапазоне от 8 до 127. На одной шине не может быть два устройства с одинаковыми адресами.

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

Программа для сканирования I2C шины

Чтобы понять, какой всё-таки адрес у модуля, подключаемого к плате Ардуино, нужно просто «постучаться» по каждому из 119 возможных адресов. Если кто-то ответит, значит адрес рабочий!

Загружаем программу на Ардуино Уно, подключаем тестируемое устройство к I2C шине и открываем монитор последовательного порта. Если все подключено правильно, то появится примерно такой отчет:

Сканер I2C шины на Ардуино

Это значит, что мой дисплей имеет адрес 0x27 в шестнадцатеричной системе счисления. Теперь можно смело подключить библиотеку для работы с такими дисплеями и указать в ней данный адрес.

Как узнать I2C адрес устройства? : 19 комментариев

Очень интересно, но думаю не помешала бы принципиальная схемка подключения I2C устройства к Ардуино. Ну или ссылка на такую процедуру.

Почему не определяются устройства на шине i2c

Интерфейс I 2 C по-русски: особенности аппаратной и программной реализации шины, плюсы и минусы

Третьего дня абсолютно неожиданно для себя накропал данную заметку про интерфейс I2C. История ее создания была такова. При описании интерфейсной шины I2C, используемой в КМПУ, мне потребовалось рассказать, каким образом можно выбрать номинал подтягивающих резисторов для линий SDA и SCL. Поскольку шина I2C является довольно древней (придумана она в 80-х годах прошлого века), и про нее уже́ написана гора статей, я, как обычно, просто хотел дать ссылку на одну из них, дабы не плодить лишних сущностей. Однако, беглый поиск показал, что путных статей на русском языке про интересующую меня тему сходу особо-то и не найдешь (хотя, например, про софтовые дела́ материала написано предостаточно). Поэтому я по традиции решил это исправить и запилить свою собственную небольшую заметку про выбор номинала подтягивающих резисторов. При этом пришлось подробно рассказывать о том, как вообще функционирует интерфейс I2C на уровне железа, и почему в нем были выбраны именно такие схемотехнические решения, так что небольшая заметка довольно сильно распухла. И в итоге оказалось, что в нее нужно добавить не так уж много информации, чтобы получилась более-менее полноценная статья про I2C. С одной стороны, перспектива была довольно интересной. С другой – наверное, я бы так и не взялся за написание «полновесной» заметки, ибо на нее даже с учетом уже́ написанного ушло бы много времени, ибо я привык копать глубоко. К тому же, для нормального оформления статьи мне потребовалось бы рисовать картинки, а я не особо люблю это дело. Но тут мне совершенно случайно попался на глаза цикл статей Роберта Кейма, посвященный интерфейсу I 2 C, где всё было расписано примерно так, как это сделал бы я сам, но главное – там были рисунки! Оставалось перевести на нормальный инженерный русский то, что уже́ есть в наличии, добавить туда свои собственные мысли и оформить всё это в виде одной заметки, что я незамедлительно и сделал.

Естественно, я совершенно не претендую на оригинальность. Более того, если бы мне захотелось написать «просто статью про I2C», я бы даже не стал приступать к оной – какой смысл в 1001-й раз мусолить то, что до тебя обсудили уже́ 1000 раз? Однако, как я уже говорил, в моей заметке довольно подробно рассмотрен вопрос выбора подтягивающих резисторов для линий SDA и SCL, ну и в целом аппаратная часть интерфейса тоже не обойдена вниманием. А вот такой информации, тем более на русском языке, мне попадалось намного меньше (конечно, я не особо продвинутый «искатель», но всё же). Поэтому я считаю, что данные, изложенные в этой заметке, в ряде случаев могут быть крайне полезны разработчикам электронной аппаратуры. Ну а то, что в ней вкратце рассказано еще и про софтовую сторону I2C – это просто приятный бонус, позволяющий найти всю «первичную» информацию в одном месте, а не переключаться постоянно между десятью вкладками браузера.

Для тех, кто с английским вполне дружит, вот ссылки на оригинальные статьи Роберта Кейма, использованные при написании данной заметки:

1) – отмечу, что расчет номиналов подтяжек здесь не совсем корректен даже с учетом того, что это грубая оценка.

Правда, здесь нужно напомнить, что моя заметка не является тупым переводом данного цикла – минимум две трети этого документа были написаны лично мной, поэтому в оригинальных статьях некоторых вещей просто нет (ну это так, к слову). Но в целом, конечно, рассматриваемый документ имеет в своей основе именно цикл статей Роберта Кейма, поэтому ознакомиться с оригиналами будет нелишним.

И последнее. В отличие от многих простейших интерфейсов, шина I2C имеет нормальный стандарт (спецификацию) . Это важно, поскольку стандартизация не позволяет двояко толковать многие моменты в работе интерфейса. Вот здесь находится самый свежий вариант спецификации шины I 2 C. На всякий случай я его сохранил и у себя (взять версию от 4 апреля 2014 года можно тут). И хочу заострить ваше внимание на том, что при разрешении каких-либо вопросов в первую очередь надо обращаться именно к официальному стандарту, а не к заметкам в Интернете, как бы хорошо они ни были написаны.

Одной из общих черт всех электронных систем является необходимость обмена информацией между двумя, тремя или десятью их отдельными компонентами. Для этих целей инженерами был разработан целый ряд стандартных протоколов (или интерфейсов), помогающих различным микросхемам успешно обмениваться данными (UART, USART, SPI, I 2 C, CAN и т.д.). Успех этот обусловлен тем, что структура и последовательность сигналов на линиях связи чипов, работающих по одному протоколу, жестко устанавливается соответствующими стандартами и/или соглашениями. В подавляющем большинстве случаев каждый стандарт для передачи информации предусматривает совместное использование сразу нескольких линий связи, объединяемых в интерфейсные шины или шины данных. Сам же конкретный способ передачи пачек данных называют интерфейсом, т.е. совокупностью правил взаимодействия между элементами системы.

Отметим, что у каждого из вышеперечисленных интерфейсов есть свои плюсы и минусы. Поэтому при разработке нового устройства нам важно знать хотя бы немного о каждом из них, чтобы принять обоснованное решение в пользу того или иного протокола. Данная статья посвящена интерфейсу I2C, который обычно используется для связи между отдельными микросхемами, расположенными на одной печатной плате или между модулями, входящими в состав одного устройства. Основной особенностью данного интерфейса можно назвать способность подключать к одной шине большое количество устройств (до 112 штук) при использовании всего двух линий связи. Однако, при этом I2C является сравнительно медленным протоколом, позволяющим обмениваться данными на скоростях, зачастую не превышающих 400кГц. Эти и другие особенности интерфейса I2C будут рассмотрены ниже.

Причины создания интерфейса I 2 C

Первым делом следует отметить, что интерфейс I2C является намного более сложным, чем другие простейшие шины (например, UART или SPI). Чтобы понять, для чего понадобились такие серьезные усложнения, представим, что нам нужно создать надежную, и в то же время универсальную систему связи между несколькими независимыми компонентами. Ситуация будет достаточно простой, если у нас есть одна микросхема, которая всегда является ведущей, и одна микросхема, которая всегда является ведомой. Но что, если у нас несколько ведомых? Что, если они не всегда знают, кто мастер? Что делать, если ведущих несколько? Что произойдет, если мастер запросит данные у ведомого устройства, которое по какой-то причине перестало работать? Что, если ведомый перестанет работать в середине передачи? Что, если мастер заявляет, что шина выполняет передачу, а затем отключается перед тем, как отпустить шину?

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

Особенности интерфейса I 2 C

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

• шина I2C является синхронной (тактируемой);

• независимо от количества устройств на шине, для передачи информации всегда используется только две линии: линия данных SDA (Data Line) и линия тактовых импульсов SCL (Clock Line). Такты на линии SCL всегда генерирует мастер:

• обе линии должны быть подтянуты к «плюсу» питания через резисторы подходящего номинала;

• каждое устройство подключается к линиям SDA и SCL через выходные драйверы с открытым стоком (или открытым коллектором), см. ниже;

• каждое ведомое устройство идентифицируется с помощью 7-битного адреса, всего на одной шине может быть до 112 устройств (16 адресов являются зарезервированными). Мастер должен знать эти адреса для связи с конкретным ведомым устройством;

• начало любого обмена данными инициируется и завершается мастером. Мастер может как записывать данные в одно или несколько ведомых устройств, так и запрашивать у них данные. Обмен информацией между двумя ведомыми невозможен;

• понятия «Мастер» и «Ведомый» по своей природе непостоянны: в теории любое устройство на шине I2C может функционировать как ведущее или ведомое, если ему это позволяет сделать аппаратная часть и/или прошивка. Иными словами, рассматриваемая шина поддерживает режим мультимастера. Однако на практике системы на базе I2C чаще всего строятся по архитектуре, в которой есть только один мастер, отправляющий команды нескольким ведомым устройствам и собирающий с них данные;

• данные загружаются (Updated) на линию SDA по заднему фронту тактовых импульсов на линии SCL и считываются (Sampled) по переднему фронту SCL:

• данные передаются побайтово, за каждым байтом следует бит подтверждения, называемый битом ACK/NACK (подтверждено или не подтверждено).

Ну а после этого можно и объяснить, откуда берется большинство данных особенностей.

Аппаратная часть интерфейса I 2 C

Достоинства интерфейса I2C (возможность связи любого количества устройств всего по двум линиям, наличие нескольких ведущих и т.д.) связаны в основном с тем, что его линии SDA и SCL являются двунаправленными. Т.е. здесь вы не просто подключаете выход буфера соответствующего интерфейса ко входу (входам) других чипов, висящих на данной шине (как это было бы в случае UART или SPI) – интерфейс I2C требует, чтобы выводы SDA и SCL применяемых микросхем могли быть как входами, так и выходами. Далее мы рассмотрим несколько нюансов аппаратной реализации данного интерфейса, которые делают его довольно привлекательным (за счет надежности и универсальности) при построении канала связи между несколькими независимыми микросхемами.

Схема «Открытый сток»

С точки зрения железа основной отличительной особенностью микросхем, поддерживающих работу с интерфейсом I2C, является то, что к линиям SDA и SCL они должны подключаться через выходные драйверы с открытым стоком (или открытым коллектором). Чтобы понять смысл данной фразы, давайте сначала рассмотрим типичный выходной каскад современных чипов на полевых транзисторах:

Если на входе VIN присутствует высокий логический уровень, N-канальный транзистор (нижний по схеме) включен, а P-канальный транзистор (верхний по схеме) выключен. Таким образом, выход VOUT будет подключен к земле (сопротивление открытого канала полевиков на практике довольно мало, и в нашем случае его можно не учитывать). Если же на вход VIN подать низкий логический уровень, ситуация меняется на обратную, и выход VOUT будет подключен к «плюсу» питания VDD. Такая схема называется двухтактным выходным каскадом. При этом крайне важно понимать, что в общем случае вы не можете напрямую соединить два двухтактных выхода. Это связано с тем, что при наличии у одного из них на входе единицы (HIGH), а у другого – нуля (LOW), ток потечет от «плюса» питания VDD к земле, будучи ограниченным исключительно сопротивлением открытого канала полевиков:

Вследствие того, что данное сопротивление имеет крайне низкое значение, выходной ток микросхем будет весьма значительным – при питании VDD=+5,0В он может достигать единиц ампер. Ну и в итоге от этого тока выход чипа, естественно, сдохнет. Так вот, для того, чтобы при соединении двух и более выходов микросхем такой херни не происходило, часто используют схему «открытый сток» (ну, или «открытый коллектор», в зависимости от типа транзисторов, используемых в ней):

P-канальный транзистор здесь заменен резистором, причем важным является то, что этот резистор может быть внешним по отношению к микросхеме (т.е. может быть вынесен за ее пределы). Теперь если на вход VIN подать высокий логический уровень, N-канальный транзистор откроется и обеспечит низкоомное соединение выхода VOUT с землей. Если же на вход подать низкий логический уровень, полевик будет закрыт и представит из себя разомкнутую цепь. При этом выход VOUT будет подключен к «плюсу» питания VDD через внешний резистор. Такая логика работы выхода микросхемы приводит к двум важным особенностям. Во-первых, когда на выходе VOUT присутствует низкий логический уровень, схема потребляет дополнительный ток – он течет через внешний резистор, далее через открытый канал полевого транзистора и далее на землю. Это плохо, поскольку у двухтактного выходного каскада дополнительное энергопотребление практически отсутствует, ибо P-канальный полевик при этом будет закрыт. Но при этом (во-вторых) даже если на входе одного из полевых транзисторов будет присутствовать высокий логический уровень (HIGH), а на входе второго – низкий (LOW), то ничего страшного не произойдет. Как нетрудно видеть, при таком раскладе точка соединения выходов притянется к массе за счет первого полевика, а второй просто перестанет оказывать на работу схемы какое-либо влияние, т.к. будет представлять из себя разомкнутую цепь. При этом ток через выход микросхемы в любом случае будет ограничен за счет внешнего резистора (обычно имеющего номинал не ниже 1кОм):

Таким образом, применение схемы «открытый сток» или «открытый коллектор» позволяет безопасно соединять два (и более) выхода разных микросхем даже тогда, когда на одном из них присутствует единица, а на другом – нуль. Естественно, это является существенным плюсом данного схемотехнического решения, в принципе делающим возможным реализацию интерфейса I2C. Кроме безопасного соединения выходов нескольких чипов, применение «открытого стока» дает следующие бонусы:

• по умолчанию (т.е. когда выходные полевые транзисторы закрыты) сигналы на шине всегда имеют высокий логический уровень (а не какой попало). Поэтому если ведомое устройство вдруг заглючило и не может управлять сигналом на линии данных SDA, эта линия никогда не перейдет в неопределенное состояние – с нее будет считана логическая единица. Аналогично, если ведущий потеряет питание в середине передачи, сигналы SCL и SDA вернутся к высокому уровню. При этом если на линиях SCL и SDA в течение определенного промежутка времени присутствовала логическая единица, другие устройства на шине могут сделать вывод, что она доступна для новой передачи данных;

• любое устройство на шине может безопасно установить нуль на любой из линий SDA и SCL, даже если другое устройство в этот момент пытается установить единицу. Это основа функции «растяжения» тактовой частоты, часто применяемой «медленными» микросхемами I2C. Данная функция означает, что мастер может генерировать тактовые импульсы SCL на любой частоте, вплоть до максимально возможной – при необходимости ведомое устройство может удерживать линию SCL на низком уровне и тем самым уменьшать тактовую частоту;

• схема «открытый сток» автоматически приводит все сигналы на шине к одному уровню – к напряжению питания VDD. При этом данное напряжение может быть как больше, так и меньше напряжений питания отдельных микросхем на шине. Это происходит потому, что в реальности каждый чип может принудительно установить на линиях SDA и SCL лишь нуль – единица получается сама собой при выключении выходного транзистора, и уровень ее автоматически будет равен как раз значению VDD. Единственное условие безопасной работы здесь – полевики в выходном каскаде каждой микросхемы должны позволять работу с напряжением VDD (т.е. оно не должно превышать максимально допустимое значение «исток-сток» выходного транзистора). Таким образом, на шине I2C могут вполне нормально уживаться устройства с различным напряжением питания (например, трехвольтовый чип может взаимодействовать с пятивольтовым, если, конечно, его не убьют эти пять вольт).

Отметим, кстати, что точка соединения нескольких «открытых стоков» часто называется также «монтажным ИЛИ», поскольку для перевода ее в низкий уровень достаточно того, чтобы хотя бы на одном из объединяемых выходов был нуль.

Влияние емкости линий шины на скорость передачи данных

Несмотря на все свои достоинства, выходной драйвер с открытым стоком имеет и ряд недостатков. Одним из самых главных является существенное затягивание фронта выходного импульса при переводе линий SDA и SCL из низкого состояния в высокое.

Данное затягивание обусловлено наличием емкости линий шины. Легко заметить, что выводы SDA и SCL любой микросхемы имеют определенную входную емкость Ci (т.е. емкость между выводом и землей). Пусть эта емкость и невелика для каждого отдельного устройства (типовое значение Ci у большинства I2C-чипов составляет 10…20пФ), однако, по мере роста ведомых на шине суммарное значение емкости линий SDA и SCL будет увеличиваться. Сюда еще добавится и емкость между дорожками на печатной плате CPCB, зависящая, в том числе, от материала диэлектрика, из которого плата сделана:

И в итоге будем иметь, что результирующая емкость линий интерфейса I2C (CSDA и CSCL) будет состоять из суммы входных емкостей всех микросхем, висящих на шине (Ci+Ci+Ci+…), емкости соответствующей дорожки (CPCB), ну и еще емкости всякой паразитной херни, которую обычно можно не учитывать. Так вот, из логики работы схемы «открытый сток» следует, что при переходе линии SDA или SCL из единицы в нуль (HIGH to LOW, левая картинка ниже) разряд ее суммарной емкости CSDA или CSCL будет идти только через сопротивление открытого канала выходного полевого транзистора. А вот при переходе линии из нуля в единицу (LOW to HIGH, правая картинка ниже) емкости CSDA и CSCL смогут заряжаться только через резистор, подтягивающий шину к «плюсу» питания:

Длительность полного заряда или разряда емкости C через резистор R (а именно эти временны́е промежутки и определяют длительность фронтов на выходе микросхем) можно примерно оценить как t=5RC. При работе с реальными чипами это значение, конечно, будет меньше из-за наличия пороговых значений нуля и единицы на входе, но понять суть можно и при помощи этой простой формулы. Так вот, длительность полного разряда емкости линий SDA и SCL будет равна

где RDS_ON – сопротивление открытого канала выходного полевика.

Время же полного их заряда составит

где RP – сопротивление внешнего резистора, подтягивающего линию к «плюсу» питания. И из-за того, что сопротивление RDS_ON обычно отличается от номинала внешней подтяжки минимум на три порядка (в лучшем случае – единицы Ом против единиц килоом), переход линий шины I2C от низкого уровня к высокому будет значительно медленнее, чем переход от высокого уровня к низкому. Это приводит к тому, что I2C-сигналы традиционно имеют не прямоугольную, а псевдо-пилообразную форму:

ну а их заваленные фронты, естественно, повлекут за собой ограничение максимальной скорости, на которой может работать шина. Отметим, что допустимые временны́е характеристики импульсов на линиях SDA и SCL, а также параметры выводов I2C-микросхем жестко регламентируются спецификацией для того, чтобы чипы разных производителей могли нормально общаться между собой. Основные данные из этой спецификации для удобства приведены ниже.

Электрическая спецификация шины I 2 C

Согласно стандарту I2C, на данный момент (декабрь 2020г.) существует пять режимов работы шины. Различаются они по максимально возможной скорости передачи данных, т.е. по максимальной частоте тактовых импульсов SCL:

Режим работы Макс. скорость
Standard-Mode (SM) fSCL_MAX = 100кГц
Fast-Mode (FM) fSCL_MAX = 400кГц
Fast-Mode Plus (FM+) fSCL_MAX = 1000кГц
High-Speed-Mode (HsM) fSCL_MAX = 3400кГц
Ultra-Fast-Mode (UFM) fSCL_MAX = 5000кГц

При этом исторически сложилось так, что наибольшее распространение получили лишь первые три из них. Почему так вышло, я не знаю, однако в дальнейшем будем рассматривать именно режимы «SM», «FM» и «FM+». Требуемые параметры выводов микросхем, поддерживающих режимы Standard-Mode, Fast-Mode и Fast-Mode Plus, приведены в Таблице 9 спецификации I2C (стр. 47):

а временны́е характеристики импульсов SDA и SCL – в Таблице 10 (стр. 48-49)

и на Рисунке 38 (стр. 50):

Отметим, что несмотря на наличие стандарта I2C, некоторые производители микросхем кладут на него хер. Например, стандартом оговорено, что входная емкость выводов SDA и SCL (Ci) не должна превышать 10пФ, а для всенародно любимого термометра LM75A в таблице указано 20пФ, и это, заметьте, не максимальное, а типовое значение. Еще бесит, когда емкость вывода не указывают вообще (типовой пример – АЦП ADS1110). Ну а уж не указывать максимально допустимый ток выходов SDA и SCL в нуле – это вообще традиция (видимо, в этом случае нужно брать IOL=3мА из спецификации). Правда, радует, что эти косяки касаются только параметров цифровых выводов – с временны́ми характеристиками всегда всё в ажуре. Однако, при расчете емкости линий шины I2C и выборе номиналов подтягивающих резисторов (см. ниже) вышеперечисленные ньюансы нужно учитывать.

Расчет номинала подтягивающих резисторов

Ранее было показано, что длительность фронтов сигналов на линии I2C напрямую зависит от емкости этой линии и от номинала резистора, который подтягивает ее к «плюсу» питания VDD. Например, на этих осциллограммах желтой линией показан переход линии SCL шины I2C из нуля в единицу и из единицы в ноль:

При этом использовался подтягивающий резистор довольно небольшого номинала (1кОм), а емкость линии была уменьшена до предела – на шине присутствовали только две микросхемы, соединенные между собой на печатной плате короткими дорожками. Отметим, что абсолютные значения фронтов сигнала (меньше 70нс) более чем приемлемы даже для устройств, работающих в режиме High-speed mode (fSCL до 3,4Мбит/с), однако с увеличением количества дывайсов на линии картина будет становиться всё менее и менее радостной. При этом формулы говорят (см. выше), что для улучшения переднего фронта сигналов шины I2C нам нужно уменьшать либо емкости линий SDA и SCL, либо сопротивление подтягивающих резисторов. Однако, как-либо уменьшить емкость линий чаще всего просто невозможно – они определяются в первую очередь количеством устройств на шине и характером взаимосвязей между этими устройствами. Поэтому зачастую единственным рычагом, позволяющим улучшить форму импульсов на линиях SDA и SCL, является сопротивление резисторов-подтяжек.

Очевидно, что чем меньше будет сопротивление подтягивающих резисторов, тем более крутые фронты импульсов мы получим. Однако, при этом будет расти энергопотребление устройства в целом, да и про предельно допустимый выходной ток микросхем забывать тоже не надо. Поэтому при выборе номинала подтягивающих резисторов каждый раз приходится искать компромисс между максимальной скоростью работы шины I2C и потребляемой ею мощностью. Понятно, что с точки зрения рабочей частоты сопротивление подтяжек должно быть как можно ниже, т.к. при этом фронты импульсов будут более крутыми. Но чем меньше взят номинал подтягивающих резисторов, тем больше будет ток, потребляемый от шины питания VDD при SCL=0 и SDA=0, а этот ток нередко ограничен требованиями к разрабатываемому устройству (например, у батарейных поделок). Поэтому минимально возможное сопротивление резисторов-подтяжек определяется максимально допустимым током IMAX, который может потребляться шиной I2C:

где VDD_MAX – максимально возможное напряжение питания шины (например, при питании +5,0В±5% значение VDD_MAX составит 105% от +5,0В, т.е. +5,25В). При этом нужно помнить, что ток IMAX, потребляемый линией I2C от источника, ни при каких обстоятельствах не должен превышать максимально допустимый ток соответствующего вывода микросхемы (ну а лучше предусмотреть хоть какой-то запас).

Отметим, что номиналу RP_MIN будет соответствовать максимально возможная частота работы шины. Однако, как сказано выше, зачастую нам гораздо важнее энергопотребление устройства, а особой скорости от шины I2C не требуется. Например, в приложениях, где по данной шине МК опрашивает исключительно датчик температуры LM75A, работать на частоте 400кГц (и даже 100кГц) обычно абсолютно бессмысленно, ибо температура не может столь быстро изменяться. Поэтому в данных приложениях стараются увеличить сопротивление подтяжек.

Для расчета максимально возможного номинала подтягивающих резисторов RP_MAX нам потребуется узнать емкость линий SDA и SCL. Понятно, что в идеале здесь надо было бы собрать всю систему вживую и тупо измерить данную емкость – так мы получим наиболее точное ее значение. Однако вполне естественно, что метод прямого измерения емкости разработчику обычно не подходит, ибо собирать всю систему ради одного номинала резистора – больно круто. Поэтому чаще всего на практике применяется приблизительная и довольно грубая оценка значений CSDA и CSCL. В этом случае сначала для каждой микросхемы, висящей на шине, из документации берется входная емкость выводов SDA и SCL (Ci), а затем они все суммируются. Обратите внимание на то, что в соответствии со стандартом I2C максимальное значение Ci должно составлять 10пФ. Однако, не каждый производитель четко придерживается спецификации, поэтому при просмотре даташытов надо быть крайне внимательным.

После того, как входные емкости всех микросхем просуммированы, нам останется учесть емкость проводников, которыми связаны между собой устройства на шине. В том случае, когда шина физически реализована в виде печатных проводников на плате, к сумме входных емкостей всех микросхем, рассчитанной ранее, надо добавить по 1,18пФ на каждый сантиметр дорожки (см. техасовский апнот, стр. 3). Если же для связи используются какие-либо «фирменные» провода, то их погонная емкость может быть напрямую взята из документации (например, в случае коаксиального кабеля RG-58 она составит около 100пФ на каждый метр). В итоге мы получим примерное значение CSDA или CSCL, которое уже́ можно использовать в дальнейших расчетах. Более подробно о составляющих суммарной емкости линий SDA и SCL, а также о том, как их вычислить, можно узнать здесь. Ну и не нужно забывать о том, что спецификация шины I2C прямо оговаривает максимально допустимую емкость этих линий: для режимов «Standard» и «Fast» предельное значение составляет Cb=400пФ, а для режима «Fast Plus» – Cb=550пФ (см. Таблицу 10 на стр. 48).

После того, как мы узнали значения емкостей линий SDA и SCL, можно, наконец-то, вычислить максимально допустимое сопротивление подтягивающих резисторов. Расчет их ведется исходя из того, что время нарастания сигналов на шине I2C (tr) не должно превышать значений, указанных в стандарте. Согласно Таблице 10 (см. стр. 48), время нарастания в режиме «Standard» должно быть не больше 1мкс, в режиме «Fast» – не больше 300нс, а в режиме «Fast Plus» – не больше 120нс. При этом под временем нарастания в спецификации понимается время, за которое сигнал успевает нарасти с 30% до 70% своего максимального значения (см. Рисунок 38 на стр. 50). И в соответствии с известной формулой для расчета времени заряда емкости до определенного уровня:

получим, что до 30% напряжение на емкости линий SDA и SCL нарастет за интервал

а до 70% – за интервал

Поэтому можно считать, что время нарастания сигнала с 30% до 70% составит

Отсюда мы можем найти максимально возможное сопротивление подтягивающего резистора для линии I2C:

(Кстати, эти формулы я сначала вывел сам, а потом обнаружил, что они уже есть в стандарте I2C на стр. 55. С одной стороны, конечно, жаль потраченного времени, но с другой – я лично проверил, что в официальной спецификации всё верно, хе-хе. При этом крайне важным является то, что формула [2] может применяться лишь с определенными оговорками . Более подробно это рассмотрено ниже).

Из последней формулы следует, что максимально возможное значение сопротивления подтяжек определяется емкостью соответствующей линии шины I2C и допустимым временем нарастания сигнала. Поэтому для всех трех режимов работы интерфейса («Standard-Mode», «Fast-Mode» и «Fast-Mode Plus») максимальное значение RP_MAX будет отличаться – чем тормозней режим, тем больший номинал резистора можно использовать. В связи с этим, в приложениях, где крайне важна минимизация энергопотребления, наиболее выгодным будет использование режима «Standard». Однако, не нужно забывать, что данный режим сильно ограничен по скорости, поэтому, возможно, здесь придется с особой тщательностью подойти к разработке функциональной схемы устройства и выбору его элементной базы.

Отмечу, что в общем случае максимально и минимально возможное сопротивление подтягивающих резисторов шины I2C можно определить не только по формулам, но и по данным графикам:

(коричневая линия на верхнем рисунке – это прямая, а не кривая, как может показаться). Данные графики построены в соответствии с формулами для RP_MIN и RP_MAX, приведенными выше. Верхний график показывает зависимость минимально допустимого сопротивления подтягивающего резистора (RP_MIN) от напряжения питания шины I2C (VDD). Отмечу, что в стандарте на стр. 55 тоже есть подобный рисунок (более того, сама идея нахождения сопротивлений по графику взята мною именно оттуда), только мне не совсем понятны там два момента. Во-первых, почему-то при расчетах везде используется формула

где IMAX=IOL_WORST=3мА или 20мА (смотря в каком режиме работает шина, см. Таблицу 9 на стр. 47), а +0,4В – это максимально допустимое падение напряжения на выходах SDA и SCL, находящихся в нуле. При этом если на выходе упадет меньше +0,4В (а по стандарту там вообще может быть чистый нуль), то для того, чтобы не превысить заданный ток IMAX, нам понадобится резистор с номиналом больше расчетного. То есть, формула, учитывающая падение напряжения +0,4В на низком выходе SDA или SCL дает заниженное значение RP_MIN, поэтому лично я предпочитаю при расчетах использовать формулу [1] (см. выше). Она позволяет получить адекватную величину сопротивления подтягивающего резистора, поскольку в данной формуле сделано предельное допущение, что всё напряжение питания шины падает исключительно на подтяжке (а с точки зрения номинала RP_MIN хуже быть просто не может). Второй непонятный для меня момент – почему на графике в спецификации напряжение питания шины Vcc изменяется до +15,0В? Ведь в Таблице 9 на стр. 47 ясно сказано, что на входе SDA и SCL в любом случае не должно присутствовать напряжение выше +5,5В (см. примечание 2 после таблицы). А поскольку линии шины I2C являются двунаправленными, то и на выход, вроде, больше +5,5В давать нельзя. При этом предельное значение «+5,5В» вполне согласуется со всеми микросхемами I2C, встречавшимися мне до сих пор, а вот «+15,0В» – как-то не очень (правда, я не знаю – может и есть чипы, толерантные к такому напряжению). В общем, по моим понятиям, ось «Х» на верхнем графике должна изменяться от +1,0В до +6,0В, что я и отобразил. Ну а для бо́льших или меньших питаний данные линии можно будет легко продлить, благо это обычные прямые.

Нижний график показывает зависимость максимально возможного сопротивления подтяжки (RP_MAX) от суммарной емкости линии I2C (Cb). Этот график полностью совпадает с картинкой из спецификации (стр. 55) с той лишь разницей, что мне кажется более удобным логарифмический масштаб. Обратите внимание на то, что при работе в режиме «Standard» подтяжка номиналом в несколько десятков килоом – вовсе не фантастика. Понятно, что за это приходится платить снижением скорости обмена информацией, но тут уж ничего не поделаешь, ибо с физикой спорить – себе дороже. При этом если мы готовы и дальше жертвовать максимальной частотой работы шины, то сопротивление подтягивающих резисторов можно еще больше увеличить, поэтому использование шины I2C является крайне заманчивым для приложений, где требуется минимизация энергопотребления. В связи с этим, вопрос увеличения номиналов подтяжек сто́ит рассмотреть более подробно.

Крайне важно понимать, что формулы [1] и [2], а также оба графика, приведенные выше, позволяют вычислить диапазон номиналов подтягивающих резисторов, в котором на шину I2C можно вешать вообще любые микросхемы, удовлетворяющие данному стандарту. То есть при таких номиналах мы можем взять любой I2C-чип, повесить его на шину, и при этом он с гарантией а) не сгорит и б) сможет работать на максимально возможной частоте (100кГц, 400кГц и 1МГц для режимов Standard-Mode, Fast-Mode и Fast-Mode Plus соответственно). Однако, реальная жизнь не ограничивается одним только стандартом. Например, верхний график на последнем рисунке говорит, какое сопротивление должно быть у подтягивающих резисторов, чтобы ток выхода микросхемы не превысил значение, указанное в спецификации (3мА или 20мА). И вроде бы это логично, т.к. в общем случае мы должны ориентироваться именно на стандарт, но с другой стороны – есть куча микросхем, которые позволяют работать с бо́льшими выходными токами (те же LM75A или, например, камни AVR с включенным TWI). И если на шине присутствуют только такие микросхемы, то сопротивление подтяжки можно уменьшить, улучшив при этом фронты сигналов SDA и SCL. Я, конечно, понимаю, что рассматриваю сейчас ситуацию в сферическом вакууме, ибо абсолютно непонятно, зачем нужно улучшать форму импульсов, если она и так удовлетворяет всем требованиям. Однако всё же считаю нужным подчеркнуть:

значение IMAX в формуле [1] вовсе не обязательно должно быть «стандартным» (3мА или 20мА). Если микросхемы, подключенные к шине I2C, допускают работу с бо́льшими токами, то расчет минимально возможного сопротивления подтяжек можно вести, используя именно эти частные значения. Иными словами, в качестве величины IMAX в формуле [1] можно использовать предельно допустимый ток самого «слабого» чипа, висящего на шине.

А вот ситуация, при которой сопротивление подтягивающего резистора должно быть больше рассчитываемого по формуле [2] – это уже́ не сферические кони, а вполне реальная проблема. Чаще всего она встречается при разработке устройств с батарейным питанием, ибо в них иногда каждые 50мкА на счету. Поэтому в таких дывайсах потребление шины I2C стараются свести к минимуму, а для этого, напомню, нужно увеличивать сопротивление подтягивающих резисторов. Сопутствующее же снижение частоты работы шины обычно пытаются нивелировать за счет более тщательного продумывания алгоритма работы устройства (хотя нужно отметить, что зачастую это снижение не особо-то сильно и напрягает). При этом максимальную скорость обмена данными (fMAX), которая получится при выбранном номинале подтяжки, можно грубо оценить, используя следующие соображения.

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

При этом, как было показано выше, за счет особенностей работы схемы «открытый сток» спадающий фронт у этого меандра будет достаточно крутым, а вот передний – затянутым:

И максимально возможная скорость шины I2C будет определяться именно степенью затянутости переднего фронта импульсов SCL, поскольку для нормальной работы интерфейса их амплитуда должна быть не ниже 0,7VDD (см. Таблицу 9 на стр. 47 спецификации). Иными словами, если передний фронт тактовых импульсов затянут настолько, что напряжение на линии SCL не успевает нарасти до 0,7VDD, то стабильная работа шины I2C не гарантируется. Более того – даже если уровень 0,7VDD и был достигнут, то перед тем, как начнется задний фронт меандра, обязательно должно пройти время tHIGH (см. Рисунок 38 на стр. 50 спецификации). В результате мы получаем, что длительность импульса SCL не может быть меньше величины

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

(данное ограничение гарантирует, что длительность тактового импульса не превысит значения (1,20∙RP_MAXCb + tHIGH) при условии, что сигнал SCL является меандром).

Кстати, не нужно забывать, что согласно спецификации тактовый импульс должен оставаться в нуле как минимум в течение времени tLOW. При этом легко убедиться, что значение tLOW для любого режима работы шины и любых реальных RP_MAX и Cb будет меньше значения 1,20∙RP_MAXCb + tHIGH, поэтому формула [3] является корректной. Отмечу также, что 0,7VDD – это именно гарантированный уровень логической единицы, и в конкретном устройстве для конкретных чипов он запросто может быть ниже. Так что весьма велика вероятность, что в реальности частота работы шины I2C может быть несколько увеличена по сравнению с расчетным значением fMAX. Однако, это будет уже́ «тонкая настройка» под конкретный дывайс, в большинстве же случаев вполне хватает и формулы [3].

Ну и последнее. При взгляде на формулу [3] может показаться, что если нас устраивает низкая скорость работы шины I2C, то потребление тока по ней мы можем свести практически к нулю. В самом деле – пусть у нас есть крайне неспешное устройство, питающееся от +5,0В и опрашивающее некий датчик раз в 10 секунд (т.е. частота опроса составляет 0,1Гц). В этом случае, казалось бы, никто не мешает использовать в качестве подтяжек резисторы даже на 10МОм, ибо при этом максимальная скорость передачи данных в худшем случае составит fMAX=0,5/[1,2*10МОм*400пФ+4мкс]=104Гц (рассматриваем режим «Standard»), чего заведомо хватит для опроса нашего укуренного датчика. Но зато ток, отжираемый каждой линией шины I2C от источника питания, никогда не превысит 5В/10МОм=0,5мкА, а его среднее значение будет еще меньше (минимум в два раза), что для батарейных устройств – просто праздник. Так вот, реальность здесь нас жестко обламывает. Дело в том, что каждая микросхема (в том числе и I2C-чипы) имеет ток утечки как по входам, так и по выходам. И этот ток ILEAK, протекая по подтягивающему резистору, создает не нем падение напряжения, равное

Напомню, что по стандарту I2C гарантированным уровнем единицы на входе является 0,7VDD. Это значит, что любой сигнал ниже данного уровня микросхема может принять за нуль. Поэтому нам нужно, чтобы падение напряжения, которое создает на подтягивающем резисторе ток утечки, не превысило VLEAK=VDD–0,7VDD=0,3VDD. В противном случае легко получить ситуацию, при которой I2C-линия вроде бы находится в исходном состоянии, а некоторые чипы, висящие на шине, считывают ее как нуль. Происходит это из-за того, что сигнал данной линии опустился ниже VDD–0,3VDD=0,7VDD, и эти микросхемы приняли его за низкое состояние. Поэтому когда в качестве подтяжки выбирается высокоомный резистор, крайне важно уделять пристальное внимание падению напряжения, создаваемому на нем токами утечки чипов. И исходя из того, что данное падение не должно превышать 0,3VDD, мы можем вывести формулу для «истинно» максимально возможного сопротивления подтяжки:

где IΣ_LEAK – это суммарный ток утечки всех микросхем, подключенных к данной линии шины I2C. Отметим, что в соответствии со спецификацией I2C ток утечки чипа по входу/выходу не должен превышать 10мкА, поэтому формулу [4] можно переписать так:

где N – количество микросхем, висящих на шине I2C. В данной формуле напряжение питания VDD указывается в Вольтах, а сопротивление подтяжки получается в килоомах, что, на мой взгляд, гораздо удобнее Омов и микроамперов. При этом, для нашего устройства с медленным датчиком, которое было упомянуто чуть выше, формулы [4] и [4а] дадут

RP_MAX_HARD = 0,3VDD / (0,01∙N) = 0,3*5В / (0,01*2) = 75кОм,

то есть, если на шине I2C, питающейся от VDD=+5,0В, висят две микросхемы (N=2), удовлетворяющие соответствующей спецификации (ILEAK=10мкА), то сопротивление подтяжки в общем случае не может быть больше 75кОм. Таким образом, делать в этом случае частоту тактовых импульсов ниже fMAX=0,5/[1,2*75кОм*400пФ+4мкс]=1,38кГц особого смысла нет – всё равно подтяжку увеличить не получится.

Обращаю ваше внимание на то, что увеличение сопротивления подтягивающего резистора больше значения RP_MAX_HARD чревато появлением волшебных глюков при обмене информацией. Связано это с тем, что данное ограничение продиктовано уже́ не максимальной скоростью работы шины (которая зачастую может быть существенно ниже значения, указанного в спецификации), а правильной работой микросхем, висящих на той или иной ее линии. С другой стороны, нельзя не отметить, что в документации на чипы обычно указан только максимальный ток утечки, а реальное его значение запросто может быть в два раза ниже табличного. К тому же, повторюсь, у конкретных чипов, установленных в конкретное устройство, уровень единицы на входе вполне может оказаться не 0,7VDD, а ниже. А раз так, то и сопротивление подтягивающего резистора можно взять больше того, которое получается по формулам [4] и [4а]. Но это будет касаться именно конкретного дывайса, к тому же потребует дополнительных исследований. В общем же случае при разработке шины I2C категорически рекомендую пользоваться значением RP_MAX_HARD, рассчитываемому по формуле [4] или [4а].

Примеры расчета подтягивающих резисторов

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

Ситуация №1. Имеем устройство, питающееся от сети и потребляющее по шине +5,0В 450мА. При этом встроенный источник рассчитан на 1А и никаких особых требований к энергопотреблению не предъявляется. На шине I2C присутствуют устройства, умеющие работать в режиме «Fast-mode» (т.е. понимающие часто́ты до 400кГц). Точность напряжения питания +5,0В составляет ±5%.

Поскольку никаких требований к энергопотреблению у нас нет, зато в наличии нехилый запас по току у источника питания, в данном случае я бы рекомендовал использовать подтяжку номиналом поменьше. Связано это с тем, что, повторюсь, в потреблении нас никто не ограничивает, а вот от модернизации устройства, при котором на шину I2C вполне может добавиться несколько микросхем, мы отнюдь не застрахованы. Ну а поскольку лишние чипы – это лишняя емкость, которая будет дополнительно заваливать передние фронты импульсов SDA и SCL, подтягивающий резистор в данном случае хотелось бы иметь поменьше. В связи с этим для расчета номинала подтяжек используем формулу [1], ибо именно она позволяет рассчитать минимальное значение RP. При этом учтем, что максимально возможное значение напряжения питания шины составляет VDD_MAX=+5,0В+5%=+5,25В, а допустимый выходной ток микросхем, рассчитанных на работу с шиной I2C, должен быть не ниже 3мА (см. Таблицу 9 на стр. 47 стандарта). Подставив данные значения в формулу [1] и взяв запас по выходному току 20% (ибо на полную катушку гонять электронику я не люблю), получим следующее минимально возможное сопротивление подтягивающих резисторов для линий SDA и SCL:

Далее осталось лишь выбрать ближайшее значение из стандартного ряда номиналов, которое превышает расчетное RP_MIN. Единственное, на чем здесь хотелось бы заострить внимание – выбирать надо с учетом погрешности ряда. Например, если мы используем ряд E24 (точность ±5%), то брать ближайший больший номинал 2,2кОм нельзя, поскольку из-за разброса сопротивление такого резистора может составлять 2,2кОм–5%=2,09кОм, что меньше расчетного RP_MIN. В итоге приходится увеличить сопротивление до 2,4кОм, что слегка затянет фронты импульсов SDA и SCL и снизит максимально возможную рабочую частоту. А вот если используется 1%-й ряд, то здесь номинал 2,2кОм уже́ будет в тему, поскольку сопротивление такого резистора не может быть ниже 2,2кОм–1%=2,178кОм, а это нас вполне устраивает. Понятно, что ставить 1%-е резисторы на подтяжки шины I2C далеко не всегда разумно, но само по себе влияние используемого ряда номиналов вышеприведенный пример демонстрирует довольно хорошо. В нашем же случае выберем для подтягивающих резисторов номинал 2,4кОм±5%, и теперь осталось только прикинуть максимальную частоту, на которой сможет работать наша шина. Для этого воспользуемся формулой [3], куда подставим наихудшую комбинацию параметров: максимально возможное сопротивление подтягивающего резистора (2,4кОм+5%=2,52кОм) и максимально возможную емкость линии (для «Fast-Mode» по стандарту это будет 400пФ):

Отметим, что полученная величина меньше, указанной в спецификации I2C (400кГц). С другой стороны, частота 276,2кГц соответствует предельно допустимой емкости на линии шины, а такую емкость еще надо умудриться создать (например, если шина состоит из 16 устройств, то ее емкость, скорее всего, не будет превышать 150пФ). Ну и вообще говоря, сам стандарт I2C предусматривает, что из-за большой емкости могут возникнуть подобные ситуации и даже предлагает различные варианты выхода из них (см. п.7.2 на стр. 56). Поэтому лично я не вижу в снижении максимально возможной частоты ничего страшного. Ну а если уж прям вот кровь из носу надо именно 400кГц, тогда можно будет убрать запас по току выхода и снизить напряжение питания – в этом случае можно использовать подтяжки с меньшим сопротивлением, что увеличит предельную частоту работы шины. Вдобавок ко всему, номинал 2,4кОм был рассчитан для общего случая, т.е. когда на шине может висеть вообще любое устройство, удовлетворяющее спецификации I2C. Однако, существуют чипы, которые гарантированно могут пропускать через свой выход токи больше 3мА. И если вся шина состоит из подобных могучих микросхем, то в формулу [1] в качестве IMAX можно подставлять не 3мА, а вот этот увеличенный ток, что позволит еще больше уменьшить сопротивление подтяжек. Однако, следует учитывать, что при этом на шине смогут присутствовать только могучие микросхемы, ибо если там появится чип, рассчитанный всего на 3мА, уменьшенная подтяжка его запросто спалит.

Ситуация №2. Имеем устройство, питающееся от литиевого аккумулятора. При этом дывайс в целом довольно прожорливый, поэтому потребление линий I2C в нем хотелось бы минимизировать. С другой стороны, внутри устройства идет довольно активная жизнь, поэтому скорость обмена данными гарантированно должна быть не ниже 100кГц (т.е. работаем в «Standard-Mode»). При этом на шине находится 4 микросхемы и дывайс не подразумевает никаких модификаций. Напряжение питания камня и периферии составляет +3,3В±2%.

Очевидно, что здесь выдвинуты два требования, идущие вразрез друг с другом – для снижения энергопотребления сопротивление подтягивающих резисторов нужно увеличивать, однако, это приведет к ограничению максимальной рабочей частоты. С другой стороны, в данном примере первое требование – это больше пожелание, поскольку никаких конкретных цифр не приводится, а вот второе – это именно пункт ТЗ, поскольку в нем четко прописана частота, на которой шина должна уметь работать в любом случае. Поэтому и рассчитывать сопротивление подтягивающих резисторов нужно исходя из второго требования. А для этого нам нужно использовать формулу [2], ибо именно она позволяет рассчитать максимальный номинал подтяжек, при котором шина еще будет работать на стандартной частоте.

Для начала надо узнать емкость линий SDA и SCL. Поскольку на шине висит 4 устройства, а емкость входа/выхода каждого из них не должна превышать 10пФ (см. Таблицу 9 на стр. 47 стандарта), можем считать, что суммарная емкость выводов всех чипов шины составляет 4*10пФ=40пФ (кстати, обратите внимание, что есть I2C-микросхемы, емкость выводов которых больше 10пФ, поэтому при вычислении значения Cb надо крайне внимательно смотреть таблицы в даташытах). К данному значению необходимо добавить емкость соответствующей дорожки печатной платы (я беру по 1,18пФ на каждый сантиметр меди – см. техасовский апнот, стр. 3). Если предположить, что длина дорожки составляет 10см, то ее емкость составит 1,18пФ/см*10см=11,8пФ, и суммарная емкость линий SDA и SCL будет равна Cb=40пФ+11,8пФ=51,8пФ. Отсюда мы можем по формуле [2] найти максимальное сопротивление подтягивающего резистора для шины, работающей в режиме «Standard» (время нарастания импульсов не должно превышать tr=1000нс, см. Таблицу 10 на стр. 48 стандарта):

Ближайший меньший номинал – это 20кОм±5% (19кОм…21кОм) или 22кОм±1% (21,78кОм…22,22кОм). Однако, на мой взгляд, формула [2] дает корректный результат лишь в том случае, когда мастер умеет формировать тактовые импульсы хитрой формы – сначала он должен подождать, пока сигнал SCL нарастет до 0,7VDD, затем выдержать интервал tHIGH, после этого перевести линию в нуль и подождать еще tLOW. Тогда в нашем случае до 70% емкость линии успеет зарядиться за 1,2∙RP_MAXCb=1,42мкс, далее в режиме «Standard» надо дополнительно выждать tHIGH=4мкс, а затем сбросить линию и держать ее в нуле tLOW=4,7мкс. И в итоге мы получим, что период тактовых импульсов будет равен T=1,42мкс+4,00мкс+4,70мкс=10,12мкс, а частота их составит f=1/T=1/10,12мкс=98,8мкс, т.е. практически то, что надо. Но реальные микросхемы, имеющие возможность быть мастером шины I2C, далеко не всегда умеют формировать подобные импульсы. Например, в случае камней ATMega сигнал SCL – это обычный меандр, у которого время нахождения в высоком состоянии равно времени нахождения в низком состоянии. И если у нас длительность единицы равна 1,42мкс+4,00мкс=5,42мкс, то и длительность нуля тоже будет равна 5,42мкс. Поэтому период тактовых импульсов составит T=5,42мкс+5,42мкс=10,84мкс, а частота – f=1/T=1/10,84мкс=92,3кГц. Это уже́ существенно отличается от требуемых 100кГц, поэтому в данном случае для расчета сопротивления подтягивающего резистора я бы рекомендовал использовать формулу, которая учитывает, что тактовые импульсы могут быть только меандром (она легко получается из формулы [3]):

И если для расчетов сопротивления подтяжек использовать ее, то максимальное значение RP составит

RP_MAX = (1–2*100кГц*4мкс) / (2,4*100кГц*51,8пФ) = 16,27кОм,

поэтому в качестве подтягивающих резисторов здесь нужно выбрать 15кОм±5% (14,25кОм…15,75кОм) или 16кОм±1% (15,84кОм…16,16кОм). Естественно, это увеличит потребление тока по шине I2C, однако, с гарантией позволит работать на требуемой частоте даже в том случае, когда тактовый сигнал является меандром. Тем более, что абсолютные значения отжираемого тока будут не сильно отличаться. Если взять вариант «5%-й ряд», то в первом случае максимальное потребление тока составит

и на фоне того, что литиевые аккумуляторы имеют собственный ток разряда в районе десятков микроампер, разницу между I1 и I2 можно считать равной нулю.

Ситуация №3. Имеем устройство, питающееся от батарейки типа «Крона» с емкостью 150мАч. При этом дывайс в целом не сильно жрущий, однако, находится он в труднодоступном месте, и часто менять батарейки в нем не получится. В связи с этим потребление линий I2C в нем необходимо сделать настолько низким, насколько это вообще возможно. При этом устройство крайне неспешно, и его практически единственная задача – опрашивать некий датчик раз в 30 секунд (т.е. частота опроса составляет 0,033Гц). На шине I2C кроме камня и датчика никого нет и никогда не будет. Напряжение питания камня и периферии составляет +5,0В±5%.

Данная ситуация почти один в один нам уже встречалась ранее (см. вывод формулы [4] выше). Для нее характерно стремление максимально снизить энергопотребление шины I2C за счет использования высокоомных подтягивающих резисторов. При этом то, на какой максимальной скорости сможет работать шина с такими подтяжками, нам вообще похер – при частоте опроса датчика один раз в 30 секунд эта скорость может быть практически любой. Поэтому в данном случае мы можем использовать самый большой номинал резисторов, который еще гарантирует приемлемые уровни сигналов на линиях SDA и SCL. Расчет этого номинала будем вести с помощью формулы [4], учитывающей токи утечки по входам/выходам I2C-микросхем. При этом учтем, что минимально возможное напряжение питания шины составляет VDD_MIN=+5,0В–5%=+4,75В, а суммарный ток утечки для двух чипов на шине не превысит IΣ_LEAK=20мкА (т.к. в соответствии со спецификацией I2C, у каждой микросхемы этот ток не должен превышать 10мкА – см. Таблицу 9 на стр. 47 стандарта):

RP_MAX_HARD = 0,3VDD_MIN / IΣ_LEAK = 0,3*4,75В / 20мкА = 71,5кОм,

Ближайший меньший номинал – это 68кОм±5% (64,6кОм…71,4кОм). При этом ток, отжираемый шиной I2C в худшем случае составит

I = (5,0В+5%) / 64,6кОм = 81,3мкА,

а скорость передачи данных можно будет с гарантией сделать не ниже

где 25пФ – емкость линии, на которой висят две микросхемы (по 10пФ на каждую), соединенные между собой дорожками длиной 4,2см (такое расстояние взято, чтобы суммарная емкость дорожки получилась 5пФ).

Что здесь можно сказать? Несмотря на то, что сопротивление подтягивающих резисторов получилось сравнительно большим, энергопотребление шины I2C оказалось далеко не на высоте. Чтобы это понять, достаточно сравнить полученное значение тока через подтяжки из этого примера (81,3мкА) и из предыдущего (236,2мкА). С одной стороны, снижение потребления налицо – цифры отличаются почти в три раза, к тому же в первом случае питание значительно ниже, чем во втором (а от этого напрямую зависит токопотребление шины). Но ведь, с другой стороны, и критерии, по которым рассчитывались подтягивающие резисторы, тоже существенно отличаются. Напомню, что в первом случае нам надо было уменьшить потребляемый ток, но при этом оставить возможность обмена данными на сравнительно большой скорости. Т.е. здесь улучшение энергопотребления априори было возможно только до уровня «как получится, так и получится», но при этом результат оказался вполне достойным (236мкА вместо «стандартных» 3мА, т.е. разница почти в 13 раз!). В втором же случае нам было абсолютно плевать на частоту работы шины, главным было уменьшить энергопотребление любой ценой – и разница всего в три раза. Да, если бы питание камня в медленном устройстве было равно +3,3В±2%, то эта разница составила бы четыре с половиной раза, однако это тоже, на мой взгляд, довольно мало. С третьей стороны, сама по себе цифра 81,3мкА – не сильно велика, особенно на фоне того, что связь с датчиком будет осуществляться раз в полминуты. Поэтому можно с ней «смириться», и оставить всё как есть. Однако, на всякий случай всегда нужно помнить, что расчет резисторов по формулам [4] и [4а] заведомо дает значение сопротивления с охереннейшим запасом, и если для нас важны каждые 10мкА, то всегда остается вариант прямого измерения суммарного тока утечки линии шины.

Как я уже́ говорил ранее, в документации на I2C-микросхемы чаще всего приводятся только максимальное значение тока утечки. И если в реальности он в два раза меньше, а на шине находится 3 устройства, то номинал подтягивающего резистора может быть увеличен в 2*3=6 раз без каких-либо ухудшений работы шины. Если ток в три раза меньше заявленного, а шина состоит из 5 микросхем, то подтяжку можно увеличить в 3*5=15 раз. И поскольку обычно значение утечки из таблицы минимум в 3 раза больше ее реальной величины, то на практике шина I2C вполне нормально работает с подтягивающими резисторами в несколько сотен килоом. Например, вот так выглядят тактовые импульсы в системе, образованной датчиком температуры LM75A и камнем ATMega328P, при использовании подтяжек номиналом 1,1МОм:

Питание шины составляет +5,0В. Обратите внимание на то, что в исходном состоянии (самый левый кусок осциллограммы) даже при использовании мегаомного резистора напряжение на линии SCL просаживается лишь на 0,5В относительно VDD . Это значит, что суммарный ток утечки по ней составляет всего IΣ_LEAK=0,5В/1,1МОм=0,46мкА вместо предельных 20мкА (2*10мкА), которые допускает спецификация (и которые, кстати, указаны в документации на вышеупомянутые микросхемы). Таким образом, в соответствии с формулой [4] сопротивление подтяжки линии SCL можно увеличивать вплоть до

RP_MAX_HARD = 0,3VDD_MIN / IΣ_LEAK = 0,3*4,75В / 0,46мкА = 3,09МОм,

т.е. более чем в 40 раз (!) по сравнению со значением, рассчитанным для предельных 20мА. Конечно, в серию такой резистор я бы не поставил, но в штучные дывайсы – почему бы и нет? Во всяком случае, в нескольких единичных поделках у меня на шину I2C чисто ради интереса установлены подтяжки номиналом 1МОм±5% и ничего – работают без нареканий несколько лет. Да и почему бы им не работать, если всё грамотно посчитано, а не взято с потолка? Вот, например, тактовые импульсы, показанные на последней осциллограмме. Большинство мега-гуру сразу же скажут: такие импульсы абсолютно неприемлемы. Извините, а почему? Потому, что эти импульсы не являются прямоугольниками? Так это не страшно – параметр tr в спецификации дан только для того, чтобы шина могла работать на максимально возможной частоте, а нам на это плевать. Или плохо то, что импульсы не доходят до напряжения питания? Так и на это тоже похер – главное, что они дотягивают до уровня 0,7VDD и после этого не сбрасываются еще минимум 4мкс. В итоге получаем, что шина отлично работает даже с треугольными сигналами SCL, если они сформированы в соответствии со стандартом, а все рассказы о их неправильной форме основаны на том, что рассказчик вообще не шарит в теме. То же самое касается и криков «на шине I2C не может быть мегаомных резисторов!» – вы сначала объясните, почему их там не может быть, а вот с этим возникают проблемы. Поэтому лично я считаю, что если надо прямо вот до усрачки предельно снизить потребление тока шиной I2C, то вполне допустимо не брать токи утечки микросхем из документации, а напрямую измерять их для конкретных чипов. Последовательность действий при этом будет такой:

• собираем устройство (ну, или хотя бы шину I2C);

• в качестве подтяжек вешаем резисторы номиналом 1МОм;

• измеряем, какое напряжение падает на этом резисторе в исходном состоянии шины (можно прямо тестером, только обмена данными во время измерений быть не должно, плюс некоторые тестеры имеют входное сопротивление 1МОм, и это нужно учитывать);

• получаем профит: реальный суммарный ток утечки данной линии (IΣ_LEAK) в микроамперах численно равен измеренному напряжению.

Далее можно вычислить максимально допустимое сопротивление подтягивающего резистора при помощи формулы [4]:

и выбрать ближайший меньший стандартный номинал. При этом необязательно стремиться именно к расчетному значению, ибо даже 1МОм в случае цифровых микросхем с их питанием максимум +5,0В дает ток потребления линии не больше 0,5мкА (чего обычно более чем достаточно). Ну и в завершение нужно при помощи формулы [3] рассчитать, до какой частоты сможет без глюков работать наша шина:

(как найти емкость Cb, было рассказано в прошлом примере). Например, для случая ATMega328+LM75A и подтяжки 1МОм, показанного на последнем рисунке, суммарная емкость составит Cb=10пФ+10пФ+11,8пФ+16пФ=47,5пФ (здесь 10пФ – емкость вывода I2C-микросхемы по стандарту, 11,8пФ – емкость линии связи длиной 10см и 16пФ – емкость щупа осциллографа при коэффициенте деления 1/10). Поэтому максимальная частота работы шины составит

и, как нетрудно видеть по последней картинке, при записи соответствующего значения TWBR в камень ATMega328 всё отлично работает. Там, кстати, даже побольше частота установлена (8,2кГц), потому что я при расчетах взял не 1,1МОм, а 1МОм, и всё равно шина пашет как надо, ибо 0,7VDD – это с запасом. Так что рассмотренный способ увеличения сопротивления подтяжек вполне работает, ну а уж пользоваться им или нет – решать вам.

Программная часть интерфейса I 2 C

Для того чтобы устройства могли общаться по шине I2C, должна быть соблюдена определенная последовательность битов на линиях синхронизации (SCL) и данных (SDA), поскольку кроме передачи непосредственно «полезной» информации шина предусматривает также наличие служебных битов. Обмен данными осуществляется пачками (посылками, транзакциями). Каждая пачка состоит из стартового бита, стопового бита, непосредственно передаваемой информации, а также битов подтверждения/неподтверждения:

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

Любая посылка начинается со стартового бита, который определяется как задний фронт импульса на линии SDA, в то время как сигнал SCL установлен в единицу. Возникновение такого события воспринимается всеми устройствами, подключенными к шине, как признак начала процедуры обмена, и после фиксации старт-бита шина считается занятой. Обратите внимание на то, что формирование стартового бита – это обязанность мастера.

После того, как старт-бит сформирован, ведущий опускает линию SCL в нуль и выставляет на линию SDA старший бит первого байта сообщения, после чего линия SCL устанавливается в единицу. Обратите внимание на то, что данные, передаваемые по линии SDA, считаются действительными только во время высокого состояния тактового импульса (т.е. при SCL=1), а изменения на линии SDA допускаются исключительно при SCL=0. При этом данные с линии SDA считываются по переднему фронту тактового сигнала, а обновляются обычно по его заднему фронту. После отправки старшего бита передаваемого байта, на линию данных поочередно выставляются все остальные его биты, вплоть до младшего. Таким образом, обмен информацией по шине I2C происходит побайтово (количество байт в сообщении не ограничено). При этом за каждым байтом следует бит подтверждения («ACK») или не подтверждения («NACK»), выставляемый на шину приемником. Отметим, что «ACK» соответствует низкому логическому уровню, а «NACK» – высокому. Так сделано из-за того, что единица – это рецессивное состояние шины I2C, и если приемник заглючил, то сигнал сам по себе поднимется до «NACK». Поэтому подтверждение «ACK» может быть передано только в том случае, когда приемное устройство может прижать линию SDA к массе, что свидетельствует о его работоспособности.

Заканчивается транзакция стоповым битом, определяемым как передний фронт импульса SDA, в то время как сигнал SCL установлен в единицу. Любая I2C-посылка должна заканчиваться стоп-битом, однако может возникнуть ситуация, при которой стоповому биту предшествует не один, а несколько стартовых битов (см. ниже). Как и в случае стартового бита, формирование стоп-бита является обязанностью мастера. Через некоторое время после возникновения стопового бита шина считается освободившейся.

Последовательность событий при передаче данных по I2C будет такой:

• мастер генерирует стартовый бит, чтобы инициировать транзакцию;

• в первом байте сообщения мастер передает 7-битный адрес, соответствующий ведомому устройству, с которым он хочет связаться. Последний бит в этом байте – это индикатор чтения/записи. Если мастер хочет считать данные с ведомого устройства, он устанавливает данный бит в единицу, если же данные должны быть записаны, то последний бит первого байта сбрасывается;

• следующий байт – это байт данных. Он может исходить как от ведущего, так и от ведомого, в зависимости от состояния бита чтения/записи в первом байте. Напомним, что данные передаются по 8 бит, начиная со старшего;

• за байтом данных следует бит подтверждения, равный «ACK» или «NACK». Если осуществляется процедура считывания данных, то бит подтверждения генерируется мастером. Если же производится запись данных, то бит подтверждения должно генерировать ведомое устройство. Отметим, что процесс формирования бита ACK/NACK в случае шины I2C заслуживает особенного внимания, поэтому чуть ниже он будет рассмотрен более подробно;

• после формирования бита подтверждения по шине можно передавать следующий байт данных (напомним, что количество передаваемых байт неограниченно);

• посылка завершается стоп-битом, сгенерированным мастером;

• после этого шина считается готовой к осуществлению новой транзакции.

Как было сказано выше, процесс формирования бита подтверждения в случае шины I2C является нетривиальным. В том случае, когда мастером осуществляется запись данных в ведомое устройство, бит подтверждения генерирует ведомый. При этом на время импульса подтверждения мастер отпускает (переводит в высокое состояние) линию SDA, а ведомое устройство должно формировать сигнал «ACK», удерживая данную линию в низком уровне всё время, пока импульс синхронизации SCL равен единице. В том случае, когда ведомый не может ответить ведущему (например, когда он выполняет в данный момент какие-либо функции реального времени), линия данных SDA должна быть оставлена им в высоком состоянии, что будет соответствовать сигналу «NACK». При возникновении подобной ситуации у мастера остается возможность выдать стоповый бит для прерывания пересылки данных.

В случае, когда мастер считывает данные с ведомого, бит подтверждения после каждого принятого байта он должен формировать сам. При этом возможны два варианта. Если ведомый (по мнению мастера) передал еще не всю информацию, ведущий должен сгенерировать сигнал «ACK». Если же мастер считает принятый байт последним в посылке, то в этом случае вместо «ACK» выставляется сигнал «NACK», сообщающий ведомому об окончании транзакции и требующий от него освободить шину. Подобный подход является крайне эффективным в тех случаях, когда мастер получает от ведомого (например, от датчика температуры) непрерывный поток данных. В этом случае ведущему не нужно для считывания нового значения постоянно начинать новую транзакцию – достаточно просто не прерывать старую, раз за разом выставляя «ACK» в ответ на принятые данные. Если же мастеру нужно отвлечься на что-то еще, он может сформировать «NACK» после приема очередного байта и начать новую транзакцию только тогда, когда он будет к этому готов. Отметим, что для описанной работы интерфейса I2C ведомый, передающий данные мастеру, должен отпускать (т.е. переводить в высокое состояние) линию данных SDA на время формирования ведущим бита подтверждения.

Формирование нескольких стартовых битов

Протокол I2C допускает возможность формирования на шине так называемых «повторных запусков», когда мастер при помощи стартового бита начинает одну транзакцию, а затем объявляет начало новой транзакции без промежуточного стопового бита:

Данная фича введена для устранения возможных конфликтов между несколькими мастерами, присутствующими на шине. Чтобы понять, зачем она нужна, рассмотрим типичный пример – вычитывание данных с ведомого, в качестве которого выступает датчик температуры LM75A. Сначала мастеру надо сформировать стартовый бит для того, чтобы объявить начало транзакции. Затем нужно отослать датчику первый байт данных. В данном байте содержится адрес конкретного датчика (их на шине может висеть до восьми штук), последний же бит равен нулю – это означает, что мы будем записывать данные в датчик. Это может показаться странным, ведь, по идее, данные из датчика мы должны считывать, а не записывать их туда. Однако, из LM75 можно вытащить не только температуру, но и всякую служебную информацию, поэтому перед считыванием данных мы должны указать микросхеме, из какого регистра мы хотим их читать. Таким образом, вторым байтом данной транзакции будет выступать адрес регистра, в котором хранится измеренная температура (0х00). И в итоге первая посылка будет содержать адрес датчика, с которым мы хотим общаться (старшие 7 бит первого байта), плюс требование работать с регистром температуры (младший бит первого байта + второй байт). А вот далее можно уже́ считывать показания термометра – хоть непрерывно, хоть однократно. Однако, перед этим нужно объяснить датчику, что данные теперь должны именно считываться. Согласно стандарту I2C, это можно сделать только при помощи адресного байта, т.е. первого байта транзакции, в котором указывается адрес ведомого и направление передачи данных. Поэтому мастер будет вынужден объявить новую транзакцию на шине, для чего ему, по идее, надо было бы сначала сформировать стоповый импульс, а затем – стартовый. Так вот, функция «повторного запуска» позволяет ведущему сгенерировать стартовый бит, начинающий вторую транзакцию, без завершения первой посылки (т.е. без выдачи на шину стоп-бита).

На первый взгляд, данная фича абсолютно бесполезна, ибо сформировать стоповый бит для мастера – дело плёвое. Однако, смысл использования повторного запуска становится ясен, если вспомнить, что на шине I2C может присутствовать несколько мастеров. Дело в том, что при формировании стоп-бита мастер освобождает шину, поэтому любой другой ведущий тут же может ей воспользоваться. И нет никакой гарантии, что между первой и второй транзакцией не объявится мастер, который тоже захочет пообщаться с ведомыми, при этом помешав первому мастеру получить необходимые данные. Более того, второй ведущий может обратиться к тому же датчику и указать другой адрес регистра, из которого нужно вычитывать данные, после чего освободить шину для второй транзакции. И если в этот момент первый мастер захватит шину, то он будет читать неправильную инфу, поскольку исходить она будет не из регистра температуры, а из какого-то другого, запрошенного вторым ведущим. И именно для предотвращения подобной херни в стандарт I2C была введена возможность «повторного запуска», позволяющая начать вторую транзакцию (в нашем случае – чтение) без освобождения шины (т.е. без формирования стопового бита).

Арбитраж шины I 2 C

Одним из важных свойств интерфейса I2C является поддержка нескольких мастеров на шине (режим мультимастера). При этом во избежание конфликтов между ведущими, I2C-микросхемы должны уметь определять, свободна или нет в данный момент шина (см. предыдущий пункт). Если шина занята другим мастером, устройство должно ожидать завершения текущей транзакции, прежде чем инициировать свою собственную передачу. Но что происходит, когда два (или более) ведущих пытаются начать транзакцию одновременно? Шина I2C обеспечивает эффективное и простое решение данной проблемы при помощи процесса, называемым «арбитражем». Данный процесс основан на следующем свойстве выходного драйвера с открытым стоком: если один мастер пытается установить на линии высокий логический уровень сигнала, а другой – низкий, то установлен будет низкий логический уровень. В этом случае говорят, что второй мастер «выиграл», поскольку состояние шины будет определять именно он. Более того, если «проигравший» имеет возможность опрашивать свой выход, то он сразу обнаружит, что фактическое состояние линии не соответствует предполагаемому (т.е. на шине присутствует нуль, а не единица), и сможет прервать передачу данных:

Процесс арбитража на шине I2C происходит следующим образом. Сначала оба мастера генерируют стартовый бит, после чего они начинают последовательно выставлять данные на шину. При этом если логические уровни на линии SDA совпадают, процесс выдачи данных продолжается как обычно. Однако, при возникновении первого же несовпадения мастер, установивший низкий уровень сигнала, объявляется победителем и полностью захватывает шину, а проигравший должен прекратить передачу информации. При этом победитель может продолжать передачу без каких-либо прерываний (т.е. без необходимости перезапускать транзакцию), а это означает сохранность передаваемых данных и отсутствие конфликтов с другими устройствами. Однако, за такие плюхи приходится платить усложнением схемы выходного драйвера, т.к. он должен уметь одновременно как выставлять сигнал на линию SDA шины, так и считывать его фактическое состояние.

Поскольку после стартового бита на шину I2C должен выставляться «адресный» байт, то вполне очевидно, что большинство арбитражных конфликтов будет разрешено в течение его старших семи бит, ибо разные мастера обычно обращаются к разным ведомым. Однако, нельзя исключать ситуацию, при которой два ведущих захотят одновременно обратиться к одному и тому же устройству. В этом случае «адресный арбитраж» не будет выигран ни одним из мастеров, поскольку данные, которые они выставят на шину в течение семи старших бит «адресного» байта, будут идентичными. И далее в дело вступит «арбитраж по направлению передачи», при котором сравниваются младшие биты «адресного» байта. Напомним, что в соответствии со стандартом I2C, младший бит первого байта транзакции должен быть равен нулю, если инициируется процесс записи данных в ведомого, и единице, если инициируется процесс чтения. Таким образом, здесь возможны два варианта. Если оба мастера хотят считывать информацию с ведомого, то арбитраж по направлению не выиграет ни один из них, и оба ведущих начнут одновременное чтение данных с одного и того же устройства (что ничему не противоречит). Если же один мастер инициирует запись информации, а второй – ее считывание, то победителем будет ведущий, желающий записать что-то в ведомого (а второму мастеру придется подождать, пока процесс записи не будет завершен). Отметим, что если писа́ть данные на шину намереваются сразу два ведущих, то дальше вступит в дело «арбитраж по данным», который выиграет устройство, у которого в передаваемой информации раньше всех встретится нуль. Таким образом, наличие на шине адресного арбитража и арбитража по данным намекает нам, что самые «важные» адреса и данные должны быть как можно меньше (т.е. ближе всего к нулю), ибо они будут обработаны самыми первыми.

Плюсы и минусы шины I 2 C

Таким образом, основными достоинствами шины I2C (по мнению Роберта Кейса) являются следующие:

• поддержка сравнительного большого количества устройств (до 112 штук);

• даже при большом количестве устройств на шине для ее реализации достаточно всего двух линий – SDA и SCL;

• на шину легко повесить ведомые устройства разного типа;

• одновременная поддержка несколько мастеров на одной шине;

• наличие бита подтверждения (ACK/NACK), облегчающего обработку ошибок.

К недостаткам рассматриваемой шины можно отнести:

• увеличение сложности прошивки МК или усложнение аппаратной части;

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

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

Отсюда видно, что интерфейс I2C особенно подходит для систем, имеющих сложную, разнообразную и/или разветвленную сеть исполнительных устройств. Однако, если пропускная способность шины является важным фактором, то от использования данного интерфейса часто приходится отказываться, либо шустрые элементы нужно выводить на отдельную шину, например, SPI или UART. При этом аппаратная реализация SPI/UART намного проще, чем I2C, и если вы работаете с FPGA и разрабатываете свой последовательный интерфейс с нуля, зачастую выбор падает именно на SPI/UART, а не на I2C. С другой стороны, по сравнению с USB или тем же самым Ethernet’ом интерфейс I2C является просто «игрушечным», и если требуемая элементная база для проекта (АЦП, датчики, ЧРВ и т.д.) существует только с интерфейсом I2C, принципиальных проблем с его реализацией даже в FPGA чаще всего не возникает. В любом случае – каждый раз при выборе шин данных, которые будут использованы разрабатываемом устройстве, приходится учитывать уйму «мелких» моментов, и в данной заметке я постарался заострить внимание именно на таких «мелочах» (в основном касающихся аппаратной части I2C).

А у меня на сегодня всё. Желаю удачи при работе с интерфейсом I2C!

Обсудить эту заметку можно здесь.

Место для разного (сдается)

Создание, «дизайн», содержание «сайта»: podkassetnik
Для писем и газет: Почта России электрическая

Место для &#169 (копирайта, понятно, нет, но ссылайтесь хотя бы на первоисточник)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *