Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Управление устройством USB HID на Windows 7

Anna | 17.06.2014 | нет комментариев
В статье сделана попытка предоставить пошаговую инструкцию — как объединить самодельное устройствоUSB HID на микроконтроллере AVR и компьютер с операционной системой Windows 7 x64, Дабы обмениваться данными и руководить портами микроконтроллера. Пример приложения управляет через USB ножкой порта микроконтроллера (к ней подключен индикационный светодиод). Есть вероятность также прочитать состояние состояние светодиода — потушен он либо горит. Топик предуготовлен для новичков, следственно огромная просьба к знатокам программирования — приберегите тухлые яйца и гнилые помидорыиронические комментарии для больше комфортного случая.

Используемое программное обеспечение

1. Для микроконтроллера — библиотека V-USB [1] компании Objective Development и IDE Atmel Studio 6 [2] компании Atmel. Необходимо также скачать и установить тулчейн WinAVR [3] для компиляции firmware микроконтроллера (для спецов это необязательно, потому что дозволено обойтись тулчейном, тот, что входит в состав Atmel Studio).
2. Для написания программы Windows (ПО хоста) применялась библиотека LibUsbDotNet [4] Тревиса Робинсона и IDE Visual Studio C# 2010 [5] компании Microsoft.

Все программное обеспечение, помимо Visual Studio 2010, бесплатное, правда есть вероятность применять Visual Studio C# 2010 Express даром в течение ограниченного срока. Все действия проводились в среде операционной системы Windows 7 x64, но наверно подойдет и любая иная операционная система семейства Windows (Windows XP и больше свежая).

Используемое сталь

Вследствие библиотеке V-USB для создания устройства USB HID подойдет всякий микроконтроллер AVR. Если Вы дружите с паяльником, то даже можете собрать подключение к USB независимо по одной из опубликованных схем. Такая схема (взята из пакета V-USB [1]) в качестве примера приведена на картинке.

Дабы экономить время и усилия, отменнее применять готовую макетную плату. Исключительно комфортно, если в плату будет записан USB-загрузчик (bootloader), тогда не потребуется приобретать программатор для перепрошивки платы. Я применял макетную плату AVR-USB-MEGA16 с микроконтроллером ATmega32A, в ней загрузчик есть (USBasploader, эмулирующий поведение программатора USBasp). Вот так платка выглядит в естественную величину:

image

Дозволено взять также metaboard (на нем стоит ATmega168 либо ATmega328), либо даже программатор на микроконтроллере ATmega8. Сходственные железки дозволено дешево приобрести на ebay.com либо dx.com.

Создание firmware микроконтроллера с поддержкой Atmel Studio 6 и библиотеки V-USB

Сделайте новейший план в Atmel Studio 6 (дальше легко AS6). Когда AS6 предложит предпочесть микроконтроллер, выберите Atmega32 без буквы A, не Atmega32A (правда на плате стоит Atmega32A) — это значимо, так как тулчейн WinAVR не видит разницы, он знает только Atmega32. Эти микроконтроллеры по внутреннему устройству одинаковы, так что для нас разницы нет, а для AS6 есть.

Сейчас необходимо верно настроить компилятор. В верхнем меню AS6 нажите Tools, дальше Options.. и появится вот такое окно:

image

Слева в списке выберите Toolchain. Справа появится список Flavours. Этим словечком Atmel закодировала допустимые варианты используемого инструментария (тулчейны).

Примечание. В списке теснее присутствует тулчейн Native, тот, что применяется по умолчанию (Default). Тулчейн Native - это компилятор GCC совместно с заголовочными файлами и библиотеками, которые предоставляют нужную среду компилирования начального кода для микроконтроллера. Данный тулчейн предоставила Atmel, он устанавливается механически совместно с установкой AS6. Как я теснее упоминал, для компиляции дозволено применять и данный тулчейн, но тогда в начальный код примеров V-USB (на основе примера USB HID будет трудиться наше устройство USB) придется вручную вносить исправления. Они несложные, но для новичков будет отменнее добавить сюда тулчейн WinAVR, и применять для компиляции именно его.

Для добавления в список Flavours тулчейна WinAVR нажмите кнопку Add Flavour, появится следующее окно:

image

В верхней строчке этого окна введите имя компилятора WinAVR (произвольное), а в нижней строке введите полный путь, куда установлен сам компилятор тулчейна (с указанием папки \bin) и нажмите кнопку Add. В списке Flavours появится добавленный компилятор, как показано на скриншоте.

