Поиск неисправной микросхемы с помощью логического анализатора

Сегодня хочу рассказать как можно обнаружить неисправную микросхему с помощью логического анализатора.
Очень часто на платах присутствует несколько микроконтроллеров, которые общаются между собой посредством интерфейса SPI, I2C или какого-то другого. И почти всегда на старте центральное управляющее устройство проверяет правильную инициализацию управляемых устройств. Такая проверка осуществляется установкой связи с управляемым микроконтроллером и попыткой чтения или записи некоторых значений регистров. И в случае сбоя отправляется сигнал сброса RESET на все устройства.
Например, в автомагнитоле HU-850 это можно заметить по характерным повторяющимся щелчкам в колонках с периодом в 3-5 секунд после включения.
Чтобы найти неисправную микросхему нужно первым делом прозвонить все выводы на короткое замыкание и убедиться, что на все входы Vcc и Vdd подается правильное напряжение питания. Информацию о расположении выводов можно найти в даташите на микросхему.

Вот так в даташите выглядит схема выводов. Так как микросхема может состоять из нескольких блоков, то и питание на них может подаваться раздельно и лучше прозвонить их все и убедиться, что с этим все в порядке.
На схеме красным цветом обозначил выводы питания — Vss(земля) и Vdd(+3.3V). А сигнал RESET подается через 42-ю ногу с подписью DSP_RESET. Надеюсь сами её на картинке найдете 🙂
Процедура сброса так же описывается в даташите. Active low означает, что на эту ногу подается постоянное напряжение +5V и сброс произойдет, когда напряжение упадет близко к 0.

Для определения того, что управляющий контроллер посылает сигнал сброса на другие устройства, необходимо установить мультиметр в режим проверка постоянного напряжения +20V и поставить красный щуп на пин 42 DSP_RESET, а черный на землю. Если на протяжении 10-15 секунд вы будете наблюдать постоянное напряжение без падения, то сброса не происходит. Для более точного определения лучше подключить осциллограф, но не у всех он есть. Такую процедуру лучше провести для всех микроконтроллеров в схеме, так как они могут управляться разными каналами сброса с центрального контроллера.
Но иногда бывает так, что несколько контроллеров завязаны на одну шину и управляются одним сбросом. Тогда сигнал сброса будет поступать сразу на все устройства и этим методом определить неисправный контроллер не получится.
В этом случае нам необходимо будет проверить сигнал на входе в I2C интерфейс. На этой микросхеме вывод A0 заземлен, так как он таким образом формирует режим подчиненного устройства(slave) для этого микроконтроллера. А на выводах SCL и SDA должно быть почти постоянно напряжение +5V. При передаче данных напряжение будет падать и это означает, что сигнал с управляющего устройства по крайней мере доходит до вывода микросхемы 🙂

На фото я обозначил входы I2C шины, которые подаются через резисторы на ноги микросхемы. Левая нога это SCL, а правая SDA.
После того как мы убедились, что с питанием микросхемы все в порядке, а по интерфейсу I2C идут какие-то данные, но центральный контроллер все равно посылает сигнал сброса, необходимо подключить логический анализатор и убедиться, что все подчиненные микроконтроллеры отвечают на запросы центрального.
Для этого необходимо иметь логический анализатор. Я купил такой на Ozon за примерно 900 рублей. На Алиэкспрессе будет дешевле раза в два 🙂

Для анализа нам потребуется программа Saleae Logic, которую можно скачать с сайта абсолютно бесплатно.
Скачать Saleae Logic
Учтите, что логический анализатор, так же как и большинство программаторов не будет работать от урезанного вывода USB на передней панели компьютера. Я сперва даже подумал, что мне нерабочий продали 🙂 Но подключил сзади напрямую в плату и все заработало.
Теперь подключаем каналы анализатора к выводам микросхемы и запускаем процесс.

Специальные захваты для ножек микросхем с логическим анализаторов в комплекте не идут и я покупал их на Aliexpress. Но можно использовать иглы от BDM рамки, как на первом фото.
Я подключился к соседней микросхеме, так как они работают по одной шине и увидел такую картину в программе анализа.

Как можно видеть справа, обмен данными идет с двумя устройствами с адресами 0x1E и 0x1C. И первое устройство передает какие-то данные, а вот 0x1C не отвечает на запросы управляющего микроконтроллера. Адресацию устройства можно посмотреть в даташите. В моем случае 0x1E это маленький квадратный контроллер, а 0x1C это как раз исследуемый прямоугольный SAA7709H.
! Рекомендую в случае нескольких контроллеров на одной шине подключить захваты на все микросхемы к выводам SDA и SCL и протестировать каждую. Так как при подключении к «неисправной» микросхеме 0x1C я увидел такую картину:

А должно быть вот так:

