Програмиране на usb контролер. Основи на разработването и програмирането на прости USB устройства. Програмиране на HID устройства на „най-високо ниво“

Програмиране през USB порт

Програмиране на устройството за настройка сателитни чинии SF-50 чрез USB се различава от програмирането чрез RS-232 само по начина, по който данните се прехвърлят от инструмента към компютъра и от компютъра към инструмента. При програмиране през USB, преносим USB устройство(флашка). Това е удобно, когато например вашият компютър или по-често лаптоп (нетбук) няма сериен RS-232 порт на шасито си.
За да програмирате устройството с помощта на USB устройство, ще ви трябва:
- USB устройство (флашка), форматирано във файловата система FAT-32;
- Редакторска програма AliEditor, намираща се в папка Database_editor_new на софтуерния раздел на устройството OPENBOX SF-50.

Преди да програмирате, трябва да прехвърлите базата данни от устройството на вашия компютър. За да направите това, включете устройството, свържете се към порта USB флашка. Изпълнете MENU – System – Save to USB,

Излезте от менюто, като натиснете бутона MENU, докато се появи текущият канал, или до снимката на главното меню, ако все още няма канали и извадете флашката. Поставете флаш устройството в компютъра.
Стартирайте програмата Editor.exe от папката Database_editor_new и отворете изображението на флашката в нея.

Когато бъдете подканени да изберете база данни, изберете Потребителска база данни.

Натиснете OK. Изберете Всички услуги, ще се отвори списък с всички сканирани и запазени телевизионни, радио и сервизни канали, налични в базата данни.

Редактирайте каналите, както желаете, например оставяйки само отворени канали.
На клавиатурата на компютъра задръжте натиснат бутона Shift, натиснете стрелка надолу и маркирайте каналите, които искате да изтриете. Щракнете върху Изтриване, за да изтриете избраното.

За да редактирате сателитните настройки, изберете Всички услуги – Сателитна информация – EUTELSAT W4, W7, натиснете бутона ENTER.

Ако е необходимо, редактирайте стойностите в Antenna 1.
За да изтриете транспондер, изберете ненужния и натиснете бутона Изтриване на клавиатурата на компютъра, потвърдете избраното действие.

За да добавите транспондер, отидете на името на сателита, натиснете десен бутонмишката и изберете Add Information (или маркирайте сателита и натиснете бутона Insert на клавиатурата).

Въведете данните за новия транспондер, като ги вземете например от уебсайта lyngsat.com.

Щракнете върху OK и се уверете, че транспондерът е регистриран.

За да добавите сателит, отидете на реда Информация за сателита, натиснете клавиша Insert на клавиатурата и въведете параметрите на новия сателит.

затворете програмата за редактор и премахнете устройството.
Поставете устройството в устройството OPENBOX SF-50, следвайте последователността МЕНЮ – Система – Актуализиране от USB, изберете режим „SAT&TP List”.

Изберете Старт. Потвърдете намеренията си.

Устройството ще актуализира базата данни и ще се рестартира. След рестартирането ще трябва да зададете езика на менюто на руски по нов начин. Нулирайте устройството до фабричните настройки.
Излезте от менюто с настройки, като натиснете два пъти бутона MENU. Натиснете бутона OK на текущия канал и се уверете, че списъкът с канали е редактиран.

Можете също така да се уверите, че списъкът с транспондери и сателити е редактиран.
Програмирането е завършено.

Да започнем с минимума:
включва 18f2455 -- библиотека за използвания MK
--
enable_digital_io() -- превключване на всички входове в цифров режим
--
псевдонимБутон е pin_B7 -- тъй като имаме свързан бутон, нека го декларираме
pin_B7_direction = вход -- нашият бутон работи за влизане
--
-- един ред - и имаме всичко необходимо за работа с USB CDC
включва usb_serial -- библиотека за работа с usb
--
usb_serial_init() -- --инициализирайте USB CDC
завинаги цикъл-- основен цикъл, изпълняван непрекъснато
usb_serial_flush() -- usb актуализация. Тази процедура изпълнява всички необходими
-- действия за поддържане на връзка с компютър
крайна линия

Чрез компилиране на този код, записване на получения HEX файл в MK с помощта на буутлоудър и стартиране на устройството, можете да наблюдавате как се дефинира ново устройство в системата: Виртуален com порт.