Выделите мышкой наш новейший добавленный компилятор WinAVR и нажмите кнопку Set As Default (сделать его тулченом по умолчанию), и нажмите OK. Позже этой процедуры наша AS6 будет применять компилятор WinAVR.

Пора настроить свойства нашего плана, для этого курсором в Solution Explorer левым щелчком выберите имя плана и нажмите Alt F7 (меню Project -> Properties), появится окно с настройками:

image

Сделайте следующие настройки:

  • В разделе AVR/GNU C Compiler -> Symbols добавляем в поле -D строчку F_CPU=12000000UL — это соответствует частоте микроконтроллера 12 МГц (такой кварц установлен на моей макетной плате AVR-USB-MEGA16).
  • В разделе AVR/GNU Assemler -> General в поле Assembler flag нужно добавить -DF_CPU=12000000UL.
  • В разделе AVR/GNU C Compiler -> Optimization в поле Optimization Level должно стоять Optimize for size (-Os).

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

image

В выпадающем списке Toolchain Flavour выберите добавленный компилятор WinAVR, Дабы при компилировании плана AS6 использовала его. На этом настрока AS6 завершена.

Дальше нужно в сделанный план добавить файлы начального кода плана [6] — см. папку firmware\VUSB, файлы VUSB.c, usbdrv.c, usbdrvasm.S и oddebug.c. План ASS6 сделан на основе одного из примеров библиотеки V-USB: hid-custom-rq, тот, что первоначально компилировался с поддержкой утилиты make из командной строки. На основе библиотеки V-USB дозволено обнаружить много других примеров кода — в основном это устройства USB HID (мыши, клавиатуры, устройства ввода и итога), но есть также и устройства USB CDC (воображаемый COM-порт). Если Вам лень самому создавать план, легко откройте в AS6 файл плана VUSB.atsln, в нем теснее сделаны все нужные настройки и добавлены все надобные файлы.

Если у Вас применяется иная макетная плата, то необходимо верно настроить файл usbconfig.h. Подробное изложение всех настроек дано в комментриях этого файла. Основное внимание следует уделить назначению итогов микроконтроллера, которые применяются под сигналы USD D и D- (макроопределения USB_CFG_IOPORTNAME, USB_CFG_DMINUS_BIT, USB_CFG_DPLUS_BIT), к этим ножкам предъявляются специальные требования. Конфигурационный файл usbconfig.h из архива [6] предуготовлен под разводку ножек макетной платы AVR-USB-MEGA16, и он гарантированно работает. Моргать программа будет светодиодом, тот, что теснее имеется на макетной плате и подключен к ножке 0 порта B.

Создание программы для компьютера (ПО хоста)

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

Примечание. Программа была сделана на основе примера консольного приложения из той же библиотеки V-USB. Компиляция начального кода консольного приложения выполнялась с поддержкой makefile и пакета MinGW, и использовала библиотеку LibUSB. В нашем примере мы будем применять графическую среду Visual Studio и библиотеку LibUsbDotNet.

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

Запустите Microsoft Visual C# 2010 Express и сделайте новейший план на основе Windows Form. Сейчас необходимо подключить к плану библиотеку LibUsbDotNet.dll. В обозревателе решений нажмите правой кнопкой мыши на наименовании плана, и выберите «Добавить ссылку».

image

появится ещё одно окно

image