То есть, по каналу SCL(канал синхронизации, снизу графика) напряжение подается нормально и сигнал проходит. А вот по каналу SDA(сверху) нет нормальной формы сигнала данных. Это означает, что что-то не так с напряжением. Замерил еще раз мультиметром и анализатором до и после резистора и оказалось, что до резистора сигнал приходит нормальный, а после уже неправильный. Проверил резистор, он работает нормально, КЗ нет, сопротивление соответствует маркировке. Пропаял ногу SDA и точку рядом и сигнал начал проходит нормально.
(на этом скрине SCL и SDA были подключены наоборот. SCA теперь снизу, а SCL сверху)

Микросхема начала отвечать на запросы центрального микроконтроллера.
Сигналы RESET перестали поступать и магнитола нормально заработала.
P.S. Подписывайтесь на мой блог, если интересуетесь ремонтом автомобильной электроники 🙂
Расширенные возможности библиотек iarduino для шины I2C.
В данной статье рассматриваются только библиотеки iarduino предназначенные для работы с датчиками и модулями по шине I2C.
Библиотеки iarduino могут использовать как аппаратную, так и программную реализацию шины I2C
При этом выбранный тип реализации шины I2C не влияет на синтаксис функций и методов библиотек iarduino.
При работе с аппаратной шиной I2C, датчики подключаются к заранее указанным на плате (или в документации) выводам, так как прием/передача данных по шине осуществляется на физическом уровне (внутренними блоками микроконтроллера).
При работе с программной шиной I2C, датчики можно подключать к любым выводам, Вы их назначаете сами.
Аппаратная шина I2C:
По умолчанию библиотеки iarduino самостоятельно работают с аппаратной шиной I2C. Датчики подключаются к Arduino используя выводы SDA и SCL (они либо подписаны на плате, либо указаны в документации).
#include // Подключаем библиотеку iarduino_AM2320. iarduino_AM2320 sensor; // Объявляем объект sensor для работы с датчиком AM2320, используя функции и методы библиотеки iarduino_AM2320. // void setup() < // sensor.begin(); // Инициируем работу с датчиком AM2320. Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод. >// // void loop() < // sensor.read(); // Читаем показания датчика. Serial.println(sensor.tem); // Выводим температуру. Serial.println(sensor.hum); // Выводим влажность. delay(1000); // Ждём секунду и повторяем вывод. >//
- Преимущества: Не требуется подключение дополнительных библиотек. Скетч занимает меньше памяти.
- Недостатки: Поддерживаются не все платы.
Аппаратная шина I2C с библиотекой Wire:
Если перед подключением библиотек iarduino подключить библиотеку Wire, то библиотеки iarduino будут использовать методы и функции библиотеки Wire для работы с аппаратной шиной I2C. Датчики подключаются к Arduino используя выводы SDA и SCL (они либо подписаны на плате, либо указаны в документации).
#include // Подключаем библиотеку Wire для работы с шиной I2C. #include // Подключаем библиотеку iarduino_AM2320. iarduino_AM2320 sensor; // Объявляем объект sensor для работы с датчиком AM2320, используя функции и методы библиотеки iarduino_AM2320. // void setup() < // sensor.begin(); // Инициируем работу с датчиком AM2320. Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод. >// // void loop() < // sensor.read(); // Читаем показания датчика. Serial.println(sensor.tem); // Выводим температуру. Serial.println(sensor.hum); // Выводим влажность. delay(1000); // Ждём секунду и повторяем вывод. >//
Код данного примера отличается от предыдущего кода только первой строкой, где подключается библиотека Wire.
- Преимущества: Поддерживается множество плат.
- Недостатки: Требуется больше памяти.
Программная реализация шины I2C:
Если перед подключением библиотек iarduino определить выводы pin_SW_SDA и pin_SW_SCL, то библиотеки iarduino реализуют программную шину I2C на назначенных выводах. Датчики подключаются к Arduino используя любые выводы назначенные Вами как SDA и SCL.
#define pin_SW_SDA 3 // Назначаем вывод D3 Arduino для работы в качестве линии SDA программной шины I2C. #define pin_SW_SCL 9 // Назначаем вывод D9 Arduino для работы в качестве линии SCL программной шины I2C. #include // Подключаем библиотеку iarduino_AM2320. iarduino_AM2320 sensor; // Объявляем объект sensor для работы с датчиком AM2320, используя функции и методы библиотеки iarduino_AM2320. // void setup() < // sensor.begin(); // Инициируем работу с датчиком AM2320. Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод. >// // void loop() < // sensor.read(); // Читаем показания датчика. Serial.println(sensor.tem); // Выводим температуру. Serial.println(sensor.hum); // Выводим влажность. delay(1000); // Ждём секунду и повторяем вывод. >//
Код данного примера отличается от предыдущих только двумя первыми строками в которых назначены выводы для шины I2C.
Указанные Вами выводы будут использованы в качестве линий SDA и SCL шины I2C.
- Преимущества: Возможна работа с модулями I2C на любых выводах Arduino.
- Недостатки: Поддерживаются не все платы.
- Примечание: Библиотеки iarduino не реализуют программную шину I2C для тех модулей с которыми они не работают.
Особенности:
Если перед подключением библиотек iarduino определить выводы pin_SW_SDA, pin_SW_SCL и подключить библиотеку Wire, то модули работающие с библиотеками iarduino будут использовать программную шину I2C на назначенных выводах.
Если до определения выводов pin_SW_SDA и pin_SW_SCL подключить хотя бы одну библиотеку iarduino, то все библиотеки iarduino будут использовать аппаратную шину I2C.
Интерфейсы микроконтроллеров (Часть 2)
Двухпроводной последовательный интерфейс TWI (Two-wire Serial Interface) является полным аналогом базовой версии интерфейса I2C (двухпроводная двунаправленная шина) фирмы Philips. Этот интерфейс позволяет объединить вместе до 128 различных устройств с помощью двунаправленной шины, состоящей из линии тактового сигнала (SCL) и линии данных (SDA).
Двухпроводной интерфейс (TWI) — двунаправленная двухпроводная последовательная шина передачи данных, совместимая со стандартными шинами I2C и SMBus.
Устройство, подключенное к шине, должно быть либо ведущим, либо подчиненным. Ведущее устройство инициирует передачу данных путем передачи адреса подчиненного устройства и типа передачи: чтение или запись. Если к шине подключено несколько ведущих устройств и некоторая их часть одновременно инициировала передачу, применяется механизм арбитража, который учитывает приоритет этих устройств.
Модуль TWI микроконтроллеров может работать и в роли ведущего, и в роли подчиненного устройства. Ведущая и подчиненная работа полностью отделены друг от друга и предусматривают отдельное управление включением/отключением. Для этих функций также предусмотрены отдельные регистры управления и статуса, а также векторы прерываний. Потеря арбитража, ошибки, коллизии и удержание линии синхронизации обнаруживаются на аппаратном уровне и индицируются отдельными флагами статуса для ведущего и подчиненного режимов.
Ведущий модуль содержит программируемый генератор скорости связи. Даже при синхронизации системы низкими частотами, поддерживается возможность работы шины на частоте 100 и 400 кГц. При необходимости автоматического выполнения операций и снижения сложности программы могут быть разрешены команды QUICK и режим SMART.
В подчиненном модуле на аппаратном уровне реализована возможность распознавания 7-битного адреса и адреса общего вызова. Также поддерживается 10-битная адресация. Предусмотренный регистр маски адреса может выступать в роли второго регистра сравнения, если требуется обнаружение двух подчиненных адресов, или регистра маски, если требуется обнаружение адресов, принадлежащих заданному диапазону.
Логика подчиненного модуля продолжает работать во всех экономичных режимах работы МК, в т.ч. POWER DOWN. Благодаря этому, подчиненный модуль способен возобновить активную работу МК при обнаружении совпадения адреса. При необходимости программного слежения за адресами, аппаратную функцию обнаружения совпадения адреса можно отключить. Потребность в этом может возникнуть, когда необходимо обнаруживать несколько различных адресов и реагировать на них. При необходимости автоматического выполнения действий и снижения сложности программы можно задействовать режим SMART.
Модуль TWI содержит логику контроля состояния шины, которая накапливает информацию для обнаружения условий START и STOP, коллизий и ошибок шины. С её помощью можно определить состояние шины в ведущем режиме (IDLE, OWNER, BUSY или UNKNOWN).
При необходимости подключения к внешнему драйверу шины по 4-проводному интерфейсу, внутренние драйверы модуля TWI можно отключить.
Принцип действия шины TWI
Двухпроводной интерфейс (TWI) подключается к простой двухпроводной и двунаправленной шине, которая состоит из двух линий: линия синхронизации (SCL) и линия последовательной передачи данных (SDA). Источниками сигналов для обеих линий являются схемы с открытым коллектором в выходном каскаде (используется принцип «монтажного И»). Для создания высоких логических уровней на линиях шины, в т.ч. когда к шине не подключено ни одно устройство, необходимы подтягивающие к плюсу питания резисторы (Rp) — единственно необходимые внешние компоненты. Альтернативно, вместо подтягивающих резисторов могут использоваться источники тока.
Шина TWI является простым и эффективным средством соединения по последовательной шине нескольких устройств.
Устройство, подключенное к шине, может быть либо ведущим (master), либо подчиненным (slave). Чтобы передача по шине стала возможной, к ней должно быть подключено как минимум одно ведущее устройство.
Топологию шины TWI иллюстрирует рисунок 9.

Каждое подключенное к шине подчиненное устройство должно иметь собственный неповторяющийся адрес, передачей которого ведущее устройство инициирует транзакцию. Могут использоваться 7- или 10-битные адреса. К одной шине допускается подключение нескольких ведущих устройств. Такая шина называется мультимастерной. Для определения, какое из одновременно осуществляющих доступ к шине ведущих устройств имеет приоритет, используется механизм арбитража.
Устройство может содержать, как логику ведущего устройства, так и логику подчиненного устройства. Кроме того, оно может эмулировать работу нескольких подчиненных устройств, путем реагирования на несколько адресов.
Ведущее устройство сигнализирует о начале транзакции генерацией на шине условия START (S). Затем, передается пакет адреса с адресом подчиненного устройства (ADDRESS) и указание желаемого направления передачи данных, т.е. чтение или запись (R/W). По завершении передачи всех пакетов данных (DATA), ведущее устройство генерирует на шине условие STOP (P) и транзакция завершается. После приема каждого байта получатель данных генерирует бит подтверждения (A или ACK) или неподтверждения (/A или NACK).
Транзакция шины TWI показана на рисунке 10.

Сигнал синхронизации транзакции генерирует ведущее устройство, однако, в целях снижения быстродействия шины, любое подключенное к шине устройство может увеличить длительность импульса низкого уровня.
CAN (Control Area Network) — последовательная магистраль, обеспечивающая увязку в сеть «интеллектуальных» устройств ввода/вывода, датчиков и исполнительных устройств некоторого механизма или даже предприятия. Характеризуется протоколом, обеспечивающим возможность нахождения на магистрали нескольких ведущих устройств, обеспечивающим передачу данных в реальном масштабе времени и коррекцию ошибок, высокой помехоустойчивостью. Система CAN обеспечена большим количеством микросхем, обеспечивающих работу подключенных к магистрали устройств, разработку которых начинала фирма BOSH для использования в автомобилях, и в настоящее время широко используемых в автоматизации промышленности.
Предназначен для организации высоконадежных недорогих каналов связи в распределенных системах управления. Интерфейс широко применяется в промышленности, энергетике и на транспорте. Позволяет строить как дешевые мультиплексные каналы, так и высокоскоростные сети.
Скорость передачи задается программно и может быть до 1 Мбит/с. Пользователь выбирает скорость, исходя из расстояний, числа абонентов и емкости линий передачи.
Максимальное число абонентов, подключенных к данному интерфейсу фактически определяется нагрузочной способностью примененных приемопередатчиков. Например, при использовании трансивера фирмы PHILIPS PCA82C250 она равна 110.
Протокол CAN использует оригинальную систему адресации сообщений. Каждое сообщение снабжается идентификатором, который определяет назначение передаваемых данных, но не адрес приемника. Любой приемник может реагировать как на один идентификатор, так и на несколько. На один идентификатор могут реагировать несколько приемников.
Протокол CAN обладает развитой системой обнаружения и сигнализации ошибок. Для этих целей используется поразрядный контроль, прямое заполнение битового потока, проверка пакета сообщения CRC-полиномом, контроль формы пакета сообщений, подтверждение правильного приема пакета данных. Хемминговый интервал d=6. Общая вероятность необнаруженной ошибки 4.7×10-11.
Система арбитража протокола CAN исключает потерю информации и времени при «столкновениях» на шине.
Интерфейс с применением протокола CAN легко адаптируется к физической среде передачи информации. Это может быть дифференциальный сигнал, оптоволокно, просто открытый коллектор и т.п. Несложно делается гальваническая развязка.
Элементная база, поддерживающая CAN, широко выпускается в индустриальном исполнении.
Полная спецификация СAN приведена здесь — www.gaw.ru/data/Interface/CAN_BUS.PDF
Описание интерфейса CAN
Интерфейс CAN предназначен для организации последовательных, высоконадёжных и недорогих каналов связи в распределённых системах управления. Он позволяет организовывать как мультиплексные каналы, так и высокоскоростные сети. Данный интерфейс имеет протокол, поддерживающий возможность нахождения на магистрали нескольких ведущих устройств и обеспечивает передачу данных в реальном масштабе времени.
Интерфейс обладает высокой помехоустойчивостью благодаря коррекции ошибок. Передача данных осуществляется кадрами, которые принимаются всеми устройствами сети. Кадр состоит из идентификатора длиной 11 бит для стандартного формата или 29 бит для расширенного формата и блока данных, содержащего от 0 до 8 байт. Идентификатор описывает содержимое пакета данных и служит для определения приоритета при по¬пытке одновременной передачи несколькими устройствами.
Скорость передачи данных выбирается исходя из расстояния, числа абонентов в сети и ёмкости линии связи. Она задаётся программно и может составлять от десятка Кбод до единиц Мбод.
Стандарт интерфейса CAN определяет передачу данных независимо от физического уровня, т.е. канал связи может быть каким угодно, например, радиоканалом или оптоволокном. Однако на практике под CAN-интерфейсом обычно подразумевается сеть с физическим каналом связи в виде дифференциальной пары проводов, определённым в стандарте ISO 11898. На рисунке 11 приведена схема подключения устройств к интерфейсу CAN.

Стандартное назначение выводов для широко распространённого 9-контактного разъёма интерфейса CAN приведено на рисунке 12.

Интерфейс CAN относится к типу сетей CR (Collision Resolution, разрешение коллизий), в отличие от сетей типа CD (Collision Detect, обнаружение коллизий), например Ethernet. Тип сетей CR обеспечивает приоритетный доступ к передаче сообщения, что необходимо для промышленных устройств.
Приоритетный доступ к передаче сообщений в стандарте ISO-11898 реализуют так называемые рецессивные и доминантные биты. В зависимости от типа шины, объединяющей устройства CAN, эти биты могут принимать значение лог. 0 либо лог. 1. В таблице приведены два примера организации шин, поясняющие образование управляющих битов.

Спецификация интерфейса CAN избегает описания двоичных значений сигналов, как лог. 0 либо лог. 1, с целью абстрагирования от среды передачи. Именно поэтому вместо них применяются термины «рецессивный» и «доминантный» биты. При этом подразумевается, что при передаче одним устройством сети рецессивного бита, а другим доминантного, принят будет доминантный бит. Например, при реализации физического уровня с помощью радиоканала отсутствие сигнала означает рецессивный бит, а наличие сигнала — доминантный.
Стандарт сети требует от физического уровня передачи, чтобы доминантный бит мог подавить рецессивный, но не наоборот. Например, в оптическом волокне доминантному биту должен соответствовать свет, а рецессивному — его отсутствие. В электрическом проводе рецессивное состояние соответствует высокому потенциалу на линии связи, а доминантное — низкому потенциалу, т.е. когда устройство подключает линию связи к нулевому потенциалу. Если линия находится в рецессивном состоянии, перевести её в доминантное состояние может любое устройство сети, например, включив свет в оптоволокне.
Кадры и их форматы
Кроме рецессивного и доминантного битов, стандарт интерфейса CAN оперирует таким понятием, как кадр, который используется в протоколе обмена информацией между устройствами. Каждый кадр представляет собой единый набор нескольких служебных битов и байтов. Существуют следующие виды кадров:
• кадр данных (data frame) служит для передачи данных;
• кадр запроса передачи (remote frame) служит для запроса на передачу кадра данных с тем же идентификатором;
• кадр перегрузки (overload frame) обеспечивает промежуток между кадрами данных или кадрами запросов;
• кадр ошибки (error frame) передаётся узлом, обнаружившим ошибку.
В таблицах ниже представлены базовый формат и расширенный формат кадра данных.


Графическое представление данных кадров, с пояснениями и порядком сле¬дования бит, приведено на рисунках 13 и 14 соответственно. Межкадровый ин¬тервал служит для разделения кадров между собой и состоит как минимум из трёх рецессивных бит. Он необхо¬дим передающему устройству для под¬готовки очередного кадра.


Арбитраж доступа к шине
При наличии в сети нескольких устройств, которые могут формировать запросы, в ней могут возникать конфликтные ситуации, когда эти запросы выставляются одновременно. С целью устранения подобных коллизий в интерфейсе CAN предусмотрен механизм арбитража доступа к шине. Когда шина свободна, любое устройство может начинать передачу в любой момент. В случае одновременной передачи кадров двумя и более устройствами производится арбитраж: передавая биты идентификатора, устройство одновременно проверяет состояние шины. Если при передаче очередного бита на шине присутствует противоположный бит, считается, что другое устройство передаёт сообщение с более высоким приоритетом, и передача откладывается до освобождения шины.
Таким образом, в отличие, например, от сети Ethernet, в сети CAN не происходит непроизводительной потери пропускной способности канала при коллизиях. Однако при этом не исключена вероятность того, что сообщения с низким приоритетом никогда не будут переданы.
Защита информации от ошибок
Интерфейс CAN имеет несколько механизмов контроля и предотвращения ошибок. Благодаря арбитражу доступа к шине, производится контроль передачи информации, поскольку при передаче битовые уровни в сети сравниваются с передаваемыми битами
Кроме того, интерфейс CAN использует для защиты информации от ошибок контрольную сумму. Каждый раз при передаче информации, передающее устройство вычисляет контрольную сумму пакета данных и добавляет её в передаваемый кадр. Устройство, принимающее информацию, вычисляет контрольную сумму принимаемого кадра и сравнивает её с контрольной суммой принятого кадра. В случае совпадения контрольных сумм устройство передаёт доминантный бит в промежутке подтверждения.
После передачи пяти одинаковых битов подряд передаётся дополнительный бит противоположного значения — так называемый бит-вставка (bit stuffing), который позволяет защититься от сбоя синхронизации устройств при передаче данных, состоящих из одного и того же двоичного кода.
Упомянутые выше механизмы позволяют обеспечить передачу информации с вероятностью пропуска ошибки 4,7 х 10^-11.
Технические характеристики шины
Все устройства в сети CAN должны работать с одинаковой скоростью. Стандарт CAN не определяет скорость работы, но большинство как самостоятельных, так и встроенных в МК контроллеров CAN позволяют плавно изменять скорость в диапазоне от 20 Кбит/с до 1 Мбит/с. Существуют также решения, выходящие далеко за рамки данного диапазона.
Приведённые выше методы защиты информации от ошибок требуют, чтобы изменение бита при передаче успело распространиться по всей сети к моменту контроля его состояния передатчиком. Это приводит к обратной зависимости длины шины от скорости передачи: чем больше скорость пере¬дачи информации, тем меньше должна быть длина шины. Соотношения скорости передачи и длины шины для сетей стандарта ISO 11898 приведены в таблице.

На скорость передачи информации и длину шины также оказывает влияние использование оптических пар для защиты устройств от высоковольтных помех. Снижают скорость передачи информации и сильно разветвлённые сети в виде паутины, из-за множества отражений сигнала и большой электрической ёмкости шины.
I²C — Inter-Integrated Circuit, краткое руководсто
I²C (и-квадрат-це, ай-ту-си, ай-сквэрд-си), Inter-Integrated Circuit — последовательная шина обмена данными между интегральными схемами. Изобретена и в начале 80-х компанией Philips Semiconductor (теперь NXP), передача данных осуществляется по двум проводам в обе стороны. Ведущий и ведомый могут выполнять как роль приёмника, так и передатчика. Для возможности соединения более двух устройств используются адресация. Опрашивать адреса шины может только ведущий. Адрес последовательно выводится на линию SDA сразу после сигнала Start. В этой статье речь пойдёт только о 7-ми битной адресации, так же не будет затронута тема нескольких ведущих. На каждом устройстве, поддерживающем I²C обычно обозначены два вывода: SDA и SCL. SDA (serial data) — означает последовательные данные, SCL (serial clock) — последовательное тактирование. Эти выводы являются выводами открытого коллектора или открытого стока, это означает что ведущий и ведомый могут только притягивать электрический потенциал к земле, поэтому на каждой линии должны быть подтягивающие резисторы. Сопротивление резисторов рассчитывается в зависимости от паразитной ёмкости линии.
Подключение:
Шина поддерживает подключение до 112 устройств (при 7-ми битной адресации) по двум проводам (плюс GND и Vcc), может иметь несколько ведущих и ведомых. При использовании нескольких ведущих, каждый из них должен поддерживать этот режим и уметь определять состояние занятой шины.
I²C на Arduino
Arduino UNO R3/Piranha UNO
На Arduino UNO R3/Piranha UNO шина I2C находится на выводах A4, A5. Также в эти выводы продублированы на колодке с цифровыми выводами рядом с кнопкой Reset.

Piranha ULTRA
На Piranha ULTRA шина I²C не занимает аналоговые выводы A4, A5 и находится на цифровой колодке рядом с кнопкой Reset, выводы обозначены SDA и SCL

Arduino MEGA R3
На Arduino MEGA R3 шина I²C находится на цифровой колодке на крайних выводах, близких к разъёму USB и на выводах 20, 21. Выводы объединены.

Примеры для Arduino
Работа с шиной с использованием встроенной библиотеки Wire Arduino IDE на примере Trema-модуля LED Матрицы 8×8 — i2c
#include // Подключаем библиотеку Wire для работы с шиной I2C. const int ADDRESS = 0x09; // Определяем адрес ведомого const int REG_DATA = 0x10; // Определяем адрес регистра REG_DATA. const int REG_ROW_1 = 0x11; // Определяем адрес регистра ROW_1. byte IMAGE[8] = ; // void setup() < // Wire.setClock(100000L); // Устанавливаем скорость передачи данных по шине I2C. Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера. delay(500); // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write(REG_ROW_1); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра ROW_1. Wire.write(IMAGE, 8 ); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это 8 байт массива IMAGE. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. >// // void loop()< // // >
В этом примере на матрицу выводится изображение стрелки. Стоит заметить, ко всем нашим модулям написаны библиотеки с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке.
I²C на Raspberry Pi
На Raspberry Pi I²C выводы это 3-й и 5-й выводы колодки, GPIO2 и GPIO3 по номенклатуре BCM и выводы 8, 9 по номенклатуре WiringPi.

Примеры для Raspberry
Работа с шиной с использованием модуля smbus для Python на примере Trema-модуля Матрицы 8×8 — i2c. Для работы с шиной её необходимо включить в настройках Raspberry при помощи утилиты raspi-config . Ссылка на подробное описание как это сделать.
# Импортируем модуль Python import smbus # Создаём объект для работы с шиной # 0: "/dev/i2c-0", 1: "/dev/i2c-1" bus = smbus.SMBus(1) # Адрес ведомого на шине ADDRESS = 0x09; # Регистр первого ряда светодиодов матрицы REG_ROW_1 = 0x11; # Список с изображением стрелки в двоичной записи IMAGE = [ 0b00000000, 0b00011000, 0b00111100, 0b01111110, 0b00011000, 0b00011000, 0b00011000, 0b00000000, ] # Команда вывода данных на шину. bus.write_i2c_block_data(ADDRESS, REG_ROW_1, IMAGE)
Так же как и в примере с Arduino, в этом примере на матрицу выводится изображение стрелки. Стоит заметить, к Trema-модулю LED Матрица 8×8 — i2c написана библиотека с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке
Подробнее о шине I²C:
Резисторы, ёмкость и длина линий шины
В официальном описании от NXP ничего не сказано о максимальной длине шины, но не стоит этим злоупотреблять. Шина была придумана для обмена информации между интегральными схемами в пределах одной платы одного устройства. В расчёт бралась только паразитная ёмкость линии, которая сказывается на скорости нарастания фронта волны. От этой ёмкости зависит номинал подтягивающих резисторов. Можно подобрать резисторы так, чтобы фронт волны нарастал согласно спецификации и при 100-метровой длине проводов, но это не избавляет от помех, которые влечёт за собой несимметричная электрическая реализация. Опять же, при слишком маленьком сопротивлении качество сигнала улучшается, но при этом растёт ток который необходимо пропускать устройствам через выводы для притяжки линий.
При использовании шины на модулях не существует принятого стандарта установки подтягивающих резисторов на ведущем или ведомом. У Arduino подтягивающие резисторы отсутствуют и для работы с шиной нужен хотя бы один модуль с ними. У Raspberry Pi на плате установлены подтягивающие резисторы номиналом 1,7 килоОм и для неё нет необходимости в подтяжке на модулях.
Сигналы и специальные биты шины
В состоянии покоя линии шины находятся на верхнем потенциале (обычно 3,3 В или 5 В, но могут быть и другие напряжения). Бездействие устройства, по умолчанию, воспринимается как логическая 1. Для простоты понимания можно рассмотреть аналогию: Вообразим верхний потенциал как уровень воды, а нижний как дно. Представьте, что Вы на рыбалке — попловок в состоянии покоя остаётся на поверхности, когда клюёт — идёт ко дну. Так же и в здесь, при обмене данными линии прижимаются в нулевому потециалу. Далее рассмотрим поочереди сингалы и специальные биты.
Устанавливаемые только ведущим
- Start — сигнал начала обмена данными. Линия тактирования SCL отпущена (логическая 1), ведущий пижимает линию данных SDA (переход из логической 1 в логический 0). После этого обмен данными происходит побайтово. Первый байт — семь бит адреса ведомого и бит направления (запись или чтение). Последующие байты — данные. после этого сигнала шина считается занятой.
Краткое обозначание сигнала S — заглавная буква S латинского алфавита.
SDA (данные) S, биты: 1 2 3 4 5 6 7 R/W̅ ___________________ _____ _____ _____ _____ _____ _____ _____ _____ ___ \____/_____X_____X_____X_____X_____X_____X_____X_____\_______/ SCL (такт.) | ______________________ __ __ __ __ __ __ __ __ __ ____ | \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ | Start: переход SDA из 1 в 0, линия SCL отпущена
- Бит Read — Если ведущий желает получить данные, он устанавливает логическую 1 сразу после адреса, информируя ведомого о том, что данные будут считываться (управление линией данных передаётся ведомому).
Краткое обозначание R — заглавная буква R латинского алфавита.
SDA (данные) S, биты: 1 2 2 4 5 6 7 R ___________________ _____ _____ _____ _____ _____ _____ _____ _____ ___ \____/_____X_____X_____X_____X_____X_____X_____/ | \_______/ SCL (такт.) | ______________________ __ __ __ __ __ __ __ __ __ ____ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/| \__/ \__/ | Read: после 7-бит адреса линия SDA отпущена
- Бит Write — Если ведущий желает записать данные, он устанавливает логический 0 сразу после адреса для информирования ведомого о том что данные будут записываться (управление линией данных остаётся у ведущего).
Краткое обозначение W̅ — заглавная буква W латинского алфавита с чертой сверху.
SDA (данные) S, биты: 1 2 3 4 5 6 7 W̅ ___________________ _____ _____ _____ _____ _____ _____ _____ ___ \____/_____X_____X_____X_____X_____X_____X_____\_____________/ SCL (такт.) | ______________________ __ __ __ __ __ __ __ __ __ ____ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/| \__/ \__/ | Write: после 7-бит адреса линия SDA прижата
- Stop — сигнал окончания обмена данными. Ведущий прекращат тактирование, линия тактирования SCL отпущена (логическая 1), линия данных SDA переведена ведущим из логического 0 в логическую 1. После этого сигнала шина считается свободной.
Краткое обозначение P — заглавная буква P латинского алфавита.
SDA (данные) A . байт.данных. A P _ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ ___ _X_____X_____X_____\____/_____X_____X_____X_____X_____X_____X_____X_____\_______/ SCL (такт.) | __ __ __ __ __ __ __ __ __ __ __ __ __ ____ _/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/| | Stop: переход SDA из 0 в 1, линия SCL отпущена
- Restart — сигнал продолжения обмена данными (используется взамен сигналу Stop с последующим Start для продолжения опрашивания шины ). Используется в основном при наличии нескольких ведущих на шине, чтобы управление не перешло другому ведущему после сигнала Stop. Линия тактирования SCL отпущена ведущим, линия данных SDA переведена ведущим из логической 1 в логический 0.
Обозначается Sr — заглавная буква S и строчная буква r латинского алфавита.
SDA (данные) A . биты данных. A Sr _ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ __ _X_____X_____X_____\____/_____X_____X_____X_____X_____X_____X_____X_____\_____/ \__ SCL (такт.) | __ __ __ __ __ __ __ __ __ __ __ __ __ ____ _/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ | | Restart: переход SDA из 1 в 0, линия SCL отпущена
Устанавливаемые ведущим и ведомым
Данные биты может устанавливат как ведущий, так и ведомый. В такой ситуации устанавливающее устройство или модуль (ведущий или ведомый) называют передатчиком, а считывающее устройство — приёмником.
- Бит ACK — (сокращ. англ. acknowledged — подтверждено) каждый девятый импульс тактирования передатчик (ведущий или ведомый) отпускает линию данных. Если линия была прижата приёмником (логический 0) — принятые данные верны, передача может быть продолжена или закончена.
Обозначается A — заглавная буква A латинского алфавита
SDA (данные) A . биты данных. A _ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ __ _X_____X_____X_____\____/_____X_____X_____X_____X_____X_____X_____X_____\_____/ \__ SCL (такт.) | | __ __ __ __ __ __ __ __ __ __ __ __ __ ____ _/ \__/ \__/ \__/ |\__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/| \__/ | | ACK: девятый импульс тактирования --------------------------^ линия SDA прижата ведомым (логический 0)
- Бит NACK — (сокращ. англ. not acknowledged — не подтверждено) каждый девятый импульс тактирования передатчик (ведущий или ведомый) отпускает линию данных. Если линия была отпущена принимающим или принимающего нет на шине (логическая 1) — принятые данные неверны, произошла ошибка, передача не может быть продолжена. Обозначается A̅ — заглавная буква A латинского алфавита с чертой сверху.
SDA (данные) S . биты данных или адреса. A̅ S ___________________ _____ _____ _____ _____ _____ _____ _____ _____ ____ _ \____/_____X_____X_____X_____X_____X_____X_____X_____/ | \____/ SCL (такт.) | ______________________ __ __ __ __ __ __ __ __ __ ____ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/| \__/ | NACK: девятый импульс тактирования линия SDA отпущена принимающим (логическая 1)
Обмен данными
При обмене данными тактированием занимается только ведущий, а ведомый может удерживать линию тактирования только если не успевает за ведущим, так называемое растягивание тактирования (clock-stretching). Не все модули поддерживают удержание. Установка бита на линии данных может происходит в момент, когда линия тактирования прижата, а считывания, когда линия отпущена (подтянута к Vcc), но в большинстве случаев это происходит по фронту волны на линии тактирования.
SDA (данные) ___________________ _____ _____ _____ _____ _____ _____ _____ _____ ___ \____/_____X_____X_____X_____X_____X_____X_____X_____\_______/ SCL (тактирование) | | ______________________ | __ __ __ __ __ __ __ __ __ ____ \__/ |\__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ | | | | | Считывание Установка
Рассмотрим пример простого обмена данными:
Запись в регистры ведомого. Данные взяты из примеров, приведённых выше.
S | 0x09 | W̅ | A | 0x11 | A | 0x00 | A |0x18|A|0x3C|A|0x7E|A|0x18|A|0x18|A|0x00|A| P | | | | | | | | | | Адрес | Подтв. | Подтв. | . | | | | | | Старт Запись Регистр Данные Стоп
После сигнала Start и указания адреса ведущий записывает адрес регистра с которого будет производиться дальнейшая запись. Стоит заметить, что у ведомого есть внутренний счётчик и каждый последующий байт после подтверждения будет записан в следующий регистр. Таким образом байт со значением 0x00 будет записан в регистр 0x11, байт со значением 0x18 будет записан в регистр 0x12, байт со значением 0x3C будет записан в регистр 0x13 и т. д. В этом примере биты ACK устанавливает ведомый.
Вот так сигналы этого примера выглядят на осциллографе:

