GD32实现USB HID自定义复合设备

本文详细介绍了如何在GD32微控制器上实现一个USB HID复合设备,通过两个不同的接口提供多种功能。首先介绍了复合设备的概念,然后讲解了开发准备、代码移植的步骤,包括修改USB控制引脚、添加串口调试、更新设备和配置描述符、以及修改相关处理函数。最终,成功编译并下载后,设备在主机上表现为两个独立的USB设备。
摘要由CSDN通过智能技术生成

复合设备是啥,通俗讲就是一个USB物理设备可以实现多个功能,在主机端可以看到多个设备。通常实现HID复合设备有两种方式。第一种是使用同一个接口,修改报告描述符,增加一个功能集合,同时需要使用报告ID来区分哪一个设备,这样主机端和设备端需要增加报告ID处理,但只需要两个端点来实现功能,对于端口资源较少的MCU可以使用;第二种是使用两个接口,每个接口对应不同的报告描述符,不需要特意使用报告ID来区分,但不同接口使用独立的端点。
本文章使用不同接口来实现,基于GD32例程开发。

  1. 开发准备
    (1)下载官方GD32F1x0_Firmware_Library_v3.1.0,使用GD32F1x0_Firmware_Library_v3.1.0\Projects\USBD\HID_custom工程
    (2)keil5添加GD系列
    (3)连接GDlink和串口工具

  2. 移植代码
    2.1 修改控制控制USBDP上拉电阻引脚,(内部无法直接控制上下拉,因此增加此电路,否则主机不会枚举设备)
    DP控制电路
    #define USB_PULLUP GPIOC //PORT
    #define USB_PULLUP_PIN GPIO_PIN_13 //PIN
    #define RCC_AHBPeriph_GPIO_PULLUP RCU_GPIOC //时钟

2.2 增加串口1输出调试信息,main函数里添加:
/* uart configuration */
gd_eval_com_init(EVAL_COM1);
添加如下代码实现printf功能

    int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM1, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE));
    return ch;
}
int main(void)
{
   
	
	
    /* system clocks configuration */
    rcu_config();

    /* keys configuration */
    key_config();

    /* leds configuration */
    led_config();
		//gd_eval_led_on(LED1);
    /* GPIO configuration */
    gpio_config();
	
	    /* uart configuration */
    gd_eval_com_init(EVAL_COM1);

    /* USB device configuration */
    usbd_core_init(&usb_device_dev);

    /* NVIC configuration */
    nvic_config();

    /* enabled USB pull-up */
    gpio_bit_reset(USB_PULLUP, USB_PULLUP_PIN);//使能上拉

    /* now the usb device is connected */
    usb_device_dev.status = USBD_CONNECTED;
		printf("a usart transmit test example!");
		
    while (1)
		{
   
		};
}

2.3 修改USB相关描述符
2.3.1 设备描述符:不需要修改

const usb_descriptor_device_struct device_descripter =
{
   
    .Header = 
     {
   
         .bLength = USB_DEVICE_DESC_SIZE, 
         .bDescriptorType = USB_DESCTYPE_DEVICE
     },
    .bcdUSB = 0x0200,
    .bDeviceClass = 0x00,
    .bDeviceSubClass = 0x00,
    .bDeviceProtocol = 0x00,
    .bMaxPacketSize0 = USBD_EP0_MAX_SIZE,
    .idVendor = USBD_VID,
    .idProduct = USBD_PID,
    .bcdDevice = 0x0200,
    .iManufacturer = USBD_MFC_STR_IDX,
    .iProduct = USBD_PRODUCT_STR_IDX,
    .iSerialNumber = USBD_SERIAL_STR_IDX,
    .bNumberConfigurations = USBD_CFG_MAX_NUM
};

2.3.2 配置描述符:需要增加第二个接口的接口描述符,端点描述符

const usb_descriptor_configuration_set_struct configuration_descriptor = 
{
   
    .Config = 
    {
   
        .Header = 
         {
   
             .bLength = sizeof(usb_descriptor_configuration_struct), 
             .bDescriptorType = USB_DESCTYPE_CONFIGURATION 
         },
        .wTotalLength = CUSTOMHID_CONFIG_DESC_SIZE,
        .bNumInterfaces = 0x02,      //==接口数修改为2==
        .bConfigurationValue = 0x01,
        .iConfiguration = 0x00,
        .bmAttributes = 0xc0,
        .bMaxPower = 0x32
    },

    .HID_Interface = 
    {
   
        .Header = 
         {
   
             .bLength = sizeof(usb_descriptor_interface_struct), 
             .bDescriptorType = USB_DESCTYPE_INTERFACE 
         },
        .bInterfaceNumber = 0x00, //==接口序号为0,表示第一个接口==
        .bAlternateSetting = 0x00,
        .bNumEndpoints = 0x02, //==使用两个接口==
        .bInterfaceClass = 0x03,
        .bInterfaceSubClass = 0x00,
        .bInterfaceProtocol = 0x00,
        .iInterface 
  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值