тут необходимо обнаружить путь на диске, где находится библиотека LinUsbDotNet.dll (по умолчанию она устанавливается папку C:\Program Files\LibUsbDotNet, но отменнее сделать копию файла DLL в рабочий каталог плана. Позже подключения библиотеки её необходимо объявить в плане, для этого добавьте в основной модуль программы (файл Form1.cs) строки:

using LibUsbDotNet;
using LibUsbDotNet.Info;
using LibUsbDotNet.Main;

Перейдите к визуальному редактору формы, и приведите её примерно к такому виду (добавьте 3 кнопки Button и 3 текстовых метки Label):

Внешний вид главной формы ПО хоста

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

private void Form1_Load(object sender, EventArgs e)
{
    MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
    if (MyUsbDevice != null)
    {
        label2.Text = " подключено !";
    }
    else label2.Text = " не обнаружено !";
}

Сделайте обработчик события клика на кнопке button1 («Вкл»), для этого сделайте в визуальном редакторе на кнопке двойственный щелчок, и добавьте в тело обработчика события код:

private void button1_Click(object sender, EventArgs e)
{
    // Передать пакет, тот, что включает светодиод на макетной плате AVR-USB-MEGA16.
    UsbSetupPacket packet = new UsbSetupPacket((byte)(UsbCtrlFlags.RequestType_Vendor | 
    UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.Direction_Out), 1, (short)1, 0, 0);
    int countIn;
    byte[] data = new byte[1];
    MyUsbDevice.ControlTransfer(ref packet, data, 0, out countIn);
}

Для обработчика кнопки «Выкл» добавьте код:

private void button3_Click(object sender, EventArgs e)
{
    // Передать пакет, тот, что погасит светодиод на макетной плате AVR-USB-MEGA16.
    UsbSetupPacket packet = new UsbSetupPacket((byte)(UsbCtrlFlags.RequestType_Vendor |
    UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.Direction_Out), 1, (short)0, 0, 0);
    int countIn;
    byte[] data = new byte[1];
    MyUsbDevice.ControlTransfer(ref packet, data, 0, out countIn);
}

Код для обработки кнопки «Чтение»:

private void button2_Click(object sender, EventArgs e)
{
    //Получение данных от макетной платы AVR-USB-MEGA16 - состояние светодиода.
    UsbSetupPacket packet = new UsbSetupPacket((byte)(UsbCtrlFlags.RequestType_Vendor | 
    UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.Direction_In), 2, (short)0, (short)0, (short)0);
    int countIn;
    byte[] data = new byte[1];
    if (MyUsbDevice.ControlTransfer(ref packet, data, 1, out countIn) && (countIn == 1))
    {
       label3.Text = "Прочитано значение "   data[0].ToString();
    }
}

Обработчик события закрытия формы (заключение работы программы) гасит светодиод, если он горит:

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    UsbSetupPacket packet = new UsbSetupPacket((byte)(UsbCtrlFlags.RequestType_Vendor |
    UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.Direction_Out), 1, (short)0, 0, 0);
    int countIn;
    byte[] data = new byte[1];
    MyUsbDevice.ControlTransfer(ref packet, data, 0, out countIn);
}

Как пакеты USB декодируются в firmware микроконтроллера

Прием и обработка данных на стороне микроконтроллера осуществляется в функции usbFunctionSetup(находится в основном модуле VUSB.c плана firmware AS6). Вот эта функция:

usbMsgLen_t usbFunctionSetup(uchar data[8])
{
    usbRequest_t    *rq = (void *)data;

    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR){
        DBG1(0x50, &rq->bRequest, 1);   /* отладочный итог: печатаем наш запрос */
        if(rq->bRequest == CUSTOM_RQ_SET_STATUS){
            if(rq->wValue.bytes[0] & 1){    /* установить LED */
                LED_PORT_OUTPUT |= _BV(LED_BIT);
            }else{                          /* очистить LED */
                LED_PORT_OUTPUT &= ~_BV(LED_BIT);
            }
        }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
            static uchar dataBuffer[1];     /* буфер должен оставаться валидным привыходе из usbFunctionSetup */
            dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0);
            usbMsgPtr = dataBuffer;         /* говорим драйверу, какие данные воротить */
            return 1;                       /* говорим драйверу послать 1 байт */
        }
    }else{
        /* вызовы запросов USBRQ_HID_GET_REPORT и USBRQ_HID_SET_REPORT не реализованы,
         *  от того что мы их не вызываем. Операционная система также не будет обращаться к ним, 
         *  потому что наш дескриптор не определяет никакого значения.
         */
    }
    return 0;   /* default для нереализованных запросов: не возвращаем назад данные хосту */
}

Наше устройство USB HID простейшее, и реагирует оно только на руководящие передачи (control transfer), которые проходят через финальную точку 0 (default control endpoint). По типу запроса (поле bRequest) декодируется направление передачи данных. Если CUSTOM_RQ_SET_STATUS, то это данные, предназначаемые для микроконтроллера. Данные декодируются и микроконтроллер исполняет заложенную там команду. В этом случае в самом первом по порядку принятом байте данных закодировано состояние светодиода — если там в младшем бите единичка, то светодиод включается, а если нолик, то гаснет. Если же в поле bRequest принято значение CUSTOM_RQ_GET_STATUS, то в результат заполняется буфер нынешним состоянием светодиода, и данные буфера отправляются обратно хосту. Все дюже легко, и при желании поведение кода дозволено легко переделать под свои нужды.

Видео, как это работает:

Буду рад ответить в комментариях на вопросы и конструктивные примечания.

Ссылки

1V-USB.
2Atmel Studio 6.
3WinAVR.
4LibUsbDotNet C# USB Library.
5Visual Studio 2010 Express.
6Начальный код для микроконтроллера и для ПО хоста.

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB