Данный пример, показывает как создать свое USB HID устройство на микроконтроллере.
Этот USB девайс, демонстрирует передачу данных от компьютера, микроконтроллеру и обратно.
Схема устройства.

Конфигурация контроллера.

Как видно из схемы, USB устройство выполнено на микроконтроллере ATmega8 и содержит минимум деталей - все возложено на микроконтроллер, включая и обработку USB посылок.
При поступлении команды от компьютера, микроконтроллер зажигает или гасит светодиод HL1.
А при нажатии кнопки SB1 в устройстве, микроконтроллер передаст команду через шину USB компьютеру.
Программа для контроллера разработана в среде BASCOM-AVR.
Код программы (компилятор - BASCOM-AVR версии 2.0.7.7 или новее).
$regfile = "m8def.dat"
$crystal = 12000000
$hwstack = 40
$swstack = 40
$framesize = 50
$include "USB\USB_Config.bas"
$include "USB\Const_swusb-includes.bas"
Dim Buttons_current As Byte
Dim Buttons_last As Byte
Config Portb = Input
Config Portb.0 = Output
Config Portc = Input
Portb.0 = 0
' Разрешаем прерывания.
Enable Interrupts
Do
Call Usb_refresh()
' Получены данные от компьютера.
If _usb_status._usb_rxc = 1 Then
If _usb_status._usb_setup = 1 Then
' Обработка системных сообщений нулевой конечной точки.
Call Usb_processsetup(_usb_tx_status(1))
Elseif _usb_status._usb_endp1 = 1 Then
' Пришёл пакет данных из компьютера в 1 конечную точку.
Toggle _usb_rx_buffer(2)
Portb = _usb_rx_buffer(2) ' Запись данных в порт.
End If
' Признак готовности принять следующий пакет данных.
_usb_status._usb_rtr = 1
_usb_status._usb_rxc = 0
End If
Buttons_current = Pinc
Buttons_current = Buttons_current And 1
If Buttons_current <> Buttons_last Then
If _usb_tx_status2._usb_txc = 1 Then
Buttons_last = Buttons_current
If Buttons_current <> 0 Then
_usb_tx_buffer2(2) = 40
Else
_usb_tx_buffer2(2) = 20
End If
Call Usb_send(_usb_tx_status2(1) , 1) ' Передача в компьютер одного байта.
End If
End If
Loop
End
$include "USB\USB_Descriptor.bas"
$include "USB\USB_Subroutines.bas"Устройство управляется этой программой, написанной на PureBasic.

Ее исходный текст (компилятор - PureBasic версии 5.20 или новее).
#USB_PID=1
#USB_VID=$1234
Global W_DeviceHandle=0, R_DeviceHandle=0
XIncludeFile "HID_Module.pbi"
Procedure FindDevice_Timer()
Static Old_Test
Test=HID::TestDevice(#USB_PID, #USB_VID)
If Test<>Old_Test
Old_Test=Test
If Test
HID::CloseDevice(W_DeviceHandle)
HID::CloseDevice(R_DeviceHandle)
W_DeviceHandle=HID::OpenDevice(#USB_PID, #USB_VID)
R_DeviceHandle=HID::OpenDevice(#USB_PID, #USB_VID)
SetGadgetText(1,"Подключено HID устройство")
Else
HID::CloseDevice(W_DeviceHandle)
HID::CloseDevice(R_DeviceHandle)
W_DeviceHandle=0 : R_DeviceHandle=0
SetGadgetText(1,"Устройство не обнаруженно ( PID — "+Hex(#USB_PID)+"H; VID — "+Hex(#USB_VID)+"H) ")
SetGadgetText(5,"Нет")
EndIf
EndIf
EndProcedure
Procedure SendDevice(Command.w)
If W_DeviceHandle
HID::WriteDevice(W_DeviceHandle, @Command,2)
Else
MessageRequester("", "Нет связи с устройством!", #MB_OK|#MB_ICONWARNING)
EndIf
EndProcedure
Procedure Thread(*xx)
Dim InBuffer.b(2)
Repeat
If R_DeviceHandle
HID::ReadDevice(R_DeviceHandle, @InBuffer(), 2)
If InBuffer(1)=20
SetGadgetText(5,"Да")
ElseIf InBuffer(1)=40
SetGadgetText(5,"Нет")
EndIf
EndIf
Delay(10)
ForEver
EndProcedure
HID::HID_Init()
OpenWindow(0,0,0,320,100,"Пример работы с HID устройством",#PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered)
TextGadget(1,10,10,300,16,"Устройство не обнаруженно ( PID — "+Hex(#USB_PID)+"H; VID — "+Hex(#USB_VID)+"H )",#PB_Text_Center)
ButtonGadget(2,40,70,120,24,"Зажечь светодиод")
ButtonGadget(3,170,70,120,24,"Погасить светодиод")
TextGadget(4,50,40,98,16,"Кнопка нажата?")
StringGadget(5,140,36,40,20,"Нет",1|#PB_String_ReadOnly)
FindDevice_Timer()
HideWindow(0,0)
SetTimer_(WindowID(0),1,200,@FindDevice_Timer())
CreateThread(@Thread(),0)
Repeat
Event=WaitWindowEvent()
If Event=#PB_Event_Gadget
Select EventGadget()
Case 2
SendDevice($AA00)
Case 3
SendDevice($5500)
EndSelect
EndIf
Until Event=#PB_Event_CloseWindow
HID::HID_End()Скачать файлы (компьютерная программа, прошивка для микроконтроллера и их исходные тексты).
Дальнейшее развитие темы - USB HID устройство на ATmega32U4, с использованием аппаратного модуля USB. Простое USB HID устройство на ATmega32U4 (Arduino Pro Micro)
USB HID устройство на STM32F103C8T6 Простое USB HID устройство на STM32F103C8T6
