硬件开发板:STM32F103C8

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

软件平台

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

好了现在开始利用STM32CubeMX来生成我们的工程

1、新建工程

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

选择MCU的型号

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

选择选择时钟

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

开启usb的模块

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

选择USB的类

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

配置时钟树(主要是设置usb的48Mhz)

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

设置工程路径和编译环境

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

打开工程

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

我们现在在main.c进行修改

/* USER CODE BEGIN Includes */
#include "usbd_hid.h"
/* USER CODE END Includes */
  /* USER CODE BEGIN 1 */

  // HID Mouse
struct mouseHID_t {
uint8_t buttons;
int8_t x;
int8_t y;
int8_t wheel;
};
struct mouseHID_t mouseHID; mouseHID.buttons = ;
mouseHID.x = ;
mouseHID.y = ;
mouseHID.wheel = ; /* USER CODE END 1 */
  /* USER CODE BEGIN 3 */
 
  // Send HID report
    mouseHID.x = 10;
    USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)&mouseHID, sizeof(struct mouseHID_t));
    HAL_Delay(1000);
  }
  /* USER CODE END 3 */

编译下载后复位

在电脑设备管理中可以看到一个新的USB输入设备(到这部时候可以看到我们的STM32的USB枚举成功)

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

可以看到我们鼠标光标移动

如果出现

***JLink Error: Bad JTAG communication: Write to IR: Expected 0x1, got 0xF (TAP Command : 10) @ Off 0x5.

将在HAL_MspInit()代码中 __HAL_AFIO_REMAP_SWJ_DISABLE();给注释掉

为了回顾之前的浅析USB HID ReportDesc (HID报告描述符)

我们将对static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE]进行分析

源码

__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE]  __ALIGN_END =
{
0x05, 0x01,
0x09, 0x02,
0xA1, 0x01,
0x09, 0x01, 0xA1, 0x00,
0x05, 0x09,
0x19, 0x01,
0x29, 0x03, 0x15, 0x00,
0x25, 0x01,
0x95, 0x03,
0x75, 0x01, 0x81, 0x02,
0x95, 0x01,
0x75, 0x05,
0x81, 0x01, 0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x09, 0x38, 0x15, 0x81,
0x25, 0x7F,
0x75, 0x08,
0x95, 0x03, 0x81, 0x06,
0xC0, 0x09,
0x3c, 0x05,
0xff, 0x09, 0x01, 0x15,
0x00, 0x25,
0x01, 0x75,
0x01, 0x95, 0x02, 0xb1,
0x22, 0x75,
0x06, 0x95,
0x01, 0xb1, 0x01, 0xc0
};

注释整理后

__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE]  __ALIGN_END =
{
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xC0, // END_COLLECTION
0x09, 0x3c, // USAGE (Motion Wakeup)
0x05, 0xff, // USAGE_PAGE (0xff) //在HID Usage Tables 1.12中15 页中UASE PAGES表格为Reserved
0x09, 0x01, // USAGE (SMBBatteryMode)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x02, // REPORT_COUNT (2)
0xb1, 0x22, // FEATURE(Data,Var,Abs,NPrf)
0x75, 0x06, // REPORT_SIZE (6)
0x95, 0x01, // REPORT_COUNT (1)
0xb1, 0x01, // FEATURE(Cnst,Ary,Abs)
0xc0 // END_COLLECTION
};

现在各位同学请翻开《Universal Serial Bus Specification Revision 2.0 》<9.5 Descriptors >

我们参考Table 9-8. Standard Device Descriptor 将__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] 数据也按照这个表格填入数据

__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC]的源码如下:

/* USB Standard Device Descriptor */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
0x00, /* bcdUSB */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idVendor*/
HIBYTE(USBD_PID_FS), /*idVendor*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
} ;
/* USB_DeviceDescriptor */

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

这个分析起来有点麻烦

/* USB HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_HID_CONFIG_DESC_SIZ,
/* wTotalLength: Bytes returned */
0x00,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ /************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /*bLength: Interface Descriptor size*/
USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
0x00, /*bInterfaceNumber: Number of Interface*/
0x00, /*bAlternateSetting: Alternate setting*/
0x01, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
, /*iInterface: Index of string descriptor*/
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x11, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
0x00,
HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/
/* 34 */
} ;

Table 9-10. Standard Configuration Descriptor

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

Table 9-12. Standard Interface Descriptor

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

这边需要参考<Device Class Definition for Human Interface Devices (HID) Version 1.11 > "6.2.1 HID Descriptor"

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

Table 9-13. Standard Endpoint Descriptor

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

现在利用软件直接看这个上面的信息

利用STM32CubeMX来生成USB_HID_Mouse工程-LMLPHP

Connection StatusDevice connected
Current Configuration1
SpeedFull (12 Mbit/s)
Device Address12
Number Of Open Pipes1
Device Descriptor STM32 Human interface
OffsetFieldSizeValueDescription
0bLength112h 
1bDescriptorType101hDevice
2bcdUSB20200hUSB Spec 2.0
4bDeviceClass100hClass info in Ifc Descriptors
5bDeviceSubClass100h 
6bDeviceProtocol100h 
7bMaxPacketSize0140h64 bytes
8idVendor20483hSGS Thomson Microelectronics
10idProduct2572Bh 
12bcdDevice20200h2.00
14iManufacturer101h"STMicroelectronics"
15iProduct102h"STM32 Human interface"
16iSerialNumber103h"00000000001A"
17bNumConfigurations101h 
Configuration Descriptor 1
OffsetFieldSizeValueDescription
0bLength109h 
1bDescriptorType102hConfiguration
2wTotalLength20022h 
4bNumInterfaces101h 
5bConfigurationValue101h 
6iConfiguration100h 
7bmAttributes1E0hSelf Powered, Remote Wakeup
 4..0: Reserved ...00000  
 5: Remote Wakeup ..1..... Yes
 6: Self Powered .1...... Yes
 7: Reserved (set to one)
(bus-powered for
1.0)
 1.......  
8bMaxPower132h100 mA
Interface Descriptor 0/0 HID,
1 Endpoint
OffsetFieldSizeValueDescription
0bLength109h 
1bDescriptorType104hInterface
2bInterfaceNumber100h 
3bAlternateSetting100h 
4bNumEndpoints101h 
5bInterfaceClass103hHID
6bInterfaceSubClass101hBoot Interface
7bInterfaceProtocol102hMouse
8iInterface100h 
HID Descriptor
OffsetFieldSizeValueDescription
0bLength109h 
1bDescriptorType121hHID
2bcdHID20111h1.11
4bCountryCode100h 
5bNumDescriptors101h 
6bDescriptorType122hReport
7wDescriptorLength2004Ah74 bytes
Endpoint Descriptor 81 1 In,
Interrupt, 10 ms
OffsetFieldSizeValueDescription
0bLength107h 
1bDescriptorType105hEndpoint
2bEndpointAddress181h1 In
3bmAttributes103hInterrupt
 1..0: Transfer Type ......11 Interrupt
 7..2: Reserved 000000..  
4wMaxPacketSize20004h4 bytes
6bInterval10Ah10 ms
Interface 0 HID Report
Descriptor
Mouse
Item Tag (Value)Raw Data
Usage Page (Generic Desktop)05 01 
Usage (Mouse)09 02 
Collection (Application)A1 01 
    Usage (Pointer)09 01 
    Collection (Physical)A1 00 
        Usage Page (Button)05 09 
        Usage Minimum (Button 1)19 01 
        Usage Maximum (Button 3)29 03 
        Logical Minimum (0)15 00 
        Logical Maximum (1)25 01 
        Report Count (3)95 03 
        Report Size (1)75 01 
        Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)81 02 
        Report Count (1)95 01 
        Report Size (5)75 05 
        Input (Cnst,Ary,Abs)81 01 
        Usage Page (Generic Desktop)05 01 
        Usage (X)09 30 
        Usage (Y)09 31 
        Usage (Wheel)09 38 
        Logical Minimum (-127)15 81 
        Logical Maximum (127)25 7F 
        Report Size (8)75 08 
        Report Count (3)95 03 
        Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit)81 06 
    End CollectionC0 
    Usage (Motion Wakeup)09 3C 
    Usage Page05 FF 
    Usage09 01 
    Logical Minimum (0)15 00 
    Logical Maximum (1)25 01 
    Report Size (1)75 01 
    Report Count (2)95 02 
    Feature
(Data,Var,Abs,NWrp,Lin,NPrf,NNul,NVol,Bit)
B1 22 
    Report Size (6)75 06 
    Report Count (1)95 01 
    Feature
(Cnst,Ary,Abs,NWrp,Lin,Pref,NNul,NVol,Bit)
B1 01 
End CollectionC0 
04-30 05:17