Сега, когато устройството вече работи, нека го научим да комуникира.

За четене на получения байт има функция usb_serial_read(байт ) :булев. Ако има получен байт, той го съхранява в указаната променлива и се връща вярно, в противен случай се връща невярно.

Има процедура за изпращане на байт usb_серийни_данни. Той е маскиран като променлива, така че за да изпратите байт, просто трябва да му присвоите стойността на изпратения байт.

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

включват 18f2455
--
enable_digital_io()
--
псевдонимБутон е pin_B7
pin_B7_direction = вход
--
--
включва usb_serial
--
usb_serial_init()
променлив байтгл -- деклариране на променлива
завинаги цикъл-- основен контур
usb_serial_flush()
ако(usb_serial_read(ch)) тогава-- ако се получи байт, той ще бъде записан в гл
usb_serial_data = гл -- изпрати получения байт обратно
край ако
крайна линия

Компилираме, задържаме бутона, сменяме захранването, стартираме буутлоудъра, сменяме фърмуера, стартираме.
Устройството отново е открито в системата, сега се нуждаем от софтуер, за да тестваме работата на устройството.

Въпреки че нямаме собствен, използваме готов терминал: използвах програмата RealTerm.
Отворете порта с необходимия бройи изпратете данните.


И получаваме обратно това, което изпратихме. Това означава, че всичко работи както трябва.

Софтуер

Така нашият микроконтролер може да получава байтове и веднага да ги изпраща обратно. Сега нека напишем наш собствен софтуер, за да комуникираме с него (ще използвам Delphi).

Създаваме нов проект, подреждаме необходимите компоненти според формата:
SpinEdit1 - за указване на номера на порта
Button1 - за установяване на връзка
Button2 - за прекъсване на връзката
SpinEdit2 - за въвеждане на байтове в десетична форма
Button3 - за изпращане на байт
Memo1 - за показване на получената информация.

Както бе споменато по-горе, трябва да работите с com порта по същия начин, както с обикновения текстов файл: Използване на функциите CreateFile, WriteFile и ReadFile.

Без да навлизаме в подробности, нека вземем готова библиотека за работа с com порт: ComPort.

Прикрепяме необходимата задача към всеки бутон и получаваме крайния код:

единица Единица1;

интерфейс

Употреби
Windows, съобщения, SysUtils, варианти, класове, графики, контроли, формуляри,
Диалогови прозорци, StdCtrls, Spin, ComPort;

Тип
TForm1 = клас (TForm)
SpinEdit1:TSpinEdit;
Бутон1: TButton;
Бутон2: TButton;
SpinEdit2:TSpinEdit;
Бутон3: TButton;
Бележка1: TMemo;
процедура OnRead(Sender: TObject; ReadBytes: масив от Byte);
процедура Button1Click(Подател: TObject);
процедура Button2Click(Подател: TObject);
процедура FormDestroy(Подател: TObject);
процедура Button3Click(Подател: TObject);
частен
(Лични декларации)
Порт: TComPort;
публичен
(Публични декларации)
край;

вар
Формуляр1: TForm1;
num:цяло число;
изпълнение

Процедура TForm1.Button1Click(Sender: TObject);
започвам
Порт:= TComPort.Create(SpinEdit1.Value, br115200); //създайте връзка
Port.OnRead:= OnRead; //създаване на поток за четене на получените данни
Button2.Enabled:= true; //активиране на бутона за затваряне на връзката
край;

Процедура TForm1.Button2Click(Подател: TObject);
започвам
Port.Free; //затворете връзката
Button2.Enabled:= false; //деактивирайте бутона
край;

Процедура TForm1.Button3Click(Подател: TObject);
започвам
ако Button2.Enabled тогава Port.Write();
край;

Процедура TForm1.FormDestroy(Подател: TObject);
започвам
ако Button2.Enabled тогава
Port.Free;
край;

Процедура TForm1.OnRead(Sender: TObject; ReadBytes: array of Byte);
вар
i:цяло число;
започвам
за i:= Low(ReadBytes) до High(ReadBytes) правя // преминава през масива от получени байтове
започвам
Memo1.Text:= Memo1.Text + "." +InttoHex(ReadBytes[i],2); //добавете неговата HEX стойност към прозореца
вкл.(брой); //преброяване на броя получени байтове
край;
ако num > 10 тогава започнете
Memo1.Lines.Add("" ); // обвиване на линията
брой:= 0;
край;
край;

Стартираме, установяваме връзка, изпращаме байтове:

Така че нашият най-прост терминал е готов да работи с най-простото USB устройство.

Както можете да видите, четенето и писането се извършват в динамични масиви от байтове.

Чрез обработката на получената информация можете да създадете необходимия протокол за обмен, подходящ за текуща задача.

включват 18f2455
--
enable_digital_io()
--
псевдонимБутон е pin_B7
pin_B7_direction = вход
--
--
включва usb_serial
--
usb_serial_init()
променлив байтгл
променлив байтаз -- декларирайте втората променлива
завинаги цикъл-- основен контур
usb_serial_flush()
ако(usb_serial_read(ch)) тогава-- ако байтът е получен, извършете необходимите действия
случайгл -- цикъл през номера на байта
0 : usb_serial_data = 0xff
1 : usb_serial_data = Бутон -- състояние на бутона за изпращане
ИНАЧЕ блок-- ако се получи нещо друго
за 16 използванеаз цикъл-- изпращане на 10 байта данни
usb_serial_data = ch +i -- от ch до ch+15
крайна линия
краен блок
краен случай
край ако
крайна линия

Допълнителни функции

Ако спрем до тук, получаваме редовна статия с подробно описание на пример за използване на библиотеката, от които има много в Интернет. Затова ще добавя малко по-задълбочена информация.

Улесняване на изпращането на данни

Изпращането на информация един байт наведнъж не винаги е удобно. Библиотеката може да бъде полезна много често печат. Той съдържа процедури за изпращане на данни с всички възможни дължини във всички възможни формати: byte, hex, dec, bin, boolean, което може да опрости извеждането на данни в програмата.
> включва печат
...
var dwordданни
print_dword_hex(usb_serial_data, данни)

Имената на всички команди могат да бъдат намерени във файла на библиотеката.

Изчакване за свързване с компютър

Ако преди стартиране на основния цикъл на микроконтролера е необходимо първо да се установи връзка с компютъра, тогава можете да добавите редовете пред него
докато(usb_cdc_line_status() == 0x00) цикъл
крайна линия

Задаване на номер на порт към устройството

Ако оставите всичко както е, системата ще разпредели първия свободен номер на порт за всяка нова връзка. Това означава, че винаги ще трябва да го държите под око.
За да предотвратите това да се случи, трябва да зададете уникален сериен номер на устройството, преди да свържете USB библиотеката:
Номерът може да бъде с произволна дължина и да съдържа различни знаци.
const байт USB_STRING3 =
{
24 , -- дължина на масива
0x03, -- bDescriptorType
"0" , 0x00 ,
"1" , 0x00 ,
"2" , 0x00 ,
"3" , 0x00 ,
"4" , 0x00 ,
"5" , 0x00 ,
"6" , 0x00 ,
"7" , 0x00 ,
"8" , 0x00 ,
"9" , 0x00 ,
"X", 0x00
}

Променете името на устройството на вашето

Можете да промените името на устройството, което се вижда в системата, преди да инсталирате драйверите, като декларирате масив със същото име като сериен номер, това трябва да се направи, преди да свържете USB библиотеката.
const байт USB_STRING2 =
{
28 , --
0x03, -- bDescriptorType
"Д", 0x00 ,
"д", 0x00 ,
"м", 0x00 ,
"о", 0x00 ,
" " , 0x00 ,
"Б", 0x00 ,
"о", 0x00 ,
"а", 0x00 ,
"р", 0x00 ,
"г", 0x00 ,
" " , 0x00 ,
"=" , 0x00 ,
")" , 0x00
}

Но уви, след инсталиране на драйверите, устройството ще промени името си на това, посочено в .inf файла, така че ще променим името и там


DESCRIPTION="Демо CDC"

Организираме автоматично свързване на устройството

Уви, няма директни начини за изпълнение на тази задача, така че ще трябва да сте умни.

На първо място, трябва да зададете уникален производител и продуктова стойност на вашето устройство, за да го идентифицирате лесно сред стотици други стандартни CDC фърмуери.
VID и PID се дават за пари, така че нека следваме пътя на китайците: тихо вземете очевидно безплатните стойности.

фърмуер:
Във фърмуера трябва да декларирате две променливи, преди да свържете USB библиотеката

const дума USB_SERIAL_PRODUCT_ID = 0xFF10
const дума USB_SERIAL_VENDOR_ID = 0xFF10

Вместо FF10 можете да вмъкнете произволни две думи (2 байта). Крайният резултат се съдържа в прикачения архив.

Драйвери:
Тъй като драйверите не са предназначени за нашата комбинация от VID и PID, ние ще добавим нашите стойности към .inf файла ръчно:


%DESCRIPTION%=Инсталиране на драйвер, USB\VID_FF10&PID_FF10


%DESCRIPTION%=Инсталиране на драйвер, USB\VID_FF10&PID_FF10

Софтуер:
За да уловите събития за свързване/прекъсване на връзката на устройството, нека свържем библиотеката ComponentUSB. Не мисля, че е необходимо да обяснявам всеки ред: всички промени могат да се видят в приложения проект.

Резултат

Трудно се вижда на скрийншота, но бутонът за изпращане е активен само когато има свързано устройство и на всеки 50ms програмата изпраща заявка за получаване на състоянието на бутона (което обаче е некоректно, защото натискането на бутона трябва да се обработи на МК).

Както можете да видите, организирането на обмен на данни между MK и компютър чрез USB не е най-трудната задача. Получената връзка може да се използва не само за крайни цели: тя е подходяща и за отстраняване на грешки в програмата. В края на краищата, изпращането на резултатите от изчисленията и текущите състояния на регистрите и променливите към компютър е много по-ясно от мигането на двойка светодиоди с морзова азбука.

И накрая: съветвам ви да разгледате изходен кодлампи за настроение. Можете да намерите доста там добър вариантобработка на получените данни за организиране на удобен протокол за обмен.

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

Ако трябва пишете софтуерЗа всяко USB устройство, което би разширило възможностите си за обработка на данни, можете да изберете един от три възможни пътя:

напишете свой собствен драйвер за устройство, който да осигури всички необходими функции за контрол и обмен на данни, както и програма, която да взаимодейства с този драйвер в потребителски режим. В този случай можете напълно да се откажете от стандартните системни драйвери;

напишете филтърен драйвер, който ще предостави необходимата функционалност, но ще бъде разположен в стека на драйверите над системните драйвери. Така че всичко стандартни функцииобработката ще се извършва от USB драйвери, инсталиран от системата, А допълнителни функциище бъде осигурен от вашия филтърен драйвер, с който ще взаимодейства потребителската програма;

възползвайте се от свободно разпространяваните библиотеки с функции и драйвери

mi за достъп до USB устройството.

В повечето случаи програмен достъпкъм USB устройство може да се наложи, ако това устройствоизпълнява много специфична функция. Например, разработени са базирани на USB „електронни осцилоскопи“ или системи за събиране на данни, които изискват достъп до самото устройство, за да работят. В повечето от тези случаи можете да използвате свободно разпространявани библиотеки от функции, които ще работят в почти всички популярни среди за програмиране. Например под егидата на GNU е разработен софтуер, известен като LibUsb, който включва необходимите драйвери и функционални библиотеки за работа на операционни системи Windows и Linux. Тези библиотеки с функции са много популярни и ви позволяват бързо да разработвате програми, които взаимодействат с вашето устройство, като използвате набор от стандартни функции. Това елиминира необходимостта да пишете свой собствен драйвер за устройство, което спестява значително време.

Освен това повечето потребители не са запознати с техниките за разработка на драйвери,

Това е много сложна област на програмиране, така че наличието на такъв свободно разпространяван софтуер ще предостави безценна помощ на широк кръг потребители. Въз основа на проекта LibUsb са разработени обвивки за работа Visual Basic.NET и C# .NET, най-популярният от които е LibUsbDotNet, също е разработен под егидата на свободния софтуер. Въпреки очевидната сложност на програмирането на USB устройства, изброеният софтуер опростява тази задача толкова много, че дори и начинаещите могат да я направят. Нека да разгледаме практически примерикак да работите с вашите USB устройства mi и нека започнем със софтуерния пакет LibUsb. Между другото, горният софтуер може да бъде изтеглен безплатно от www.sourceforge.net или от множество дублирани сайтове.

