На устройство hid на шине i2c что это значит

Обновлено: 08.07.2024

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

Одним из преимуществ устройств USB HID является то, что операционная система поставляется с драйверами HID, и пользователям не нужно разрабатывать драйверы, если они используют системные вызовы API для завершения взаимодействия.

Он содержит две наиболее важные инструкции:

1. 《Device Class Definition for human interface device (HID)》

2. 《Universal Serial Bus HID Usage Tables》

Документ 1 описывает базовый состав и формат HID, а документ 2 является дополнением к документу 1, в котором перечислены основные компоненты различных устройств HID.

Основываясь на введении базового протокола USB в предыдущей главе, в этой главе основное внимание уделяется классам взаимодействия человека и компьютера HID. (Базовый протокол USB-связи доступен по умолчанию)

2.1 Канал связи USB HID устройства

Все устройства HID связываются с хостом через канал управления USB (канал по умолчанию, конечная точка 0) и канал прерывания (конечная точка 1 или конечная точка 2).

Описание запроса конвейера

Выход прерывания Дополнительно Передача выходных данных с хоста на устройство

Конвейер управления в основном используется в следующих трех аспектах

  • Получение / ответ на запрос управления USB-хостом и связанные данные
  • Передавать данные, когда USB-хост запрашивает (например, отвечает на запрос Get_Report и т. Д.)
  • Получать данные с USB-хоста

Конвейер прерывания в основном используется в следующих двух аспектах

  • USB-хост получает данные асинхронной передачи от USB-устройства
  • USB-хост отправляет данные в реальном времени на USB-устройство.

Передача выходных данных прерывания от USB-хоста к USB-устройству является необязательной.Когда выходные данные прерывания не поддерживаются, USB-хост передает данные на USB-устройство через канал управления.

2.2 Дескрипторы, относящиеся к USB HID устройствам

В дополнение к пяти стандартным дескрипторам USB (дескриптор устройства, дескриптор конфигурации, дескриптор интерфейса, дескриптор конечной точки, строковый дескриптор), дескрипторы устройства HID также включают три дескриптора, зависящих от класса устройства HID: Дескриптор HID, дескриптор отчета (Отчет), дескриптор объекта (Физический) 。

Иерархическая взаимосвязь между ними показана на рисунке:


Можно видеть, что на уровне Interface desc указано HID desc.

В дополнение к трем конкретным дескрипторам HID, которые составляют интерпретацию устройств HID, к устройствам HID относятся пять стандартных дескрипторов:

  1. Дескриптор устройства : bDeviceClass, bDeviceSubClass, bDeviceProtocolТри значения должны быть 0
  2. Дескриптор интерфейса : bInterfaceClass Значение должно быть 0x03,bInterfaceSubClass Имеет значение 0 или 1 , 1 указывает, что HID-устройство является загрузочным устройством (BootDevice, обычно значимым для ПК, что означает, что BIOS может распознать HID-устройство, которое вы используете при загрузке, и только стандартную мышь или клавиатуру можно назвать BootDevice), 0 указывает устройство HID. Операционная система может распознавать используемое устройство только при загрузке. bInterfaceProtocol Смысл значения следующий:

0 — No Sub Class

1 — Boot Interface SubClass

2.2.1 Дескриптор HID

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

Дескриптор HID
Смещение площадь Размер (байт) ценность описание
0 bLength 1 цифровой Длина этого дескриптора в байтах
1 bDescriptorType 1 постоянный Тип дескриптора (здесь 0x21 Категория HID)
2 bcdHID 2 цифровой Номер версии спецификации HID (код BCD) с использованием 4-х шестнадцатеричных кодов формата BCD
4 bCountryCode 1 цифровой Идентификационный код страны назначения оборудования
5 bNumDescriptors 1 цифровой Количество поддерживаемых вспомогательных дескрипторов
6 bDescriptorType 1 постоянный Типы дескрипторов, связанных с HID, см. В таблице ниже
7 wDescriptorLength 2 цифровой Сообщите общую длину дескриптора
9 bDescriptorType 1 постоянный Константа, используемая для определения типа дескриптора, используйте устройство с более чем одним дескриптором
10 wDescriptorLength 2 цифровой Общая длина дескриптора, используемого в устройствах с более чем одним дескриптором.
Определение типа дескриптора, связанного с HID

Тип дескриптора, связанный с HID

В стандартном запросе USB, когда используется дескриптор конфигурации get, он будет возвращен в следующем порядке, то есть дескриптор HID также будет возвращен.


Дескриптор HID также содержит тип и длину присоединенного к нему дескриптора (например, дескриптора отчета), а затем хост запрашивает соответствующий дескриптор на основе информации в дескрипторе HID. Другими словами, хост знает, что устройство является HID-устройством, получая дескриптор.

Обычно в процессе запроса дескрипторов конфигурации и получения всех дескрипторов выбирают " Class 0x01 ”:



Значение Request - это содержание выше.

2.2.2 Дескриптор отчета

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

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

Чтобы понять дескриптор отчета, необходимы два официальных USB HID-данных:

《Device Class Definition for human interface device (HID)》

《Universal Serial Bus HID Usage Tables》

Один - это протокол, описывающий дескриптор HID, а другой - определение содержания дескриптора отчета HID.

Дескриптор отчета состоит из одного элемента. Элемент делится на два типа. Имеются следующие форматы:

1. Short Item


2. Long Item


Из вышеперечисленного здесь в основном речь идет оShort Item, Наиболее используемым является Short Item 。

Короче говоря, первый 1 байт представляет цель этого элемента:


bSize: представляет следующие данные размером до 4 байтов.

bType: показывает, какой тип элемента является данным элементом. Существует три основных типа: основной (0x00), глобальный (0x01) и локальный (0x02).

bTag: представляет более подробную классификацию по соответствующему элементу.

| —— Основное разделено на: ввод, вывод, функция, коллекция, конечная коллекция.

| —— Глобальное разделение на: страницу использования, логический минимум, логический максимум и т. Д.

| —— Локальное разделение на: использование, минимум использования, максимум использования, строку и т. Д.

ДляbSize + bType + bTag Комбинация из 1 байта показана в таблице ниже:


В таблице перечислены все взаимодействия. Знак "?" Представляет значение младших 4 битов. Например, короткий элемент:

0x05(Prefix), 0x01(Data) , // USAGE_PAGE (Generic Desktop)

Среди них 0x05 представляет префикс, а 0x01 - часть данных.

0x05 =》 0000 01 01 Можно разбить:bSize = 1;bType = 1(Global);bTag = 0(Usage Page)

Приведенная выше интерпретация исходит из 《Device Class Definition for human interface device (HID)》 Файл, следующий за 0x01 Это 1 байт данных. Необходимо выяснить конкретное значение этих данных:《Universal Serial Bus HID Usage Tables》 Может быть найдено в, что означает: Generic Desktop 。


То есть согласно [bSize + bType + bTag】 Информация знает конкретное значение тега. Комбинируя таблицу таблицы и конкретный тег, найдите соответствующее значение следующих данных, чтобы достичь цели интерпретации дескриптора отчета.

Разберем функцию и значение нескольких важных тегов.

Main

| —— Ввод: указывает режим ввода данных о работе устройства на хост. Этот формат данных формирует входной отчет.Хотя входной отчет может быть передан конвейером управляющего типа с получением отчета (входом), он обычно передается входным конвейером типа прерывания, чтобы гарантировать, что обновленный входной отчет может быть передан в каждый фиксированный период. Передайте хосту.

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

| —— Функция: указывает формат данных конфигурации, требуемых хостом для отправки на устройство. Этот образец данных формирует характерный отчет. Отчет о функциях может использовать конвейер управления только для получения и установки значения функции устройства с помощью команд получить отчет (функция) и установить отчет (функция) соответственно.

No Null Position

Данные / константа: данные основного элемента представляют собой значение переменной (установленное на Data) или фиксированное неизменяемое значение (установлено на Constant). Константы используются в отчете Feature или используются для заполнения, поэтому длина отчета указывается в байтах.

Абсолютный / Относительный: данные основного элемента предоставляют абсолютные значения относительно фиксированной контрольной точки (установленной на Абсолютный) или предоставляют относительные значения относительно предыдущего отчета (установленный на Относительный).

Без переноса / переноса: когда значение данных основного элемента достигает экстремального значения, оно переключается на чрезвычайно низкое значение, и наоборот, что называется намоткой (установлено значение Wrap). Например, поворотную ручку можно повернуть на 360 °, а выходное значение находится в диапазоне от 0 до 10. Если установлено значение Wrap, значение достигает 10, а значение становится 0, если она вращается в том же направлении. В противном случае, если он достигнет 0, поверните его снова, чтобы получить 10.

Линейный / Нелинейный: данные основного элемента и шкалы операций являются линейными (для параметра "Линейный") или нелинейными (для параметра "Нелинейный").

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

Нет нулевой позиции / нулевое состояние: операция, соответствующая основному элементу, имеет состояние, при котором значимые данные не будут отправляться, то есть данные не будут находиться между логическим минимумом и логическим максимумом. Этот вид манипуляции должен быть отмечен как нулевой. Состояние, иначе это не нулевая позиция. Например, если имеется несколько клавиш, но в столбце Использование не указано, что ни одна клавиша не нажата, вы можете установить нулевое состояние в данных основного элемента, чтобы исключить состояние отсутствия нажатой клавиши из логического элемента. Минимальный и логический максимальный диапазон, см.Universal Serial Bus HID Usage Tables Пример в Приложении A.3 документа.

Non Volatile / Volatile: Данные основного элемента Feature не могут быть изменены хостом (установлен на Non Volatile) или разрешены для изменения хостом (установлен на Volatile). Обратите внимание на основные пункты Input и Output, эта установка метки бессмысленна, поэтому код бита 7 должен быть 0.

Битовое поле / буферизованные байты: формат данных основного элемента должен быть в байтах.Если этого недостаточно для формирования байтов, он будет автоматически заполнен байтами, затем установите буферизованные байты.

Сбор и завершение сбора. В случае с мышью, это фактически указатель, который используется только как компьютерная мышь; и этот указатель содержит три кнопки и две оси перемещения X и Y. Следовательно, отчет указателя состоит из данных в разных форматах, поэтому необходимо использовать Сборник и Завершить сборник, чтобы сгруппировать несколько элементов ввода в группу, которая используется в качестве указателя, а затем использовать Сбор и Завершить сборку, чтобы заключить указатель. чтобы указать, что он используется как мышь. Метка тома End Collection не соответствует никаким данным. Но метка тома Collection следует за одним байтом данных.Например, имя данных указателя - Physical, а данные мыши - Application. Имена данных и коды всех Коллекций показаны в таблице:

В предыдущей статье на нашем сайте мы рассмотрели использование интерфейса SPI в плате Arduino. А здесь мы рассмотрим еще один очень популярный в настоящее время протокол последовательной связи I2C (Inter Integrated Circuits - последовательная шина обмена данными между интегральными схемами ) и как его использовать в плате Arduino. Если сравнивать протоколы I2C и SPI, то I2C использует только 2 линии (провода), а SPI использует 4 линии, I2C может иметь несколько ведущих (Master) и несколько ведомых (Slave), а SPI может иметь только одного ведущего и нескольких ведомых. То есть если в вашем проекте сразу несколько микроконтроллеров должны быть ведущими, то тогда вам нужно использовать интерфейс (протокол) I2C. Протокол I2C обычно используется для взаимодействия с гироскопами, акселерометрами, датчиками давления, LED дисплеями и т.д.

Внешний вид проекта использования интерфейса I2C в Arduino

В этом проекте мы будем использовать протокол I2C для обмена данными между двумя платами Arduino и передавать между ними значения (от 0 до 127) с помощью потенциометра. Эти принятые значения будут отображаться на ЖК дисплеях, подключенных к каждой плате Arduino. Одна из плат Arduino будет выступать в роли ведущего (Master), а другая – в роли ведомого (Slave).

Что такое протокол I2C и как он работает

Термин IIC расшифровывается как “Inter Integrated Circuits” и часто обозначается как I2C или даже как TWI (2-wire interface protocol), но во всех случаях за этими обозначениями скрывается один и тот же протокол. I2C представляет собой протокол синхронной связи – это значит что оба устройства, которые обмениваются информацией с помощью данного протокола должны использовать общий сигнал синхронизации. Поскольку в этом протоколе используются всего 2 линии (провода), то по одной из них должен передаваться сигнал синхронизации, а по другой – полезная информация.

Впервые протокол I2C был предложен фирмой Phillips. Протокол в самом простом случае соединяет с помощью 2-х линий 2 устройства, одно из устройств должно быть ведущим, а другое – ведомым. Связь возможна только между ведущим и ведомым. Преимуществом протокола (интерфейса) I2C является то, что к одному ведущему можно подключить несколько ведомых.

Схема связи с помощью протокола I2C представлена на следующем рисунке.

Схема связи с помощью протокола I2C

Назначение линий данного интерфейса:

  • Serial Clock (SCL): по ней передается общий сигнал синхронизации, генерируемый ведущим устройством (master);
  • Serial Data (SDA): по ней осуществляется передача данных между ведущим и ведомым.

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

Уровни напряжений для передаваемых сигналов в интерфейсе I2C жестко не определены. В этом плане I2C является достаточно гибким, то есть если устройство запитывается от напряжения 5v, оно для связи с помощью протокола I2C может использовать уровень 5v, а если устройство запитывается от напряжения 3.3v, то оно для связи с помощью протокола I2C может использовать уровень 3v. Но что делать если с помощью данного протокола необходимо связать между собой устройства, работающие от различных питающих напряжений? В этом случае используются преобразователи/переключатели напряжения (voltage shifters).

Существует несколько условий для осуществления передачи данных в протоколе I2C. Инициализация передачи начинается с падения уровня на линии SDA, которое определяется как условие для начала передачи (‘START’ condition) на представленной ниже диаграмме. Как видно из этого рисунка, в то время как на линии SDA происходит падение уровня, в это же самое время на линии SCL ведущий поддерживает напряжение высокого уровня (high).

Принцип передачи данных в протоколе I2C

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

Аналогичным образом, повышение уровня на линии SDA останавливает передачу данных, что на представленной диаграмме обозначено как условие окончания передачи данных (‘STOP’ condition). В это же самое время ведущим на линии SCL поддерживается напряжение высокого уровня (high).

На следующем рисунке представлена структура адреса ведомого в протоколе I2C.

Структура адреса ведомого в протоколе I2C

Бит R/W показывает направление передачи следующих за ним байт, если он установлен в HIGH – это значит что будет передавать ведомый (slave), а если он установлен в low – это значит что будет передавать ведущий (master).

Каждый бит передается в своем временном цикле, то есть нужно 8 временных циклов чтобы передать байт информации. После каждого переданного или принятого байта 9-й временной цикл используется для подтверждения/не подтверждения (ACK/NACK) приема информации. Этот бит подтверждения (ACK bit) формируется либо ведомым, либо ведущим в зависимости от ситуации. Для подтверждения приема информации (ACK) на линии SDA ведущим или ведомым устанавливается низкий уровень (low) в 9 временном цикле, в противном случае происходит не подтверждение приема информации (NACK).

Где применяется протокол I2C

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

Протокол I2C в Arduino

На следующем рисунке показаны контакты платы Arduino UNO, которые используются для связи по протоколу I2C.

Контакты платы Arduino UNO, которые используются для связи по протоколу I2C

Значение типа дескриптора
Линия протокола I2C Контакт платы Arduino UNO
SDA A4
SCL A5

Для осуществления связи по протоколу I2C в плате Arduino используется библиотека . В ней содержатся следующие функции для связи по протоколу I2C.

1. Wire.begin(address).

Эта команда производит инициализацию библиотеки Wire и осуществляет подключение к шине I2C в качестве ведущего (master) или ведомого (slave). 7-битный адрес ведомого в данной команде является опциональным и если он не указан [Wire.begin()], то устройство (плата Arduino) подключается к шине I2C в качестве ведущего (master).

2. Wire.read().

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

3. Wire.write().

Эта функция используется для записи данных в устройство, являющееся ведомым или ведущим.

От ведомого ведущему (Slave to Master): ведомый записывает (передает) данные ведущему когда в ведущем работает функция Wire.RequestFrom().

От ведущему ведомому (Master to Slave): в этом случае функция Wire.write() должна использоваться между вызовами функций Wire.beginTransmission() и Wire.endTransmission().

Функцию Wire.write() можно использовать в следующих вариантах:

  • Wire.write(value); value - значение передаваемого одиночного байта;
  • Wire.write(string) – для передачи последовательности байт;
  • Wire.write(data, length); data – массив данных для передачи в виде байт, length – число байт для передачи.

4. Wire.beginTransmission(address).

Эта функция используется для начали передачи по протоколу I2C устройству с заданным адресом ведомого (slave address). После этого вызывается функция Wire.write() с заданной последовательностью байт для передачи, а после нее функция endTransmission() для завершения процесса передачи.

5. Wire.endTransmission().

Эта функция используется для завершения процесса передачи ведомому устройству, который до этого был инициирован функциями beginTransmission() и Wire.write().

6. Wire.onRequest().

Эта функция вызывается когда ведущий запрашивает данные с помощью функции Wire.requestFrom() от ведомого устройства. В этом случае мы можем использовать функцию Wire.write() для передачи данных ведущему.

7. Wire.onReceive().

Эта функция вызывается когда ведомое устройство получает данные от ведущего. В этом случае мы можем использовать функцию Wire.read() для считывания данных передаваемых ведущим.

8. Wire.requestFrom(address,quantity).

Эта функция используется в ведущем устройстве чтобы запросить байты (данные) с ведомого устройства. После этого используется функция Wire.read() чтобы принять данные переданные ведомым устройством.
address: 7-битный адрес устройства, с которого запрашиваются байты (данные).
quantity: число запрашиваемых байт.

Необходимые компоненты

  1. Плата Arduino Uno – 2 шт. (купить на AliExpress).
  2. ЖК дисплей 16х2 – 2 шт. (купить на AliExpress).
  3. Потенциометр 10 кОм – 4 шт. (купить на AliExpress).
  4. Макетная плата.
  5. Соединительные провода.

Работа схемы

Схема проекта по применению интерфейса I2C в плате Arduino представлена на следующем рисунке.

Схема проекта по применению интерфейса I2C в плате Arduino

Для демонстрации возможностей использования связи по протоколу I2C мы использовали две платы Arduino Uno с подключенными к ним ЖК дисплеями и потенциометрами. С помощью потенциометров будут определяться значения, передаваемые между платами в направлениях ведущий-ведомый и ведомый-ведущий.

Мы будем считывать аналоговое значение напряжения, подаваемое на контакт A0 платы Arduino с помощью потенциометра и преобразовывать его в цифровое значение в диапазоне от 0 до 1023 (с помощью АЦП на этом контакте). В дальнейшем эти значения с выхода АЦП (аналогово-цифрового преобразователя) будут преобразовываться в диапазон 0-127 поскольку мы можем передавать только 7-битные данные при помощи протокола I2C. Интерфейс I2C мы будем использовать на выделенных для него в плате Arduino контактах A4 и A5.

Значения на ЖК дисплее, подключенном к ведомой плате Arduino, будут изменяться в зависимости от положения потенциометра на ведущей стороне и наоборот.

Демонстрация работы проекта

Объяснение программ для Arduino

Нам будут необходимы две программы – одна для ведущей платы Arduino, а другая – для ведомой. Полные тексты обоих программ приведены в конце статьи, здесь же мы рассмотрим их основные фрагменты.

Объяснение программы для ведущей (Master) платы Arduino

1. Первым делом в программе мы должны подключить библиотеку Wire для задействования возможностей протокола I2C и библиотеку для работы с ЖК дисплеем. Также нам необходимо сообщить плате Arduino к каким ее контактам подключен ЖК дисплей.

человеко-машинный интерфейс

Стандарт упрощения принадлежностей

HID устройства

HID в диспетчере устройств Windows

Это означало, что существует протокол для мышей, протокол для клавиатур и так далее. Устройствам необходимо использовать существующие протоколы или создавать собственные драйверы. У людей было больше работы по установке и настройке устройств.

Протокол HID значительно упрощает компаниям производство широко совместимых аксессуаров. Все современные операционные системы поддерживают протокол HID. Вы можете подключить USB-клавиатуру к ПК с Windows, Mac, Chromebook или даже к планшету Android, и она сразу заработает. Это все благодаря HID.

HID и приложения

Веб-камера USB в увеличенном масштабе

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

Вы можете подключить USB-контроллер к своему ПК, и он, как правило, будет управлять игрой должным образом. Даже если контроллер был сделан после игры, он все равно работает. Разработчикам игры не нужно было ничего делать, чтобы это произошло.

Когда вы подключаете HID-устройство, оно сообщает о своих возможностях операционной системе. Операционная система интерпретирует данные и классифицирует устройство. Это позволяет приложениям и играм ориентироваться на классы устройств, а не на конкретные модели.

Это очень важный элемент HID, и мы принимаем его как должное. Игровой контроллер будет работать с вашей библиотекой Steam. Zoom узнает, что нужно включить вашу веб-камеру. Все это происходит с очень небольшой настройкой с вашей стороны.

Типы устройств интерфейса пользователя

USB подключен

Джо Федева

Как упоминалось ранее, USB-периферийные устройства являются наиболее распространенными устройствами с интерфейсом пользователя, которые вы увидите, но есть и другие типы.

Другой распространенный тип — Bluetooth-HID. Это тот же протокол USB-HID с небольшими изменениями для Bluetooth. Как и следовало ожидать, сюда входят устройства, аналогичные USB-HID, но они подключаются через Bluetooth. Мышь Bluetooth будет работать независимо от того, подключена ли она к ПК с Windows, Mac или Chromebook.

Устройства интерфейса пользователя — одни из наиболее распространенных устройств, которые мы используем с компьютерами. Мы не очень ценим, насколько легко ими пользоваться. Было время, когда это было не так просто.

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

В истории компьютеров было много достижений, но стандарт Human Interface Device имел оглушительный успех.

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 Матрицы 8x8 - i2c

В этом примере на матрицу выводится изображение стрелки. Стоит заметить, ко всем нашим модулям написаны библиотеки с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке.

I²C на Raspberry Pi

На Raspberry Pi I²C выводы это 3-й и 5-й выводы колодки, GPIO2 и GPIO3 по номенклатуре BCM и выводы 8, 9 по номенклатуре WiringPi.


Примеры для Raspberry

Работа с шиной с использованием модуля smbus для Python на примере Trema-модуля Матрицы 8x8 - i2c. Для работы с шиной её необходимо включить в настройках Raspberry при помощи утилиты raspi-config . Ссылка на подробное описание как это сделать.

Так же как и в примере с Arduino, в этом примере на матрицу выводится изображение стрелки. Стоит заметить, к Trema-модулю LED Матрица 8x8 - i2c написана библиотека с высокоуровневым интерфейсом и вовсе не обязательно работать с матрицей на низком уровне. Подробнее о работе с библиотекой матрицы можно узнать по этой ссылке

Подробнее о шине I²C:

Резисторы, ёмкость и длина линий шины

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

При использовании шины на модулях не существует принятого стандарта установки подтягивающих резисторов на ведущем или ведомом. У Arduino подтягивающие резисторы отсутствуют и для работы с шиной нужен хотя бы один модуль с ними. У Raspberry Pi на плате установлены подтягивающие резисторы номиналом 1,7 килоОм и для неё нет необходимости в подтяжке на модулях.

Сигналы и специальные биты шины

В состоянии покоя линии шины находятся на верхнем потенциале (обычно 3,3 В или 5 В, но могут быть и другие напряжения). Бездействие устройства, по умолчанию, воспринимается как логическая 1. Для простоты понимания можно рассмотреть аналогию: Вообразим верхний потенциал как уровень воды, а нижний как дно. Представьте, что Вы на рыбалке - попловок в состоянии покоя остаётся на поверхности, когда клюёт - идёт ко дну. Так же и в здесь, при обмене данными линии прижимаются в нулевому потециалу. Далее рассмотрим поочереди сингалы и специальные биты.

Устанавливаемые только ведущим

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

Краткое обозначание сигнала S - заглавная буква S латинского алфавита.

  • Бит Read - Если ведущий желает получить данные, он устанавливает логическую 1 сразу после адреса, информируя ведомого о том, что данные будут считываться (управление линией данных передаётся ведомому).

Краткое обозначание R - заглавная буква R латинского алфавита.

  • Бит Write - Если ведущий желает записать данные, он устанавливает логический 0 сразу после адреса для информирования ведомого о том что данные будут записываться (управление линией данных остаётся у ведущего).

Краткое обозначение W̅ - заглавная буква W латинского алфавита с чертой сверху.

  • Stop - сигнал окончания обмена данными. Ведущий прекращат тактирование, линия тактирования SCL отпущена (логическая 1), линия данных SDA переведена ведущим из логического 0 в логическую 1. После этого сигнала шина считается свободной.

Краткое обозначение P - заглавная буква P латинского алфавита.

  • Restart - сигнал продолжения обмена данными (используется взамен сигналу Stop с последующим Start для продолжения опрашивания шины ). Используется в основном при наличии нескольких ведущих на шине, чтобы управление не перешло другому ведущему после сигнала Stop. Линия тактирования SCL отпущена ведущим, линия данных SDA переведена ведущим из логической 1 в логический 0.

Обозначается Sr - заглавная буква S и строчная буква r латинского алфавита.

Устанавливаемые ведущим и ведомым

Данные биты может устанавливат как ведущий, так и ведомый. В такой ситуации устанавливающее устройство или модуль (ведущий или ведомый) называют передатчиком, а считывающее устройство - приёмником.

  • Бит ACK - (сокращ. англ. acknowledged - подтверждено) каждый девятый импульс тактирования передатчик (ведущий или ведомый) отпускает линию данных. Если линия была прижата приёмником (логический 0) - принятые данные верны, передача может быть продолжена или закончена.

Обозначается A - заглавная буква A латинского алфавита

  • Бит NACK - (сокращ. англ. not acknowledged - не подтверждено) каждый девятый импульс тактирования передатчик (ведущий или ведомый) отпускает линию данных. Если линия была отпущена принимающим или принимающего нет на шине (логическая 1) - принятые данные неверны, произошла ошибка, передача не может быть продолжена. Обозначается A̅ - заглавная буква A латинского алфавита с чертой сверху.

Обмен данными

При обмене данными тактированием занимается только ведущий, а ведомый может удерживать линию тактирования только если не успевает за ведущим, так называемое растягивание тактирования (clock-stretching). Не все модули поддерживают удержание. Установка бита на линии данных может происходит в момент, когда линия тактирования прижата, а считывания, когда линия отпущена (подтянута к Vcc), но в большинстве случаев это происходит по фронту волны на линии тактирования.

Рассмотрим пример простого обмена данными:

Запись в регистры ведомого. Данные взяты из примеров, приведённых выше.

После сигнала Start и указания адреса ведущий записывает адрес регистра с которого будет производиться дальнейшая запись. Стоит заметить, что у ведомого есть внутренний счётчик и каждый последующий байт после подтверждения будет записан в следующий регистр. Таким образом байт со значением 0x00 будет записан в регистр 0x11, байт со значением 0x18 будет записан в регистр 0x12, байт со значением 0x3C будет записан в регистр 0x13 и т. д. В этом примере биты ACK устанавливает ведомый.

Вот так сигналы этого примера выглядят на осциллографе:

Чтение из регистров ведомого. Предположим, мы хотим прочитать байт из регистра 0x13.

Скорость

Первоначальный стандарт I²C был реализован на скорости 100 кГц. С тех пор появились и другие реализации шины, но большинство устройств работают на этой скорости. Так же известны случаи когда скорость шины специально снижена, чтобы увеличить расстояние передачи и уменьшить чувствительность к помехам. Не все модули могут работать на сниженной скорости.

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