39. printf("0x%02X",recvDataBuf[i+1]);
40. }
41. printf("\n\r");
42.}
复制代码
源码下载
STM32程序下载:
stm32_usb_hid.zip (2.62MB,下载次数:
6366)
STM32F105/107版本源码下载:
usb_hid.rar (2.16MB,下载次数:
5175)
HID上位机程序下载(VS2010):
STM32_HID_PC_Driver.zip (259.02KB,下载次数:
2590)
HID上位机程序下载(VS2008):
PC_HID.zip (133.6KB,下载次数:
1924)
USB开发相关资料下载
USB2.0技术规范(中文).pdf (2.59MB,下载次数:
2991)
Windows主机端与自定义USB_HID设备通信详解.pdf (259.12KB,下载次数:
1934)
STM32F10xxxUSB-FS-Devicefirmwarelibrary.pdf (1.27MB,下载次数:
2412)
STM32F10xxxUSB开发工具包.pdf (978.66KB,下载次数:
2588)
STM32_USB-FS-Device_Lib_V3.0.1.zip (822.59KB,下载次数:
2068)
STM32_usb固件库.pdf (978.66KB,下载次数:
2457)
基于STM32的USB程序开发笔记.pdf (2.42MB,下载次数:
3155)
深入解析STM32_USB-FS-Device_Lib库.pdf (697.35KB,下载次数:
1958)
描述符在文件usb_desc.c中。
第一个要改的是设备描述符。
设备描述符的结构都标准的,长度也是固定的。
范例中的USB设备描述符如下:
/*USBStandardDeviceDescriptor*/
constu8Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DESC]=
{
0x12, /*bLength*/
USB_DEVICE_DESCRIPTOR_TYPE,/*bDescriptorType*/
0x00, /*bcdUSB*/
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
0x40, /*bMaxPacketSize40*/
0x83, /*idVendor(0x0483)*/
0x04,
0x10, /*idProduct=0x5710*/
0x57,
0x00, /*bcdDevicerel.2.00*/
0x02,
1, /*Indexofstringdescriptordescribing
manufacturer*/
2, /*Indexofstringdescriptordescribing
product*/
3, /*Indexofstringdescriptordescribingthe
deviceserialnumber*/
0x01 /*bNumConfigurations*/
};/*Joystick_DeviceDescriptor*/
我们只需要修改这里的idVendor(即VID)和idProduct(即PID)即可。
它们是用来供电脑端识别设备以加载驱动用的,所以必须不能跟现有的设备相冲突。
VID和PID都是两字节,低字节在前,高字节在后。
例如这里的VID为0x0483,写在里面就是0x83,0x04。
我们将VID改成0x1234,将PID改成0x4321,即:
0x34,0x12,0x21,0x43。
然后再修改配置描述符集合。
配置描述符集合包括配置描述符、接口描述符、类特殊描述符(这里是HID描述符)、以及端点描述符。
如果你需要增加端点,那么在最后增加就行了,注意要记得修改JOYSTICK_SIZ_CONFIG_DESC的值为配置描述符集合的长度。
第一部分为配置描述符。
通常这里不需要修改,除非你要改成该配置有多个接口(USB复合设备),那么应该修改bNumInterfaces,需要多少个就改成多少个,这里只有一个接口,所以值为1。
第二部分为接口描述符,在接口描述符中决定该接口所实现的功能,例如HID设备,或者是大容量存储设备等等。
其中bInterfaceNumber为该接口的编号,从0开始。
这里只有一个接口,所以它的值为0,如果又更多的接口,则依次编号。
注意一个接口完整结束(包括该接口下的类特殊描述符和端点描述符)后,才开始一个新的接口。
bNumEndpoints为该接口所使用的端点数目(不包括端点0),原来的程序是实现鼠标功能的,所以只有一个输入端点。
我们这里增加一个输出端点,用来控制LED(键盘上有大写字母锁定、小键盘数字键锁定等指示灯),因此将bNumEndpoints改为2。
bInterfaceClass为接口所使用的类,这里指定为HID设备,USB键盘和鼠标都是HID设备,这里不用修改,如果你要实现其它设备,请根据USB协议所规定的类来修改。
bInterfaceSubClass为接口所使用的子类,在HID设备类下规定了两种子类,系统引导时能用的和不能用的,这里为1,表示系统引导时能使用。
bInterfaceProtocol为接口的协议,原来为鼠标,这里改为1,键盘。
第三部分为HID描述符,只有HID设备才有,如果你要修改成其它设备,则用其它设备的类特殊描述符代替或者没有,在这里不用做修改。
第四部分为输入端点1的端点描述符,原来代码中,设置的端点最大包长度(wMaxPacketSize)为4字节,我们将其改成8字节。
另外,我们再增加一个输出端点1,将最后的输入端点1描述符复制一份,然后修改地址(bEndpointAddress)为0x01,这表示该端点为输出端点,地址为1。
由bEndpointAddress的最高位表示方向,1为输入,0为输出,最后4位表示地址。
最后,要记得在usb_desc.h文件中修改JOYSTICK_SIZ_CONFIG_DESC的长度为41,因为我们增加了7字节。
实际修改好的配置描述符集合如下:
/*USBConfigurationDescriptor*/
/*AllDescriptors(Configuration,Interface,Endpoint,Class,Vendor*/
constu8Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC]=
{
//以下为配置描述符
0x09,/*bLength:
ConfiguationDescriptorsize*/
USB_CONFIGURATION_DESCRIPTOR_TYPE,/*bDescriptorType:
Configuration*/
JOYSTICK_SIZ_CONFIG_DESC,
/*wTotalLength:
Bytesreturned*/
0x00,
0x01, /*bNumInterfaces:
1interface*/
0x01, /*bConfigurationValue:
Configurationvalue*/
0x00, /*iConfiguration:
Indexofstringdescriptordescribing
theconfiguration*/
0xC0, /*bmAttributes:
selfpowered*/
0x32, /*MaxPower100mA:
thiscurrentisusedfordetectingVbus*/
//以下为接口描述符
/**************DescriptorofJoystickMouseinterface****************/
/*09*/
0x09, /*bLength:
InterfaceDescriptorsize*/
USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType:
Interfacedescriptortype*/
0x00, /*bInterfaceNumber:
NumberofInterface*/
0x00, /*bAlternateSetting:
Alternatesetting*/
0x02, /*bNumEndpoints*/
0x03, /*bInterfaceClass:
HID*/
0x01, /*bInterfaceSubClass:
1=BOOT,0=noboot*/
0x01, /*bInterfaceProtocol:
0=none,1=keyboard,2=mouse*/
0, /*iInterface:
Indexofstringdescriptor*/
//以下为HID描述符
/********************DescriptorofJoystickMouseHID********************/
/*18*/
0x09, /*bLength:
HIDDescriptorsize*/
HID_DESCRIPTOR_TYPE,/*bDescriptorType:
HID*/
0x00, /*bcdHID:
HIDClassSpecreleasenumber*/
0x01,
0x00, /*bCountryCode:
Hardwaretargetcountry*/
0x01, /*bNumDescriptors:
NumberofHIDclassdescriptorstofollow*/
0x22, /*bDescriptorType*/
JOYSTICK_SIZ_REPORT_DESC,/*wItemLength:
TotallengthofReportdescriptor*/
0x00,
//以下为输入端点1描述符
/********************DescriptorofJoystickMouseendpoint********************/
/*27*/
0x07, /*bLength:
EndpointDescriptorsize*/
USB_ENDPOINT_DESCRIPTOR_TYPE,/*bDescriptorType:
*/
0x81, /*bEndpointAddress:
EndpointAddress(IN)*/
0x03, /*bmAttributes:
Interruptendpoint*/
0x08, /*wMaxPacketSize:
8Bytemax*/
0x00,
0x20, /*bInterval:
PollingInterval(32ms)*/
//以下为输出端但1描述符
/*34*/
0x07, /*bLength:
EndpointDescriptorsize*/
USB_ENDPOINT_DESCRIPTOR_TYPE,/*bDescriptorType:
*/
0x01, /*bEndpointAddress:
EndpointAddress(OUT)*/
0x03, /*bmAttributes:
Interruptendpoint*/
0x08, /*wMaxPacketSize:
8Bytemax*/
0x00,
0x20, /*bInterval:
PollingInterval(32ms)*/
/*41*/
};
接下来,还需要修改报告描述符,报告描述符比较复杂,这里就不详述了,直接给出修改好的报告描述符如下:
constu8Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC]=
{
0x05,0x01,//USAGE_PAGE(GenericDesktop)
0x09,0x06,//USAGE(Keyboard)
0xa1,0x01,//COLLECTION(Application)
0x05,0x07,// USAGE_PAGE(Keyboard/Keypad)
0x19,0xe0,// USAGE_MINIMUM(KeyboardLeftControl)
0x29,0xe7,// USAGE_MAXIMUM(KeyboardRightGUI)
0x15,0x00,// LOGICAL_MINIMUM(0)
0x25,0x01,// LOGICAL_MAXIMUM
(1)
0x95,0x08,// REPORT_COUNT(8)
0x75,0x01,// REPORT_SIZE
(1)
0x81,0x02,// INPUT(Data,Var,Abs)
0x95,0x01,// REPORT_COUNT
(1)
0x75,0x08,// REPORT_SIZE(8)
0x81,0x03,// INPUT(Cnst,Var,Abs)
0x95,0x06,// REPORT_COUNT(6)
0x75,0x08,// REPORT_SIZE(8)
0x25,0xFF,// LOGICAL_MAXIMUM(255)
0x19,0x00,// USAGE_MINIMUM(Reserved(noeventindicated))
0x29,0x65,// USAGE_MAXIMUM(KeyboardApplication)
0x81,0x00,// INPUT(Data,Ary,Abs)
0x25,0x01,// LOGICAL_MAXIMUM
(1)
0x95,0x05,// REPORT_COUNT(5)
0x75,0x01,// REPORT_SIZE
(1)
0x05,0x08,// USAGE_PAGE(LEDs)
0x19,0x01,// USAGE_MINIMUM(NumLock)
0x29,0x02,// USAGE_MAXIMUM(CapsLock)
0x91,0x02,// OUTPUT(Data,Var,Abs)
0x