Как се работи с библиотеки USB функции LibUsb? Библиотеката е изградена по този начин

така че да можете да извършвате основни операции, свързани с USB устройството:

идентификация или, с други думи, изброяване. При извършване на тази операция се откриват устройства, свързани към USB шината, което се извършва с помощта на съответните функции на библиотеката libusb;

получаване на параметри на устройството (идентификатори на устройството, данни за производителя и характеристики на устройството), за които разполага библиотеката цяла поредицафункции;

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

Всички горепосочени функции могат да бъдат реализирани чрез извикване на съответните библиотечни функции на libusb, но те няма да бъдат изброени тук, защото това би заело твърде много място; ще разгледаме как да използваме някои от тези функции

ориз. 6.10

Местоположение на драйвера libusb0.sys в стека на драйвера на устройството

ции с помощта на практически примери. Читателите могат да намерят описание на всички функции в съответната документация. Позволете ми да ви напомня, че обмисляме използването на библиотечни функции libusb в операционни системи Windows.

Когато инсталирате дистрибуция с libusb в операционна система Windows инсталира филтърния драйвер libusb0.sys в системата. Този драйвер ще бъде разположен в горната част на стека на системния драйвер, което е лесно да се види, например, като се погледне информацията за драйвера за всяко USB устройство (фиг. 6.10).

В допълнение, за достъп до драйвера от потребителски програми в системата е инсталирана библиотеката libusb0.dll, с помощта на която можете да разработвате потребителски програми.

ориз. 6.17

Изглед на прозореца на приложението при деинсталиране

USB устройства от системата

Но не е достатъчно само да свържете физически устройството към компютъра, трябва също така да установите обмен на данни между тях. Как да изберем порт и да организираме връзка? Преди няколко години стандартното решение беше използването на COM порт. Между другото, различни специалисти все още инсталират 8, 16 или дори 32 COM порта на индустриални компютри (има цяла категория различни PCI разширителни карти за серийни портове, контролери и т.н.). Така, ако трябва да свържете няколко външни устройства с интерфейс RS-232, може да се нуждаете от скъпи адаптери и екзотични разширителни карти, които по стара традиция пътуват до Русия със седмици на кораб. Между другото, името на обикновен адаптер „DB9m/DB25f адаптер“ може да предизвика само раздразнение за мениджъра на компютърен магазин.

Какво е HID устройство

В днешно време почти всички устройства се свързват към компютър чрез USB интерфейс. Поради това много нови компютри изобщо нямат COM порт.

USB интерфейс - типично решение за свързване на нов външно устройствос компютър, по-точно, това е HID интерфейс, базиран на USB протокол 1.1.

Въпреки че много хора смятат, че интерфейсът HID (Human Interface Device) е предназначен единствено за клавиатурата, мишката и джойстика, той е подходящ за много решения, свързани със сдвояване на външни устройства с компютър.

Ако потребителят трябва да извърши нискоскоростен обмен на данни (до 64 kbit / s) и в същото време иска да намали времето, прекарано в досадното разработване на собствените си драйвери, тогава HID е напълно подходящ за него. Крайният резултат ще бъде просто и напълно модерно решение, базирано на стандартен USB софтуерен интерфейс с гарантирана поддръжка на всички разпространени софтуерни платформи.

Свойства на HID устройство

От гледна точка на организиране на софтуерна поддръжка за HID устройство, всичко изглежда доста привлекателно: за работа Windows контролможете бързо да създадете разбираем, компактен код, базиран на готови, доказани алгоритми. В същото време разработчикът ще има много време да внедри свой собствен протокол за обмен на данни от най-високо ниво, тъй като необходимото ниво на абстракция вече е организирано чрез протокола HID (виж таблицата). В допълнение, за програмиста е лесно да отстрани грешки в писмен протокол за обмен (разбира се, ако има работещо HID устройство) - поради относителната твърдост на самия протокол, достатъчно е просто да се разработи програма за компютърна поддръжка за устройство. Разбира се! Създателят на HID устройството вече се е заел с много работа.

Организация на обмена на данни между HID устройството и компютъра

За да опишем взаимодействието на HID устройство с компютър, ще използваме термина „хост“. В този случай се разбира като управляващо устройство в общата физическа архитектура на взаимодействие чрез USB протокола. И така, всички портове на компютъра са хостове. Можете да свържете различни USB устройства (флашки, мишки, уеб камери, фотоапарати и др.), които нямат хост към тях. Хостът осигурява откриване на устройство, свързване, прекъсване на връзката, конфигуриране, както и събиране на статистически данни и управление на енергията.

HID устройството може да зададе собствена честота на запитване, за да определи дали съдържа нови данни. Това означава, че дори при такова ниско ниво програмистът може да се довери на системата, тъй като честотата на запитване и други комуникационни параметри трябва да бъдат предварително зададени в програмата на контролера на HID устройството. Това отличава HID протокола от общото описание на USB 1.1 или USB 2.0, които нямат строги изисквания за организацията на протокола. Въпреки това, за конкретни задачи, които изискват повишено ниво на сигурност, може да бъде доста трудно да се отървете от цикличното анкетиране, когато постоянно се предават почти едни и същи блокове данни.

Функции за програмиране на HID устройство

HID устройствата имат специални дескриптори. Когато хостът определи, че устройството принадлежи към класа HID, той прехвърля контрола върху него на съответния драйвер. Предполага се, че по-нататъшният обмен на данни се извършва под негово ръководство.

В Windows системната услуга HidServ е отговорна за достъпа до HID устройства. Повече подробности за функциите на заявките към HID устройства и други характеристики на работата с HID драйвера са описани в работата на П. В. Агуров „USB интерфейс. Практика на използване и програмиране" (Санкт Петербург: BHV-Петербург, 2005).

Програмиране на HID устройства за " горно ниво»

Трудният живот на „приложните“ програмисти, работещи в Pascal, е улеснен от доказания HID модул. PAS, шел софтуер за hid. dll (Скрита потребителска библиотека - както е посочено в свойствата на файла). Коментарите към файла показват, че той е базиран на модулите hidsdi.h и hidpi.h от Microsoft. И самия HID файл. PAS е част от пакета JEDI().

За работа с HID устройство в Delphi средаза win32 се използва компонента TJvHidDeviceController, който е удобен глобален мениджър за достъп до HID устройства. И вече на негова основа можете да получите екземпляр на обект за работа с конкретно устройство.

Основни свойства и събития на компонента TJvHidDeviceController

Нека разгледаме по-подробно компонента TJvHidDeviceController. Събитието OnArrival се задейства, когато HID устройство влезе (свърже се) към системата, достъпът до устройството се предоставя в манипулатора на това събитие чрез екземпляр на класа TJvHidDevice. Простото събитие OnDeviceChange реагира на промените в състоянието на устройството; то само сигнализира за промени в системата. Събитието OnDeviceData се задейства, когато данните пристигнат от едно от HID устройствата и предават следното на манипулатора: HidDev: TJvHidDevice; - устройството, от което са получени данните;

Събитието OnDeviceDataError уведомява за грешка при трансфер на данни, като предава параметрите HidDev на процедурата за обработка: TJvHidDevice; - HID устройство и грешка: DWORD; - код на грешка. Събитието OnDeviceUnplug уведомява, че дадено устройство е премахнато от списъка с инсталирани в системата. Типовете манипулатори на събития на Plug и Unplug са еднакви (в изходния текст: TJvHidUnplugEvent = TJvHidPlugEvent). Обект от класа TJvHidDevice, съответстващ на HID устройството, се предава на манипулатора.

За последователно изброяване на HID устройствата, налични в системата чрез извикване на метода Enumerate, е предназначено събитието OnEnumerate, т.е. в манипулатора на събития намерените устройства се прехвърлят последователно като обекти. Това събитие е принудено от метода Enumerate, който се използва за „преминаване“ на съществуващи HID устройства през манипулатор, например, когато се преразглежда състоянието на HID устройствата по инициатива на хоста (компютъра).

Събитието OnRemoval се задейства, когато дадено устройство е физически премахнато от системата и има същия тип манипулатор TJvHidUnplugEvent като за OnDeviceUnplug. Функцията CountByProductName връща броя устройства, които съответстват на името на продукта, посочено в аргумента, а CountByVendorName връща името на производителя, посочено в аргумента.

Основни свойства и събития на класа TJvHidDevice

Класът TJvHidDevice е виртуално представяне на едно HID устройство. Нов обект от този клас може да бъде получен, както вече беше споменато, от събитието OnArrival или OnEnumerate. Функционалността на класовете TJvHidDeviceController и TJvHidDevice е частично дублирана, тъй като първият от тях интегрира общи инструменти за работа с набор от налични в системата HID устройства и механизъм за достъп до едно от тях. Едно устройство може да бъде уникално идентифицирано чрез неговите свойства SerialNumber, ProductName и VendorName. За да получите информация за пристигането на данни с помощта на такъв обект, можете да използвате събитието OnData. Данните се изпращат чрез метода WriteFile (в тесния смисъл - чрез функция). WriteFile е обвивка системна функция WriteFile(kernel32).

За да контролирате дали устройството е премахнато, трябва да зададете свой собствен манипулатор на събитието OnUnplug. Преди да започнете да обменяте данни с HID устройство, трябва да се уверите, че такъв обмен е възможен чрез HasReadWriteAccess. Този клас дори има отделно събитие OnDataError, когато възникне грешка при обмен на данни.

Сега нека разгледаме кодови фрагменти от „жив“ проект, който внедрява тестово клиентско приложение за организиране на обмен на данни с нестандартно устройство - базирани на HID пластмасови чип карти. В борбата за реализъм авторът си позволи да не изхвърля „допълнителни“ технологични кодови връзки от списъците.

Методът ScanDevices (списък 1) е предназначен да инициира процеса на търсене в системата за необходимото HID устройство. По-голямата част от кода, с изключение на извикването на метода Enumerate, е по избор и осигурява гъвкавост на приложението, например, за да тестова програмабеше възможно да се добави възможност за работа през интерфейс, различен от HID. Методът AddError показва информация за отстраняване на грешки в прозореца, докато програмата работи.

Списък 2 показва манипулатор на събития OnEnumerate за намиране на необходимото външно устройство. За простота ще приемем, че програмата може да работи само с едно устройство от вида, от който се нуждае.

Преди да обмислим по-нататъшното изпълнение на проекта, трябва да поговорим малко за възприетия формат за обмен на данни от най-високо ниво, т.е. за структурата, предназначена да бъде посредник между методите за получаване и предаване на данни и конкретния проблем на приложението, който се решава. Факт е, че тук разработчикът има възможност да реализира творческите си способности. Или по-скоро разработчици, защото процесът на създаване на нов протокол много често е двупосочен и първата цигулка се играе от този, на когото му е по-трудно да приложи алгоритъма за обмен. Като цяло, без значение какъв е протоколът за обмен, винаги е хубаво да се направи всяка софтуерна единица възможно най-визуална и самодостатъчна, дори за сметка на някои общоприети традиции. Защото най-доброто решение е това, което ще бъде реализирано за кратко време с минимална връзка към софтуерна средаи с големи възможностипо-нататъшно развитие. Въз основа на тези принципи е създаден протокол за обмен от най-високо ниво, където основната концепция е „команда“. Листинг 3 показва колко много авторът обича низови данни, които са го спасявали повече от веднъж по време на отстраняване на грешки. софтуерни модули. Колко чудесно е, че дори имаме тип String! Всички команди на протокола са разделени на категории (класове), в рамките на които има код на команда, който уникално характеризира нейното предназначение. Параметърът edParam се използва за изпращане на данни към устройството, а параметърът edAnswerData съдържа данни, получени от устройството. Типът низ на описаните членове на запис ви позволява свободно и ясно да манипулирате данни в HEX формат на низ. А най-хубавото е, че форматът на описания запис идеологически стои някъде по средата между прякото му предназначение и различните форми на представянето му (INI, HEX, XML и др.)

Изпълнението на командата, т.е. изпращането на данни към устройството, се реализира чрез изпращане на пакети данни с дължина 8 байта (списък 4). Тази дължина не е единственото решение; изборът е продиктуван от изискванията на протокола от по-високо ниво и може да бъде различен във всеки конкретен случай. Това е, както се казва, въпрос на вкус. Странният флаг IsUSBMode в метода ExecuteCommand (листинг 5 в PC World) е оставен като напомняне, че може да се наложи да използваме COM порт или някакъв друг интерфейс, вместо да работим с USB. В началото на изпратената група от данни към устройството се предава синхронизираща серия от произволно избран формат (например 3E3E3E2B), информирайки устройството, че има напълно легални данни на входа. Нека ви напомня, че в случая ние говорим зане толкова за HID, а за специфичен протокол от най-високо ниво, идеологически отделен от хардуера и предназначен за решаване на специфични проблеми с приложенията.

Манипулаторът GetDataExecutor за данни, получени от устройството (пакет от 8 байта) използва специално създадено събитие OnNewInputData, за да прехвърли първоначално обработените данни за по-нататъшна обработка, като посочва техните стари и нови стойности (Списък 6 на „World of PC Disk “). По този начин събитията за пристигане на необработени данни и индикацията за по-нататъшна обработка са отделени, което позволява добавянето на някакъв специфичен алгоритъм на ранен етап, за да предупреждава срещу погрешна, дублирана или ненужна входна информация.

Представените тук примери за работа с HID устройство илюстрират общата идея на статията - относителната лекота на програмиране на нестандартни HID устройства с помощта на Delphi.

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

Сега ще го създадем.

Отново има пример в пакета с решения на Microchip за нашия контролер, но аз го пренаписах по свой начин. Първо направих без да използвам GUI, а размерът на кода намаля 3-4 пъти. Което е много по-добро за учене. Принципът на действие обаче е същият. Кодът в стандартния пример от microchip работи точно като този.

Програмата е написана на C++. Проектът е компилиран в безплатната студентска версия на Visual C++ express 2010. Ще дам общи идеи и коментари за кода, но предполагам, че вече имате поне малко опит в програмирането на C++.

Така че нека започнем

Ето целия проект, включително връзката към изходния текст

За да четем и записваме данни през USB порта, трябва да получим указател към нашето устройство. Тъй като, за разлика от старите портове, може да има над сто свързани устройства, не е толкова лесно да се получи този индекс. За да направим това ще се обърнем към драйвери за windows, а именно SetupAPI. Между другото, веднага щом получим показалеца, ще комуникираме с USB порт, сякаш е файл.
Прехвърлянето на данни ще отнеме само няколко команди. Но ето подготовката!
Тъй като програмираме на C++, трябва да сме много внимателни с типовете данни.
Създайте конзолен проект за win32. И добавете единствения файл main.cpp там

Така че трябва да включим някои библиотеки.
#включи
#включи
#включи

Свързваме и външна библиотека:
#pragma коментар (lib, "Setupapi.lib")

Първата функция, описана в програмата, е getUSBHandle(). Описанието му е в коментарите към кода. И като цяло, основните коментари са дадени в кода. Той служи за намиране на нашето устройство и подготовка на указатели, така че да можем да пишем и четем от устройството.
С две думи тя използва стандартни прозорцифункции за достъп USB драйверии чрез тях получава указател към самото устройство.
Ако се интересувате какво правят всички тези функции и как, вижте MSDN или книгата на Агуров, която е в съдържанието. Какво е важно да знаем: всяко устройство има път и за нас е важно да го получим. Първо проверяваме дали идентификаторът отговаря на устройството, което търсим. И тогава намираме пътя на устройството. Търсим само сред устройства от клас HID. това е дефинирано в променливата Guid. Вижте останалото в коментарите по програмата
Следващата функция е writeReadUSB. Това е само помощна функция, която пише на нашето устройство. Моля, обърнете внимание, че писането и четенето на устройство, след като сме създали указател към него, се реализира с помощта на стандартните команди WriteFile и ReadFile
И след това виждаме основната функция, с която започва изпълнението на програмата. Извиква getUSBHandle, докато получим указател към устройството, след което чете командата от клавиатурата и в зависимост от нея прехвърля и чете данни от USB устройството.
Проектът на връзката по-горе съдържа изходния код с коментари и самата компилирана програма. Успех

Докато търсех грешка, попаднах на библиотеката hidapi. Той е междуплатформен. И само за работа със скрити устройства. Много лесен за използване. Нося проект за него. връзка .
Hidapi е изтеглен от официалния сайт. За да започнете проект, трябва да добавите setupapi.lib към линкера. проект->свойства->линкер->въвеждане и подписване на setupapi.lib там;
Успех
Намерих прилично описание на библиотеката тук: http://microsin.net/programming/PC/multi-platform-hid-api.html.
благодаря ви