I2c driver что это

Обновлено: 08.07.2024


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

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

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

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

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

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

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

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

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

Радиолюбительские измерения: анализ сигналов шины I2C


Как я уже неоднократно упоминал в своих публикациях, любительские проекты финансируются из семейного бюджета, и радиолюбитель, обычно, не может себе позволить покупку дорогостоящего измерительного оборудования. Приходится довольствоваться тем, что есть. Или тем, что удаётся взять попользоваться «на время». А иногда от безысходности радиолюбителю приходится «сверлить пилой и пилить буравчиком».

Недавно я испытал потребность выяснить, что на самом деле передаётся в разрабатываемом мной устройстве по шине I2C. Это был тот счастливый момент, когда можно было себе позволить «пилить пилой».

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

Цифровой двухканальный осциллограф с памятью

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

В данном случае мне достался «на время» цифровой двухканальный осциллограф с памятью Rigol DS1102 (цена на сайте производителя $461). У этого прибора есть два канала измерения с полосой пропускания до 100 MHz и частотой выборки сигнала 1 GSa/s.

К сигналу SCL был подключен CH1. К сигналу SDA был подключен CH2. Для обоих каналов был установлен масштаб 1.00 V/дел. Масштаб развёртки – 10 us/дел. Для наглядности луч первого канала смещён в верхнюю половину экрана, а луч второго канала – в нижнюю.

В меню Trigger осциллограф был настроен на однократное измерение с запуском по достижению передним фронтом в канале CH1 уровня 1.00 V:


После включения тестируемого оборудования была нажата большая красная кнопка Run/Stop. Осциллограф встал в режим ожидания, затем запустился. Через несколько секунд запись была остановлена вручную.

Полученная осциллограмма записывалась на внешний носитель поэкранно:


Произведём разбор записанных сигналов. На первом экране мы видим отображение настроек прибора и осциллограмму сигналов SCL (верхняя часть) и SDA (нижняя часть экрана), на которой читаем слева направо:

  • сигнал START: ведущее устройство выставляет низкий уровень сначала на шине SDA, а затем на шине SCL;
  • 7-bit адрес: читаем 0x60 (1100000) на шине SDA по передним фронтам SCL;
  • признак режима записи: читаем на шине SDA низкий уровень по следующему переднему фронту SCL;
  • сигнал ACK: ведущее устройство после передачи байта переключается на приём по шине SDA, на SDA устанавливается высокий уровень, ведомое устройство по заднему фронту SCL выставляет на SDA низкий уровень (собственно, сигнал ACK), который ведущее устройство считывает по переднему фронту SCL;
  • сигнал STOP: ведущее устройство выставляет высокий уровень сначала на шине SCL, а затем на шине SDA

Логический анализатор цифровых сигналов

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

Для использования в качестве логического анализатора мне был любезно предоставлен коллегами Saleae Logic 8 (цена на сайте производителя $399). В качестве программного обеспечения использовалась демо-версия Saleae Logic 1.2.18, взятая с официального сайта. Устанавливая данное программное обеспечение, я принял лицензионное соглашение с условием, в том числе, не использовать данное программное обеспечение с оборудованием сторонних производителей.

В программе был включен анализатор протокола I2C. Для сигнала SCL был назначен канал CH0, а для сигнала SDA – канал CH1. Частота выборки сигнала 24 MSa/s.


Запуск был настроен по «переднему» фронту CH0. Для отображения данных был выбран шестнадцатеричный формат.


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


Максимум пользы в применении логического анализатора я вижу в том, что программа сама дешифрует полученные данные. Результаты дешифровки заносятся построчно в окно Decoded Protocols. При выборе в окне строки данных, программа показывает расположение этих данных на диаграмме.

Цифровой осциллограф vs логический анализатор

Для сравнения вариантов я «склеил» в графическом редакторе четыре снимка экрана осциллографа и фрагмент диаграммы логического анализатора:

Start обозначен зеленым кружочком, Stop – красным кружочком. На диаграмме сначала происходит проверка наличия на шине устройства с адресом 0x60, а затем производится запись в регистр 0xB7 этого устройства значения 0x80.

Если подходить к сравнению вариантов «с пристрастием», то можно заметить, что на диаграмме логического анализатора (частота выборки 24 MSa/s) присутствует «джиттер» сигнала SCL, которого нет, как такового, на осциллограмме с частотой выборки 1 GSa/s. В остальном картина совпадает, а логическим анализатором ещё и производится правильная дешифрация данных в автоматическом режиме.

При выборе «или-или» в «сухом остатке» имеем, в случае осциллографа, дорогое универсальное устройство, не такое удобное для анализа шины, как логический анализатор, но за сопоставимые с ним деньги. В этих условиях лично я, как инженер «старой закалки», приобрёл бы цифровой осциллограф.

Однако, если бы существовало программное обеспечение с лицензионным соглашением, позволяющим использование недорогих клонов популярных логических анализаторов, типа Saleae Logic 8 или DSLogic Plus…

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

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

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

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

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

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

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

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

И такое программное обеспечение существует

Недорогие клоны популярных логических анализаторов, и не только их, поддерживает программное обеспечение open source проекта sigrok.

Было собрано рабочее место:


После чего начались «танцы с бубном». На Windows 10 запустилась только 32-разрядная версия PulseView. Наличие в системе недорогого китайского клона Saleae Logic (цена на сайте продавца $7) она не определила.

После этого, в Zadig для устройства Logic были установлены драйверы WinUSB, и после повторного сканирования оно определилось в Zadig, как устройство fx2latw:


После этого для устройства fx2latw в Zadig снова были установлены драйверы WinUSB, и только после этого PulseView увидела в списке устройство «Saleae Logic». Устройство было подключено.

После подключения устройства были произведены следующие настройки программы (слева направо по панели инструментов, начиная с надписи «Saleae Logic»):

  • выставлено Pre-trigger capture ratio = 2% по нажатию кнопки с ключом и отвёрткой;
  • отключены лишние входы по нажатию кнопки с красным щупом;
  • выставлен объем записи 100 К выборок;
  • выставлена частота выборки 24 MHz;
  • включен анализатор протокола I2C по нажатию кнопки с жёлто-зелёным значком.
  • каналам присвоены соответствующие сигналам текстовые метки;
  • условием запуска назначен задний фронт сигнала SDA;
  • сигналам I2C назначены соответствующие каналы.


Похоже, «танцы с бубном» того стоили!

UPD: После ручной установки в Диспетчере устройств для устройства USB Logic драйвера libusb-win32 программа PulseView начала стабильно определять наличие в системе «Saleae Logic» без манипуляций с Zadig.

Краткие выводы:

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

Универсальным методом анализа сигналов, но недешёвым и небыстрым, является применение цифрового осциллографа с памятью.

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

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

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

Пишем модуль ядра Linux: I2C

Данная статья посвящена разработке I2C (Inter-Integrated Circuit) модуля ядра Linux. Далее описан процесс реализация базовой структуры I2C драйвера, в которую можно легко добавить реализацию необходимого функционала.

Опишем входные данные: I2C блок для нового процессора «зашитый» на ПЛИС, запущенный Linux версии 3.18.19 и периферийные устройства (EEPROM AT24C64 и BME280).

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



Рисунок 1. Временная диаграмма сигналов шины I2C

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

Шаг первый

Для начала познакомимся с утилитой i2cdetect. Результат работы i2cdetect выглядит следующим образом:

Утилита последовательно выставляет на I2C шину адреса устройств и при получении положительного ответа (в данном случае положительным ответом является ACK) выводит в консоль номер адреса устройства на шине.

Напишем небольшую программку, которая считывает уникальный ID датчика температуры, и выведем результат ее работы в консоль. Выглядит очень просто:

Шаг второй

  • Сначала заполняется TX FIFO: первым идет адрес устройства, а после оставшиеся данные на передачу;
  • Очищается статусный регистр прерывания ISR и разрешаются прерывания в регистре IER (в данном случае прерывание возникающее при отсутствии данных в TX FIFO);
  • Разрешается передача данных и устанавливается старт бит на шине.

Шаг третий

Добавим модуль ядра в сборку и опишем аппаратную часть устройств в device tree:

1. Создадим source файл в следующей директории:


В результате появится файл:

2. Добавим конфигурацию драйвера в drivers/i2c/busses/Kconfig:


3. Добавим в сборку драйвер drivers/i2c/busses/Makefile:


4. Добавим в devicetree (*.dts) описание I2C блока, а также сразу поддержу eeprom устройства:


Подробно рассматриваться выше перечисленные шаги не будут, но любопытным читателям можно заглянуть сюда.

Шаг четвертый

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


Главными управляющими регистрами контроллера являются:

  • Control Register (CTRL) — регистр управления;
  • Interrupt Status Register (ISR) — статусный регистр прерывания;
  • Interrupt Enable Register (IER) — регистр маски прерывания.


Из названий структур и функций очевидно их назначение, опишем только главную структуру из представленных выше:

  • skel_i2c_driver — описывает имя драйвера, таблицу поддерживаемых устройств и функций, которые вызываются в момент загрузки или удаления модуля ядра из системы.


Наиболее простой функцией является skel_i2c_remove, которая отключает источник тактовой частоты и освобождает используемую память. Функция skel_i2c_init выполняет первичную инициализацию I2C контроллера.

Как упоминалось ранее skel_i2c_probe регистрирует драйвер в системе. Последовательность действий, условно, можно разделить на два этапа:

  • Получение системных ресурсов и регистрацию обработчика прерывания skel_i2c_isr;
  • Заполнение полей структуры и вызов процедуры добавления нового I2C адаптера.

Полный скелет драйвера прикреплен ниже. Пожалуйста, если вы нашли ошибки/неточности, или вам есть что добавить — напишите в ЛС или в комментарии.

Управление дисплеем по I2C

Полтора года назад, я делал курсовой проект под названием «частотомер». Измерял я частоту вращения вентилятора компа и выводил данные да дисплей. Это был мой первый проект на микроконтроллере. Все шло хорошо, пока дело не дошло до выбора дисплея. Ну не было в нашем городе их и все! Хотя вру, был один в ЧиД за 800р, но бедному студенту это не по карману :) Через месяц, мне нужно было съездить в Москву, за одно решил заехать на Митинский рынок, где я и приобрел свой первый дисплей: МЭЛТ 16S2H (контроллер HD44780). В итоге курсовик сдан на отлично, но остался какой-то странный осадок… Какая-то не изящная схема включения у этого МЭЛТ-а (ну правильно, я по-конски припаял его к контроллеру проводом толщиной 1мм). Тогда и возникла идея свести количество проводов к минимуму. Первоначально я хотел сделать интерфейс SPI, на паре регистров 74HC595, однако в местной радиолавке их не оказалось. Я плюнул и оставил эту идею до лучших времен.

С новыми силами

Недавно я, как и многие, заказал себе халявным набор I2C микросхем и не менее халявную LPCXpresso у именитой NXP. И как бы это не было парадоксально, они приехали! Две xpress-ы и три набора I2C микросхем! Радости не было предела, однако возник резонный вопрос «зачем мне все это надо?». И тут я вспомнил про старую задумку с драйвером дисплея! Эврика! В пакете Industrial оказалась микросхема PCA9675, которая зовётся «16-и битный расширитель портов ввода/вывода». Все отлично, можно начинать! Но минуточку… Платка получится слишком большой, если применить выводные компоненты. Не беда, применим SMD, которых у меня нет :) Купить всю мелкую рассыпуху я решил в магазине TaydaElectronics. Надо сказать вполне годный магазин, для покупок мелким оптом – самое оно!

Техническое задание
  1. Интерфейс I2C с максимально простым управлением (один байт команда, второй – данные);
  2. Питание 5В, но возможность управления устройством с помощью напряжения 3.3В (т.е. я хотел управлять платой с LPCXpresso);
  3. Возможность управления подсветкой.
Сборка устройства
  • Резистор 390 Ом (SMD 0805) x11;
  • Резистор 1 КОм (SMD 0805) x1;
  • Резистор 10 КОм (SMD 0805) x3;
  • Микросхема PCA9675PW x1;
  • Биполярный транзистор SMD npn (я взял 2N5551S, т.к. боялся, что ток у подсветки может быть приличным);
  • Стабилитрон 3.3В (у меня 1N4728);
  • Резистор 100 Ом (выводной, т.е. TH) x1.