- Канал 1 — тактирование (SCL)
- Канал 3 — данные (SDA)
- Линия B1 — декодирование данных осциллографом
Чтение из регистров ведомого. Предположим, мы хотим прочитать байт из регистра 0x13.
S | 0x09 | W̅ | A | 0x13 | Sr | 0x09 | R | A | 0x3C | A | P | | | | | | | | | | | | | Адрес | Подтв. | Рестарт | Чтение | Данные | Стоп | | | | | | Старт Запись Регистр Адрес Подтв. Подтв. ведущим
После сигнала Start и указания адреса ведущий записывает адрес регистра, который необходимо прочитать. Далее следует сигнал Restart (или Stop, затем Start). Ведущий снова выводит адрес ведомого, но уже с битом Read (чтения). Ведомый устанавливает бит ACK и во время следующих 8-ти импульсов тактирования выводит данные на линию SDA. На девятом импульсе уже ведущий устанавливает бит ACK (или NACK, если данные не удалось прочитать) и завершает обмен сигналом Stop.
Скорость
Первоначальный стандарт I²C был реализован на скорости 100 кГц. С тех пор появились и другие реализации шины, но большинство устройств работают на этой скорости. Так же известны случаи когда скорость шины специально снижена, чтобы увеличить расстояние передачи и уменьшить чувствительность к помехам. Не все модули могут работать на сниженной скорости.
Ссылки
- Официальное описание шины на сайте NXP (на английском)
- Модули I²C в магазине iarduino.ru
- Урок — узнаём адреса на шине I²C
- Урок — соединяем две Arduino по шине I²C
- Wiki — Raspberry Pi включаем I²C, SPI