Hid клавиатура на микроконтроллере

10-кнопочная USB HID клавиатура на микроконтроллере PIC. Часть 1 – Схема и конструкция

В статье мы рассмотрим простую конструкцию на микроконтроллере, реализующую 10-кнопочную USB HID (Human Interface Device) клавиатуру, которая является Plug-and-Play устройством и не требует установки драйверов.

Изначально устройство предназначалось для быстрого доступа к часто используемым сочетаниям клавиш в операционной системе Windows, например Alt+F4 (закрыть программу), Windows+D (свернуть все окна), Ctrl+Alt+Del и др.

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

Основой конструкции является микроконтроллер Microchip PIC18F14K50, помимо него используется несколько резисторов, конденсаторов и коннекторы. Устройство не требует отдельного источника питания, т.к. подключается к порту USB компьютера (USB Host) и получает питание от него.

Аппаратная часть базируется на примере от компании Microchip “USB Device HID Keyboard”, который предоставляется в отладочном наборе DM164127 – Low Pin Count USB Development Kit. Сочетания клавиш задаются в программе микроконтроллера, назначение сочетания клавиш мы рассмотрим во второй части статьи.

Коды сочетаний клавиш предназначены для операционной системы Windows, однако возможно их переназначение для использования в других ОС.

Основные характеристики устройства:

  • 10 входных каналов (кнопки);
  • все кнопки имеют подтягивающие резисторы к «+» питания;
  • активное состояние кнопок – низкий логический уровень;
  • подключение к порту USB;
  • питание от USB;
  • Plug-and-Play устройство, не требуется установка драйверов.

Основные характеристики микроконтроллера PIC18F14K50:

  • Flash-микроконтроллер со встроенным USB 2.0 интерфейсом;
  • рабочая частота до 48 МГц;
  • 16 КБайт Flash-память программ, 768 Байт SRAM, 256 Байт EEPROM;
  • один 8-битный таймер, три 16-битных таймера, 1 канал ШИМ;
  • коммуникационные интерфейсы: USB, SPI, I2C, UART;
  • встроенный 9-канальный 10-битный АЦП;
  • два аналоговых компаратора;
  • до 15 линий ввода/вывода общего назначения;
  • корпус: 20-выводный DIP, SOIC, SSOP.

Для сборки устройства нам понадобятся:

  • микроконтроллер PIC18F14K50;
  • кварцевый резонатор 12 МГц;
  • один конденсатор 0.1 мкФ;
  • один конденсатор 220 нФ;
  • 2 сборки из 5 резисторов номиналом 10 кОм;
  • один резистор номиналом 1.5 кОм;
  • панелька (сокет) для установки 20-выводного микроконтроллера;
  • коннектор USB Type B;
  • кабель USB Type B – Type A;
  • 10 кнопок;
  • 4-выводные и 6 выводные коннекторы (либо аналогичные).

Принципиальная схема устройства

Кликните для увеличения

Вид печатной платы

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

Расположение элементов на печатной плате

Кнопки установлены на отдельной плате и подключаются к плате с микроконтроллером при помощи коннекторов (обозначены на плате HEADER1-4 и HEADER5-10).

Назначение отдельных компонентов и основные замечания по установке на печатную плату

Наборы 10 кОм резисторов – данные элементы содержат в себе 5 резисторов номиналом 10 кОм каждый, включенных параллельно с одним общим выводом. Этот вывод обозначается точкой на корпусе элемента.

Кварцевый резонатор должен быть расположен максимально близко к микроконтроллеру. Возможно, потребуется подключение двух конденсаторов емкостью 22 пФ к кварцевому резонатору. Конденсатор С2 (220 нФ) подключается между выводом микроконтроллера VUSB и V+.

Резистор R1 (1.5 кОм) подтягивает линию Data+ к напряжению питания, что сигнализирует для Host устройства, на какой скорости работает USB Device (клавиатура).

Джамеперы, указанные на печатной плате (J1 и J2, P1-P2-P3, G1 и G2, Rx и Tx), используются в связи с односторонней разводкой печатной платы, а также для возможности расширения функций:

  • J1 соединен с J2;
  • P1 подключен к P2, который подключен к P3;
  • точки G1 и G2 остаются свободными (подключены к «–» питания);
  • точки Rx и Tx подключены к линиям Rx и Tx микроконтроллера (на схеме не показано) для расширения функций.

Кнопки подключаются при помощи коннекторов к плате с микроконтроллером согласно схемы.

В следующей части статьи мы рассмотрим основные моменты в ПО микроконтроллера, как назначать сочетания клавиш и использование клавиатуры.

Источник: https://www.rlocman.ru/shem/schematics.html?di=108428

AVR271: демонстрационный проект клавиатуры на AVR с аппаратным USB

Источник: http://microsin.net/programming/avr-working-with-usb/avr271-usb-keyboard-demonstration.html

Резистивная клавиатура на Arduino

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

1. Аппаратная часть

Для реализации данного проекта нам понадобится любой контроллер Arduino на чипе ATmega32u4. Этот микроконтроллер позволяет делать HID устройства.

Вариант для домашнего использования как с планшетом или телефоном так и с компьютером

Подойдёт и более компактный вариант от RobotClass, подходящий для встраиваемой установки. Например, в автомобиль — для управления планшетом.

Так же будет нужен набор резисторов различного номинала (к примеру 10 кОм)

и набор кнопок

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

2. Программа и схема

Для начала соберем простенькую схему. Сама клавиатура будет подключена к аналоговому входу A0, что не особо принципиально. Можно использовать любой другой.

После сборки схемы получаем

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

byte key(){     int val = analogRead(0); // считываем значение с аналогового входа и записываем в переменную val     if (val < 50) return 1; // сверяем переменную, если val меньше 50 возвращаем 1 (первая кнопка)     else if (val < 150) return 2; // если val меньше 150 вторая кнопка     else if (val < 350) return 5; // если val меньше 350 третья кнопка     else if (val < 500) return 4; // если val меньше 500 четвертая кнопка     else return 0;   } void setup() { Serial.begin(9600); } void loop() {   int sensorValue = analogRead(A0); //считываем кнопку   Serial.print(key()); // выводим номер кнопки в serial   Serial.print(" ");   Serial.println(sensorValue);   delay(1);        }

После того, как загрузили скетч, открываем «Монитор порта» и нажимая на кнопки  видим их значения в мониторе порта .

3. Программа для управления Android устройством на Ардуино

Теперь попробуем сделать клавиатуру для управления планшетом или телефоном на базе Android. Схема устройства остается та же, что и была. Но теперь контроллер будет распознаваться устройством как USB HID, в нашем случае клавиатурой.

Загружаем следующий скетч:

int analogPin=0;  int data;  void setup(){  Keyboard.begin();     Serial.begin(9600);  }  void loop(){     data=analogRead(analogPin); //чтение нажатой кнопки     Serial.println(data); // вывод кода нажатой кнопки в монитор порта      if (data==614)  Keyboard.write(176); //ENTER код 614     if (data==122)  Keyboard.write(216); //стрелка влево     if (data==165)  Keyboard.write(215); //стрелка вправо     if (data==216)  Keyboard.write(218); //стрелка вверх     if (data==276)  Keyboard.write(217); //стрелка вниз     delay(100);  }

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

4. Заключение

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

Изменено: 25 Апр, 2018 17:41

Источник: http://robotclass.ru/articles/arduino-resistive-keyboard/

Создаем свой хардварный USB-троян – «Хакер»

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

Информация представлена исключительно в образовательных целях. Любое ее использование в неправомерных целях может караться по всей строгости закона РФ (статьи 272 и 273 Уголовного кодекса). Ни автор, ни редакция в этом случае ответственности не несут. Думай головой.

Маленький пример

Начну с небольшой демонстрации. Представь: специалист по безопасности проводит внутренний пентест в некоторой компании и видит, что один из сотрудников часто оставляет станцию незалоченной. Очевидный путь — подойти и выполнить несколько «злобных» команд, пока этого никто не видит.

Однако есть серьезный риск быть пойманным за чужим рабочим местом да еще набирающим что-то непонятное в черном окне консоли :).

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

Если замаскировать девайс под видом мышки, флешки или 3G-модема, то есть шанс, что его без лишней помощи вставит кто-то из самих же сотрудников. Известны случаи, когда такие «протрояненные» девайсы отправлялись просто по почте в качестве сувенирки.

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

HID-устройства

Для начала надо разобраться с понятием Human Interface Device, или HID. В Википедии говорится, что HID — тип компьютерного устройства, которое взаимодействует напрямую с человеком, наиболее часто принимает входные данные от человека и предоставляет ему выходные данные.

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

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

Еще в 2010 году на хакерской конференции DEFCON небезызвестные Irongeek и Dave ReL1k подробно рассказывали об использовании HID-устройств для проверки безопасности систем. С тех пор в плане защиты не изменилось ровным счетом ничего.

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

Плата Teensy

За основу такого USB-девайса была выбрана плата Teensy++ 2.0. Это программируемый микроконтроллер, который изначально идет вместе с полноценным USB-портом.

Среди примеров использования Teensy, в огромном количестве собранных на официальном сайте, — LED-футболка, которая с помощью диодов выводит различные изображения, станок для рисования маркером, наносящим нужный рисунок на любую ровную поверхность, считыватель RFID-карточек, детектор движения и еще десятки полезного и не очень «самопала».

Ты наверняка слышал о платах Arduino и ее аналогах, так вот Teensy — очень похожий проект. Но что важно для моей задачи: на Teensy чрезвычайно просто реализовать HID-устройство, которое будет определяться системой как клавиатура или, к примеру, мышь.

Поскольку плата изначально снабжена USB-портом, то мне даже не пришлось брать в руки паяльник и выполнять какие-либо хардкорные вмешательства. Все, что было нужно, — написать правильную программу. Замечу, что у платы есть несколько версий, но я выбрал самую навороченную и дорогую — Teensy++ 2.0. Ее можно заказать на официальном сайте проекта pjrc.com всего за 24 доллара.

Есть один нюанс, который сильно усложняет Teensy жизнь. Поскольку мы используем эмуляцию HID-устройства, то мы можем говорить с системой, но не можем ее услышать. Это основное ограничение при написании пэйлоадов для Teensy, которое делает пэйлоады менее чувствительными к состоянию системы.

Разработчику боевых нагрузок придется заранее определить все возможные ситуации и реакцию системы, потому что во время выполнения прочитать ответ системы будет невозможно. Единственная вещь, которую Teensy может считать, когда используется в качестве клавиатуры, — это состояние кнопок CAPS, NUM и SCROLL.

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

Hello world для железки

Teensy, как и платы Arduino, использует похожий процессор Atmel AVR, поэтому можно взять ту же среду разработки — Arduino Development Environment (arduino.cc), ее также называют ADE.

Последняя бесплатно доступна для всех популярных ОС (Windows, Linux, Mac OS X) и, помимо редактирования кода, позволяет залить программу в микроконтроллер.

Чтобы полноценно использовать ее для работы с Teensy, необходимо также установить дополнительный аддон Teensyduino (pjrc.com/teensy/teensyduino.html).

Надстройка, в частности, сразу предоставляет возможность перевести Teensy в режим эмуляции клавиатуры: это делается в ADE через меню «Tools —> Boards —> USB Keyboard». Если вставить девайс в компьютер, то он сразу определится как клава. Однако происходить ничего не будет — пока ничего не запрограммировано.

Среда разработки Arduino Development Environment с установленным плагином для совместимости с Teensy

Что представляет собой программа или, как ее называют в здешней терминологии, скетч для Teensy? Разработка осуществляется с помощью С-подобного синтаксиса. Программисту доступны переменные, методы, условные операторы, указатели — короче говоря, все, что нужно для счастья.

Любой скетч должен содержать функции setup() и loop(): первая вызывается один раз во время запуска, а вторая в цикле выполняет написанный внутри нее код. Функции могут быть даже пустыми, однако присутствовать должны — иначе компиляция будет завершаться неудачей.

Приведу пример простейшего кода:

Источник: https://xakep.ru/2013/01/28/60017/

Урок 5. USB. Сторона контроллера

ВНИМАНИЕ!!! ЭТО УСТАРЕВШАЯ СТАТЬЯ. НОВАЯ ЗДЕСЬ

Все, теперь добрались мы до чего-то интересного. Протокол USB.

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

Нам понадобится пакет Microchip Libraries for applications ссылка Зеркало(на данный момент актуальная версия v2013-06-15) Качаем этот файл и устанавливаем. Для компиляции проекта нам понадобятся эти библиотеки.

Мы будем собирать пример HID – custom demos лежит он в папке с установленной программой: microchip_solutions_v2013-06-15USBDevice – HID – Custom Demos Внутри в папке firmware – прошивка для контроллера. В остальных – программы для компьютера.

Дело в том, что в Microchip libraries каждый проект создан для десятка разных контроллеров, и учиться на этом коде довольно проблематично. Он очень громоздкий и не последовательный. Страница кода одна и та же, но в зависимости от того, какой проект вы откроете, для такого контроллера и будет создаваться прошивка.

Изначально из наших контроллеров там присутствует только pic18f4550 и для этого нужно открыть файл проекта USB Device – HID – Simple Custom Demo – C18 – PICDEM FSUSB.mcp Это по идее для такой учебной платы picdem fsusb. Она как раз работает на контроллере pic18f4550.

Я для удобства восприятия удалил “лишний” код, необходимый для настройки других контроллеров и чуть изменил программу, чтобы она корректно работала под pic18f2550 ссылка. Для того, чтобы программа работала, архив нужно распаковать в

microchip_solutions_v2013-06-15USBDevice – HID – Custom Demosлюбойкаталог , поскольку пути к библиотекам прописаны относительно к текущему каталогу. Не дурно бы было почитать документацию к USB библиотеке. Но почему-то microchip уже давно не выпускает новый нормальный user guide. Придется воспользоваться старым. Тем не менее он даст нам идею, как работает библиотека.

лежит он по адресу ссылка  зеркало

Этот файл за 2007 год! Так что уже многие функции библиотеки даже называются по-другому. Примерно философия работы следующая: Контроллер наш, поскольку имеет аппаратную поддержку протокола USB имеет в своей памяти определенные места, в которые нужно записать настройки usb. это первый главный момент. В основном все это находится в файле usb_descriptors.c.

Вы можете открыть этот файл и посмотреть комментарии или даже отредактировать. Потом, важно грамотно настроить биты конфигурации. И в теле программы мы будем вызывать функцию USBDeviceTasks(), которая выполняет в общем-то всю работу по обмену информации через USB.

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

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

В случае, если это не происходит, хост может просто отключить наше устройство, посчитав его сломанным. Чтобы обработать usb сообщение и выслать ответ, нужно вызвать функцию этой библиотеки: USBDeviceTasks(); ну и чтобы отправилось правильное сообщение надо подготовить буферы вывода и прочее. В нашем примере мы просто циклически будем вызывать эту функцию.

Есть и другой выбор: для того, чтобы вовремя давать ответ хосту, можно использовать прерывания, но я опишу это потом, если будет время. Если мы просто периодически вызываем функцию USBDeviceTasks(), то обычно ее надо вызывать не реже, чем 1.8мс. Иногда бывают исключения из этого правила. Смотри комментарии usb_device.

c для тог, чтобы узнать, что это за исключения. Обычно вызвать USBDeviceTask() не требует много времени. Около 100 тактов процессора. Для корректной работы нашего устройства нужно будет задать USB дескрипторы. В общем-то это описание нашего устройства.

Они содерждат класс устройства, в нашем случае это – HID (Human Interface Device, которым могут быть мышки, клавиатуры, или вообще любое устройство) и имя устройства. Все эти параметры заданы в файле usb_descriptors.c, который уже добавлен в проект.

Перед началом работы хост с устройством обмениваются дескрипторами, это дает понять, каким образом будет осуществляться взаимодействие устройств.
Файл hardware profile содержит информацию о том, какой контроллер или плату мы используем. Плюсо к нему microchip обычно добавляет файл конкретного контроллера. Например HardwareProfile – PICDEM FSUSB.h.

В этом файле хранятся различные функции и адреса, связанные с аппаратной частью контроллера. Например, функция инициализации АЦП. В ней непосредственно указано, какое значение должно быть присвоено регистрам АЦП и на какую ножку будет подаваться напряжение.
Все основные комментарии приведены мной в коде в файле main.c. Здесь лишь пара слов. Когда мы открываем проект, перед нами будет следующий набор файлов:

lkr файл – файл линковщика. Он говорит о том, как и которую память можно использовать.

Плюс некоторые настройки usb протокола задаются в файле usb_config.h

На мой взгляд это дерево файлов и логика – далеко не идеальные, но это то, что предлагает microchip.

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

Основные функции программы:

void YourHighPriorityISRCode() – прерывание высокого уровня

void YourLowPriorityISRCode() – прерывание низкого уровня

void main(void) – главная функция

static void InitializeSystem(void) – инициализация контроллера (задание настроек)

void UserInit(void) – то же самое

void ProcessIO(void) – тело программы, где происходит вся обработка и расчеты

WORD_VAL ReadPOT(void) – функция вызова Аналого Цифрового Преобразователя

Далее будем рассматривать файл main.c, в котором находится наш исполняемый код. это сделано в самом файле в комментариях. 

проект для контроллеров pic18f4550 и pic18f2550 ссылка

Здесь для поддержки USB интерфейса используются прерывания.

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

Уменьшенный вариант: ссылка

Проект обязательно нужно распаковать в папку 

microchip_solutions_v2013-06-15USBDevice – HID – Custom Demosлюбойкаталог

потому что там довольно жестко задаются пути к библиотекам

Этот проект работает с обоими контроллерами (только что проверил) с бутлоадером и без него.

Для того, чтобы проверить, работает ли наш пример, запускаем утилитку 

microchip_solutions_v2013-06-15USBDevice – HID – Custom DemosHID PnP Demo.exe

она должна найти ваш контроллер.

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

Источник: http://jasuramme.blogspot.com/2013/08/5-usb.html

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}
");let k=document.querySelector(".flat_pm_modal[data-id-modal=\""+a.ID+"\"]");if(-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(k,d):jQuery(k).html(b+d),"px"==a.how.popup.px_s)e.bind(h,()=>{e.scrollTop()>a.how.popup.after&&(e.unbind(h),f.unbind(i),j())}),void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{e.unbind(h),f.unbind(i),j()});else{let b=setTimeout(()=>{f.unbind(i),j()},1e3*a.how.popup.after);void 0!==a.how.popup.close_window&&"true"==a.how.popup.close_window&&f.bind(i,()=>{clearTimeout(b),f.unbind(i),j()})}f.on("click",".flat_pm_modal .flat_pm_crs",()=>{jQuery.arcticmodal("close")})}if(void 0!==a.how.outgoing){let b,c="0"==a.how.outgoing.indent?"":" style=\"bottom:"+a.how.outgoing.indent+"px\"",e="true"==a.how.outgoing.cross?"":"",f=jQuery(window),g="scroll.out"+a.ID,h=void 0===flatPM_getCookie("flat_out_"+a.ID+"_mb")||"false"!=flatPM_getCookie("flat_out_"+a.ID+"_mb"),i=document.createElement("div"),j=jQuery("body"),k=()=>{void 0!==a.how.outgoing.cookie&&"false"==a.how.outgoing.cookie&&h&&(jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show"),j.on("click",".flat_pm_out[data-id-out=\""+a.ID+"\"] .flat_pm_crs",function(){flatPM_setCookie("flat_out_"+a.ID+"_mb",!1)})),(void 0===a.how.outgoing.cookie||"false"!=a.how.outgoing.cookie)&&jQuery(".flat_pm_out[data-id-out=\""+a.ID+"\"]").addClass("show")};switch(a.how.outgoing.whence){case"1":b="top";break;case"2":b="bottom";break;case"3":b="left";break;case"4":b="right";}jQuery("body > *").eq(0).before("
"+e+"
");let m=document.querySelector(".flat_pm_out[data-id-out=\""+a.ID+"\"]");-1===d.indexOf("go"+"oglesyndication")?flatPM_setHTML(m,d):jQuery(m).html(e+d),"px"==a.how.outgoing.px_s?f.bind(g,()=>{f.scrollTop()>a.how.outgoing.after&&(f.unbind(g),k())}):setTimeout(()=>{k()},1e3*a.how.outgoing.after),j.on("click",".flat_pm_out .flat_pm_crs",function(){jQuery(this).parent().removeClass("show").addClass("closed")})}countMode&&(flat_count["block_"+a.ID]={},flat_count["block_"+a.ID].count=1,flat_count["block_"+a.ID].click=0,flat_count["block_"+a.ID].id=a.ID)}catch(a){console.warn(a)}}function flatPM_start(){let a=flat_pm_arr.length;if(0==a)return flat_pm_arr=[],void jQuery(".flat_pm_start, .flat_pm_end").remove();flat_body=flat_body||jQuery("body"),!flat_counter&&countMode&&(flat_counter=!0,flat_body.on("click","[data-flat-id]",function(){let a=jQuery(this),b=a.attr("data-flat-id");flat_count["block_"+b].click++}),flat_body.on("mouseenter","[data-flat-id] iframe",function(){let a=jQuery(this),b=a.closest("[data-flat-id]").attr("data-flat-id");flat_iframe=b}).on("mouseleave","[data-flat-id] iframe",function(){flat_iframe=-1}),jQuery(window).on("beforeunload",()=>{jQuery.isEmptyObject(flat_count)||jQuery.ajax({async:!1,type:"POST",url:ajaxUrlFlatPM,dataType:"json",data:{action:"flat_pm_ajax",data_me:{method:"flat_pm_block_counter",arr:flat_count}}})}).on("blur",()=>{-1!=flat_iframe&&flat_count["block_"+flat_iframe].click++})),flat_userVars.init();for(let b=0;bflat_userVars.textlen||void 0!==a.chapter_sub&&a.chapter_subflat_userVars.titlelen||void 0!==a.title_sub&&a.title_subc&&cc&&c>d&&(b=flatPM_addDays(b,-1)),b>e||cd||c-1!=flat_userVars.referer.indexOf(a))||void 0!==a.referer.referer_disabled&&-1!=a.referer.referer_disabled.findIndex(a=>-1!=flat_userVars.referer.indexOf(a)))&&(c=!0),c||void 0===a.browser||(void 0===a.browser.browser_enabled||-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser))&&(void 0===a.browser.browser_disabled||-1==a.browser.browser_disabled.indexOf(flat_userVars.browser)))){if(c&&void 0!==a.browser&&void 0!==a.browser.browser_enabled&&-1!=a.browser.browser_enabled.indexOf(flat_userVars.browser)&&(c=!1),!c&&(void 0!==a.geo||void 0!==a.role)&&(""==flat_userVars.ccode||""==flat_userVars.country||""==flat_userVars.city||""==flat_userVars.role)){flat_pm_then.push(a),flatPM_setWrap(a),flat_body.hasClass("flat_pm_block_geo_role")||(flat_body.addClass("flat_pm_block_geo_role"),flatPM_ajax("flat_pm_block_geo_role")),c=!0}c||(flatPM_setWrap(a),flatPM_next(a))}}}let b=jQuery(".flatPM_sticky");b.each(function(){let a=jQuery(this),b=a.data("height")||350,c=a.data("top");a.wrap("
");let d=a.parent()[0];flatPM_sticky(this,d,c)}),debugMode||countMode||jQuery("[data-flat-id]:not([data-id-out]):not([data-id-modal])").contents().unwrap(),flat_pm_arr=[],jQuery(".flat_pm_start, .flat_pm_end").remove()}

Перевод апноута AVR271: USB Keyboard Demonstration on megaAVR with USB [1], рассказывающий про демонстрационный код устройства USB HID – компьютерная клавиатура, подключаемая через USB. Исходный код и документацию можно скачать по ссылке [2].

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

• Клавиатура стандартная, т. е. она работает с любым компьютером PC, на котором установлена операционная система (Windows® 98SE или более свежая, Linux® или Mac OS®).• Не требуется установка драйвера для поддержки клавиатуры.• При подключении клавиатура отображает простое текстовое сообщение.

• Не реализована поддержка управления светодиодами клавиатуры.

Исходный код можно скачать по ссылке [2] (см. папку USB Keybord).

Прим. переводчика: в библиотеке LUFA также есть готовый проект клавиатуры USB HID с исходным кодом, который можно скомпилировать на любой микроконтроллер AVR с аппаратным интерфейсом USB (см.

[2], папки LUFA-130901DemosDeviceClassDriverKeyboard и LowLevelKeyboard архива). Проекты из LUFA удобнее тем, что их можно скомпилировать практически под любую макетную плату, имеющуюся на рынке.

Все примеры кода из архива [2] можно с успехом запустить на макетных платах AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4 [6].

[1. Введение]

Традиционно клавиатура подключалась к компьютеру через интерфейс PS/2. Но интерфейс уже PS/2 устарел, и постепенно исчезает с новых моделей компьютеров PC и ноутбуков.

Его место с успехом заменяет интерфейс USB, который становится стандартным типом подключения для всех периферийных устройств PC.

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

Этот апноут описывает простой проект клавиатуры, подключаемой к компьютеру через USB. Цель документа – показать на примере стартеркита STK525, как запустить тестовый пример реализации клавиатуры USB HID (прим.

переводчика: вместо STK525 можно применить макетные платы AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4).

Подразумевается, что читатель знаком с библиотекой USB Software Library for AT90USBxxx Microcontrollers [3] (поставляется бесплатно на CD-ROM, и её также можно скачать с сайта Atmel) и со стандартом USB HID [4].

Прим. переводчика: за разъяснением специфических терминов стандарта USB (конечная точка endpoint, polling, request, report, хост USB, устройство USB и т. д.) лучше обратиться к документу USB in a Nutshell [7].

[2. Требования к аппаратуре]

Приложение firmware для клавиатуры USB требует следующую аппаратуру:

• Отладочную плату с микроконтроллером AVR USB (STK525, AT90USBKey, STK526, или это может быть Ваша собственная плата).• Стандартный кабель USB, если он нужен для подключения к Вашей плате (например, на одной стороне должен быть стандартный коннектор типа A, а на другой коннектор типа Mini B).

• Компьютер, на котором установлена операционная система Windows (98SE, ME, 2000, XP и т. д.), Linux или MAC OS, поддерживающие хост USB стандартов USB 1.1 или USB 2.0.

Firmware клавиатуры USB Вы также можете запустить на макетных платах AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4.

[3. Как можно запрограммировать Ваш чип AVR USB]

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

• Интерфейс JTAG, для этого нужен аппаратный отладчик JTAGICE mkII(2).
• Интерфейс ISP (SPI), для этого можно использовать программаторы AVRISP mkII, AVR Dragon (прим. переводчика: и множество других программаторов [5]) и отладчик JTAGICE mkII(2).

• Интерфейс USB, благодаря прошитому в память микроконтроллера (это уже сделано на заводе Atmel) DFU bootloader и программному обеспечению FLIP(1). Этот способ наиболее практичен и удобен.

• Параллельное программирование, для этого нужны программаторы STK®500 или STK600.

Примечания:

(1) Программа-утилита FLIP предоставляется компанией Atmel, чтобы позволить пользователю прошить устройства AVR USB (и другие) через подключение USB, что не требует никакой дополнительной аппаратуры типа отладчиков и программаторов.

Прием данных через USB и перепрошивку памяти программ берет на себя бутлоадер DFU, заранее прошитый в память чипа на заводе Atmel.

(2) При использовании JTAGICE MKII будьте осторожны с галочкой “erase before programming” (очистить перед программированием) в утилите программатора AVR Studio®.

Если эта галочка установлена, то это приведет к стиранию как программы пользователя, так и к стиранию бутлоадера DFU. Прим. переводчика: при необходимости бутлоадер всегда можно восстановить с помощью ISP-программатора, бинарник бутлоадера можно скачать с сайта Atmel.

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

Прим. переводчика: простые указания на русском языке по установке драйвера USB и перепрошивке микроконтроллера через FLIP можно получить из статьи “Макетная плата AVR-USB32U4” [6].

[4 Быстрый старт]

Как только прошили Ваш микроконтроллер (например ATmega32U4) файлом usb_keyboard.a90 проекта USB Keybord [2], Вы можете запустить демонстрацию работы клавиатуры.

Проверьте, что Ваше устройство USB успешно прошло энумерацию как клавиатура (см.

скриншот окна Диспетчера Устройств), и теперь Вы может использовать Вашу плату как клавиатуру, чтобы отправить компьютеру символы клавиатурных нажатий.

На рисунке ниже показан джойстик платы STK525.

Для отправки клавиатурных нажатий используйте джойстик. Контакты джойстика просто подключены к портам ввода вывода AVR как замыкатели на землю.

Уже упоминалось, что могут быть использованы и другие стартер-киты и отладочные платы, в этом случае см.

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

1. Запустите программу текстового редактора (Блокнот, Notepad и т. п.).
2.

Переключитесь на английскую раскладку клавиатуры (QWERTY), иначе Вы можете увидеть в текстовом редакторе не те символы, которые ожидалось.
3.

Подключите через USB плату STK525 (или другу Вашу плату), прошитую файлом usb_keyboard.a90.
4. Понажимайте кнопки джойстика.

В результате увидите экран наподобие следующего:

[5. Обзор приложения firmware клавиатуры USB HID]

Программа микроконтроллера (firmware), которая ведет себя как клавиатура USB, использует простейший обмен данными с компьютером PC.

Компьютер постоянно опрашивает клавиатуру с интервалом P (поллинг или опрос, polling interval time) на предмет наличия новый данных, и клавиатура будет отправлять эти данные, если они имеются.

Если данных нет, то клавиатура будет посылать в ответ NAK (No Acknowledge, нет подтверждения). В этом отношении клавиатура USB HID ведет себя точно так же, как USB HID мышь (различия только в формате отправляемых данных).

Данные, которыми обмениваются клавиатура и компьютер PC через USB, называются репортом (report). Репорт, содержащий клавиатурные нажатия, называется report IN (данные передаются в сторону PC). Репорт, который содержит состояние светодиодов клавиатуры (NUM LOCK, CAPS LOCK, SCROLL LOCK…), называется report OUT (данные передаются от PC). На рисунке ниже показана структура этих репортов.

Рис. 5-1. Структура USB репортов клавиатуры.

Примечание: этот демонстрационный пример [2] поддерживает только report IN (обработка report OUT и изменение состояния светодиодов не поддерживается).

Рис. 5-2. Как работает приложение клавиатуры.

[6. Организация кода firmware]

Код firmware клавиатуры USB базируется на USB Software Library for AT90USBxxx Microcontrollers [3], и поэтому имеет ту же самую архитектуру.

Рис. 6-1. Архитектура программного обеспечения USB Keyboard

Эта секция посвящена только работе модуля клавиатуры (как опрашивается джойстик и кнопка). После этого будет описана настройка файлов, чтобы дать пользователю возможность построить собственное приложение клавиатуры USB на основе проекта [2].

6.1 keyboard_task.c

Этот файл содержит функции для инициализации аппаратуры, используемой в клавиатуре, для сбора данных репорта и копирование данных репорта в стек FIFO конечной точки (endpoint FIFO), чтобы репорт был готов к отправке в сторону компьютера PC.

Рис. 6-2. Приложение клавиатуры.

6.1.1 keyboard_task_init

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

6.1.2 kbd_test_hit

Эта функция проверяет, нажата ли в настоящий момент кнопка, и если нажата, устанавливает переменную key_hit в значение true.

6.1.3 keyboard_task

Эта функция определяет, была ли нажата кнопка (key_hit == true). Если кнопка была нажата, то report IN заполняется соответствующими величинами, и загружается в FIFO конечной точки USB, чтобы данные были отправлены хосту PC.

6.2 stk_52x.c

Этот файл содержит все подпрограммы, касающиеся управления ресурсами платы STK52x (джойстик, потенциометр, термодатчик, светодиоды…). Пользователю не нужно модифицировать этот файл, если он использует плату STK52x. Иначе на основе файла stk_52x.c. нужно сделать свой собственный файл для управления аппаратными ресурсами Вашей платы.

6.3 Как добавить поддержку светодиодов клавиатуры (CAPS, NUMLOCK…)

Светодиоды (LED), расположенные на клавиатуре (CAPS, NUMLOCK…), управляются хостом, когда была нажата соответствующая кнопка. Т. е. когда хост получил код клавиши (keycode) CAPS или NUMLOCK, или Scroll Lock, то хост отправляет запрос Set_Report request (Out Report), чтобы включить/выключить соответствующий LED на клавиатуре.

Этот запрос отправляется через конечную точку 0 (endpoint 0, или управляющая конечная точка, или конечная точка по умолчанию, обслуживающая специальные передачи для управления control transfer), и этот запрос обрабатывается как Set_Configuration request, что показано ниже. Сначала хост отправляет set_report:

bmRequestType 00100001
bRequest SET_REPORT (0x09)
wValue Report Type (0x02) и Report ID 0x00)
wIndex Interface (0x00)
wLength Report Length (длина репорта в байтах, 0x0004)
Data Данные репорта, 1 байт.

Этот запрос специфичен для устройств USB класса HID, поэтому он не обрабатывается в модуле usb_standard_request.c, но обрабатывается в модуле usb_specific_request.c. В файле usb_specific_request.c запрос декодирует следующее значение bmRequest и bRequest, используя функцию usb_user_read_request(). Тип репорта report type (0x02) соответствует Out Report.

Для обработке этого запроса функция usb_user_read_request() вызовет функцию hid_set_report().

Эта функция в свою очередь подтвердит setup request, и тем самым позволит пользователю получить 1 байт данных (Вы можете проверить размер данных с помощью параметра wLength) и по нему узнать, какой LED нужно включить или выключить (пожалуйста, обратитесь к спецификации HID, чтобы узнать подробности значений для установки LED).

void hid_set_report (void) { U16 wLength; U8 CAPS_LED = 0; U8 REPORT_ID; LSB(wInterface)=Usb_read_byte(); MSB(wInterface)=Usb_read_byte(); LSB(wLength) = Usb_read_byte(); //!< прочитать wLength MSB(wLength) = Usb_read_byte(); Usb_ack_receive_setup(); while(!Is_usb_receive_out()); REPORT_ID = Usb_read_byte(); CAPS_LED = Usb_read_byte(); // получить значение отправленного // хостом состояния CAPS LED Usb_ack_receive_out(); Usb_send_control_in(); while(!Is_usb_in_ready()); //Отправка репорта для очистки запроса CAPS request Usb_select_endpoint(EP_KBD_IN); Usb_write_byte(0); // байт 0: модификатор Usb_write_byte(0); // байт 1: зарезервировано Usb_write_byte(0); // байт 2: Keycode 0 Usb_write_byte(0); // байт 3: Keycode 1 Usb_write_byte(0); // байт 4: Keycode 2 Usb_write_byte(0); // байт 5: Keycode 3 Usb_write_byte(0); // байт 6: Keycode 4 Usb_write_byte(0); // байт 7: Keycode 5 Usb_ack_in_ready(); //Включить/выключить светодиод в соответствии с запросом хоста if(CAPS_LED == 0) Led3_off(); else Led3_on(); }

6.4 Как переделать устройство USB из “незагрузочного” (non-bootable device) в “загрузочное” (bootable device)

Пожалуйста имейте в виду, что устройства USB HID могут быть bootable или non-bootable. По умолчанию демонстрационные примеры от Atmel поставляются как non-bootable устройства. Если Ваше приложение требует поддержки bootable, то нужно модифицировать параметр подкласса (sub-class parameter) в файле usb_descriptors.h:

// USB Interface descriptor Keyboard (дескриптор интерфейса USB клавиатуры) #define INTERFACE_NB_KEYBOARD 0 #define ALTERNATE_KEYBOARD 0 #define NB_ENDPOINT_KEYBOARD 1 #define INTERFACE_CLASS_KEYBOARD 0x03 // HID Class #define INTERFACE_SUB_CLASS_KEYBOARD 0x00 // Non-bootable #define INTERFACE_PROTOCOL_KEYBOARD 0x01 //Клавиатура #define INTERFACE_INDEX_KEYBOARD 0

Установите INTERFACE_SUB_CLASS_KEYBOARD в значение 1, чтобы клавиатура стала bootable device.

[7. Программное обеспечение для компьютера (PC Software)]

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

https://www.youtube.com/watch?v=B3Umr0YlR0w

Демонстрационное приложение клавиатуры USB HID [2], предоставленное Atmel, не поддерживает обработку OUT report. Вы можете самостоятельно добавить код для поддержки этой возможности, см. раздел 6.3.

[Ссылки]

1. AVR271: USB Keyboard Demonstration on megaAVR with USB site:atmel.com.
2. 131122AVR270_AVR271_AVR272_AVR273.zip.
3. AVR276: USB Software Library for AT90USBxxx Microcontrollers.

4. HID Related Specifications site:usb.org.
5. Программаторы для AVR.
6. Макетная плата AVR-USB32U4.
7. USB in a NutShell – путеводитель по стандарту USB.