Я думаю тут все вполне очевидно, но все же приведу некоторые комментарии:

  1. Линия E (строб) дисплея: P00 микросхемы;
  2. Линия RW (чтение/запись) дисплея: P01 микросхемы;
  3. Линии RS (команда/данные) дисплея: P02 микросхемы;
  4. Подсветка дисплея: P03 микросхемы;
  5. Линии D0…D7 (байт данных) дисплея: P10…P17 микросхемы;
  6. Стабилитрон выполняет питание микросхемы и подтягивающих резисторов;
  7. Транзистор управляет подсветкой экрана;
  8. Контрастность экрана подтянута к земле (Вот это я зря! Но об этом чуть позже);
  9. Линии выбора адреса устройства (A0, A1, A2) подтянуты к земле, таким образом по даташиту мы получаем адрес устройства 0x40.

Замечание 2: после сборки схемы, оказалось, что если подтянуть контрастность к земле, то оптимальная работа экрана возможно лишь на напряжении питания 4.3 – 4.7В. по этому я настоятельно рекомендую добавить построечный резистор, для управления контрастностью


В итоге я сделал такую штуковину:

Первый опыт

Учитывая то, что я еще не был уверен в работоспособности платы, начать я решил с arduino. Скажете, что это не труЪ? И будете правы! Однако для первого опыта arduino – как раз то, что нужно.

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


Ну что же, дисплей подключен к драйверу, драйвер 4-я проводами к arduino, осталось подключить плату к Компу, залить прошивку и можно тестить!

Собственно исходник прошивки:

В целом я думаю ничего сложного, но опять-таки объясню ключевые моменты:

  1. Кто не знает, в arduino нету main, зато есть бесконечный цикл (процедура loop) и первоначальные установки (процедура setup);
  2. Про дисплей я думаю ничего объяснять не надо, этого добра в интернете навалом;
  3. Процедура работу с микросхемой PCA9675 весьма проста (см. диаграмму):
    1. Начинаем передачу и передаем адрес устройства;
    2. Передаем первый байт (команды);
    3. Передаем второй байт (данные);
    4. Завершаем передачу.

    Внимание! Для arduino нужно делить адрес устройства на 2 в шестнадцатеричной системе счисления.
    Например, по даташиту адрес устройства = 0x40, значит для arduino мы получим 0x20.

    Если вы внимательно читали данную статью, то наверняка задумались, для чего нужна ножка int? Это ножка прерывания с микросхемы. Она нужна для приема данных с микросхемы. Пока этой фишкой я еще не овладел, на как только разберусь, обязательно сообщу!


    Пожалуй про arduino все. На последок покажу фотку устройства в работе:

    P.S. отвратная фотка, знаю :( Кто-нибудь, научите меня фоткать.

    Второй опыт

    Наступала ночь, но мне что-то не спалось. Хотелось заюзать свою новую няшку, в сочетании с LPC1114 (aka LPCXpresso), для которой я и затеял сие действо.

    Проблема было только одна: где взять 4.5В?

    1. поглядел на плату, нашел там пин +5VIN, померял – действительно 5В, но подключив к ним дисплей понял, что ток там ничтожный, нужно искать другой источник;
    2. Почитал мануал по плате, нашел там USB-VBUS, который якобы подключен к +5В… Обман! На моей плате он подключен к какой-то ножке МК;
    3. Возникла мысль найти +5В от USB, сказано сделано, нашел! (см. рисунок).


    P.S. на картинке не моя плата, просто эта картинка более качественная и отлично подходит для пояснения.

    Замечание: при 5В дисплей работает, но нужно изменить контрастность (что я не предусмотрел)

    Прошивка получилась тоже простой, ее анализировать я не хочу, т.к. получилась она почти такой же, как и для arduino (я просто взял демку I2C и немного ее допилил). Хочу отметить, что для LPCXpresso в моем случае адрес устройства соответствует адресу из даташита (т.е. 0x40).

    Заключение
    Данное устройство я считаю не законченным, в схеме явно не хватает стабилизатора напряжения (хотя конечно можно и обойтись без него) и регулировки контрастности, из-за отсутствия которой мне пришлось немного по шаманить. В целом я хотел сделать акцент на том, что самое трудное в нашем деле – это железо, которое зачастую довольно трудно достать, приходится по долгу ждать посылок, искать фирмы, которые готовы предоставить бесплатные образцы, однако результат стараний всегда оправдывается! Если в устройство вложить душу, то оно для тебя всегда будет самым лучшим.

    Комментарии ( 31 )

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

    Алсо, duemilanove переводится как «две тысячи»… че-то они отстали от времени…

    Читайте также: