【GD32F427开发板试用】+使用USBFS轻松实现HID键盘应用

这篇具有很好参考价值的文章主要介绍了【GD32F427开发板试用】+使用USBFS轻松实现HID键盘应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:不锈钢铁侠

前言

最近有项目需要用到键盘自动输入功能,提升工作效率。故使用该开发板实现自定义输入内容并通过按键控制自动通过usb输出。

简介

在官方GD32F4xx_Firmware_Library_V3.0.2 里的example上进行修改,使用外设分别有USB device(HID)、gpio(KEY,LED)、time2(usb)

项目结构

gd32 hid,兆易创新GD32 MCU,网络

Application--用户文件  
CMSIS---CMSIS文件  
GD32F4xx_StdPeriph_Driver--外设驱动  
USB_Drivers--USB核心驱动文件  
USB_Device--USB设备驱动  
USB_Class----USB类文件  
Startup--启动文件

USB接口使用(HID按键)

USB HID类是USB设备的一个标准设备类,包括的设备非常多。HID类设备定义它属于人机交互操作的设备,用于控制计算机操作的一些方面,如USB鼠标、USB键盘、USB游戏操纵杆等。但HID设备类不一定要有人机接口,只要符合HID类别规范的设备都是HID设备。

USB HID设备的一个好处就是操作系统自带了HID类的驱动程序,而用户无需去开发驱动程序,只要使用API系统调用即可完成通信。

HID设备的描述符除了**5个USB的标准描述符(设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符)**外,还包括三个HID设备类特定的描述符:HID描述符、报告描述符(Report)、实体描述符(Physical)。

standard_hid_core.C

//设备描述符
//设备描述符主要包括厂商ID(vendorID)和产品ID(productID)、USB协议等内容。一个设备只有一个设备描述符。

__ALIGN_BEGIN const usb_desc_dev hid_dev_desc __ALIGN_END =
{
    .header =
    {
        .bLength          = USB_DEV_DESC_LEN,//描述符长度(18字节)
        .bDescriptorType  = USB_DESCTYPE_DEV//描述符类型(设备描述符为0x01)
    },
    .bcdUSB                = 0x0200U,//设备使用的USB协议版本
    .bDeviceClass          = 0x00U,//类代码
    .bDeviceSubClass       = 0x00U,//子类代码
    .bDeviceProtocol       = 0x00U,//设备使用的协议
    .bMaxPacketSize0       = USB_FS_EP0_MAX_LEN,//端点0最大包长
    .idVendor              = USBD_VID,//厂商ID
    .idProduct             = USBD_PID,//产品ID
    .bcdDevice             = 0x0100U,//设备版本号
    .iManufacturer         = STR_IDX_MFC,//描述厂商的字符串的索引
    .iProduct              = STR_IDX_PRODUCT,//描述产品的字符串的索引
    .iSerialNumber         = STR_IDX_SERIAL,//产品序列号字符串的索引
    .bNumberConfigurations = USBD_CFG_MAX_NUM//可能的配置数
};


//配置描述符
//配置描述符,定义了设备的配置信息。一个设备可以有多个配置描述符。配置描述符描述了该配置的接口数、供电模式等信息。
__ALIGN_BEGIN const usb_hid_desc_config_set hid_config_desc __ALIGN_END = 
{
    .config =
    {
        .header =
        {
            .bLength         = sizeof(usb_desc_config),//该描述符字节数长度(9字节)
            .bDescriptorType = USB_DESCTYPE_CONFIG//描述符类型(设备描述符为0x01)
        },
        .wTotalLength         = USB_HID_CONFIG_DESC_LEN,//此配置信息的总长度,(包括配置,接口,端点和设备类及厂商定义的描述符)
        .bNumInterfaces       = 0x01U,//该配置所支持的接口个数
        .bConfigurationValue  = 0x01U,//在SetConfiguration()请求中用做参数来选定此配置
        .iConfiguration       = 0x00U,//描述此配置的字串描述表索引
        .bmAttributes         = 0xA0U,//配置特性
        .bMaxPower            = 0x32U//在此配置下的总线电源耗费量 2mA为一个单位
    },
//接口描述符
//接口描述符描述了该接口的端点数目、以及子类代码等。由配置描述符可知一个设备可以有多个接口描述符。
    .hid_itf =
    {
        .header =
        {
            .bLength         = sizeof(usb_desc_itf),
            .bDescriptorType = USB_DESCTYPE_ITF
        },
        .bInterfaceNumber     = 0x00U,
        .bAlternateSetting    = 0x00U,
        .bNumEndpoints        = 0x01U,
        .bInterfaceClass      = USB_HID_CLASS,
        .bInterfaceSubClass   = USB_HID_SUBCLASS_BOOT_ITF,//bios可认到
        .bInterfaceProtocol   = USB_HID_PROTOCOL_KEYBOARD,//键盘
        .iInterface           = 0x00U
    },
//HID描述符描述符

    .hid_vendor =
    {
        .header =
        {
            .bLength         = sizeof(usb_desc_hid),
            .bDescriptorType = USB_DESCTYPE_HID
        },
        .bcdHID               = 0x0111U,
        .bCountryCode         = 0x00U,
        .bNumDescriptors      = 0x01U,
        .bDescriptorType      = USB_DESCTYPE_REPORT,
        .wDescriptorLength    = USB_HID_REPORT_DESC_LEN,
    },

    .hid_epin =
    {
        .header =
        {
            .bLength         = sizeof(usb_desc_ep),
            .bDescriptorType = USB_DESCTYPE_EP
        },
        .bEndpointAddress     = HID_IN_EP,
        .bmAttributes         = USB_EP_ATTR_INT,
        .wMaxPacketSize       = HID_IN_PACKET,
        .bInterval            = 0x10U
    }
};

键值发送函数

STANDARD_HID_CORE.H

typedef struct {
    uint32_t protocol;
    uint32_t idle_state;
/*
 * buffer[0] - bit0: Left CTRL
 *           -bit1: Left SHIFT
 *           -bit2: Left ALT
 *           -bit3: Left GUI
 *           -bit4: Right CTRL
 *           -bit5: Right SHIFT
 *           -bit6: Right ALT
 *           -bit7: Right GUI 
 * buffer[1] - Padding = Always 0x00
 * buffer[2] - Key 1
 * buffer[3] - Key 2
 * buffer[4] - Key 3
 * buffer[5] - Key 4
 * buffer[6] - Key 5
 * buffer[7] - Key 6
 */
    uint8_t data[HID_IN_PACKET];//用于传输键盘参数的,Byte0是传控制键,Byte1是保留键,不用改;Byte3~byte7都可以存放传输的按键值。
    __IO uint8_t prev_transfer_complete;
} standard_hid_handler;

键盘发送给PC的数据每次8个字节
BYTE1 BYTE2 BYTE3 BYTE4 BYTE5 BYTE6 BYTE7 BYTE8

定义分别是:

BYTE1 –
|–bit0: Left Control是否按下,按下为1
|–bit1: Left Shift 是否按下,按下为1
|–bit2: Left Alt 是否按下,按下为1
|–bit3: Left GUI 是否按下,按下为1
|–bit4: Right Control是否按下,按下为1
|–bit5: Right Shift 是否按下,按下为1
|–bit6: Right Alt 是否按下,按下为1
|–bit7: Right GUI 是否按下,按下为1

BYTE2 – 暂不清楚,有的地方说是保留位
BYTE3–BYTE8 – 这六个为普通按键

例如:键盘发送一帧数据 02 00 0x04 0x05 00 00 00 00
表示同时按下了Left Shift + ‘a’+‘b’三个键

void MYhid_key_data_send(usb_core_driver *udev)
{
 standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE];
  if (hid->prev_transfer_complete)
  {
    hid->data[2]=0x04;//将‘a’存入数据帧
    if (0U != hid->data[2])
      {
          hid_report_send(udev, hid->data, HID_IN_PACKET);//发送键值
      }
  } 
}

main函数

main.c

int main(void)
{
    
        
    systick_config();
    usb_gpio_config();
    usb_rcu_config();
    usb_timer_init();
        LED1_init();
    hid_itfop_register(&hid_keyboard, &fop_handler);

    usbd_init(&hid_keyboard,
#ifdef USE_USB_FS
              USB_CORE_ENUM_FS,
#elif defined(USE_USB_HS)
              USB_CORE_ENUM_HS,
#endif
              &hid_desc,
              &usbd_hid_cb);
    usb_intr_config();

    /* check if USB device is enumerated successfully */
    while(USBD_CONFIGURED != hid_keyboard.dev.cur_status)
    {
    }

    while(1)
    {

        //  fop_handler.hid_itf_data_process(&hid_keyboard);
                if(k==SET)
                {
                
                    gpio_bit_set(GPIOC, GPIO_PIN_6);
                    hid_key_data_send(&hid_keyboard,KEY_H);
                    hid_key_data_send(&hid_keyboard,KEY_E);
                    hid_key_data_send(&hid_keyboard,KEY_L);
                    hid_key_data_send(&hid_keyboard,KEY_L);
                    hid_key_data_send(&hid_keyboard,KEY_O);
                    hid_key_data_send(&hid_keyboard,KEY_SPACE);
                    hid_key_data_send(&hid_keyboard,KEY_G);
                    hid_key_data_send(&hid_keyboard,KEY_D);        
                    hid_key_data_send(&hid_keyboard,KEY_3);
                    hid_key_data_send(&hid_keyboard,KEY_2);    
                    
                    hid_key_data_send_shift(&hid_keyboard,KEY_1);    
                    hid_key_data_send(&hid_keyboard,KEY_ENTER);
                    k=0;
                    gpio_bit_reset(GPIOC, GPIO_PIN_6);
                }


    }
}

代码下载(文末也可以下载)

链接:https://pan.baidu.com/s/1Ey7qg5tBUQPb3ERa7M6rcQ?pwd=gd32提取码: gd32

视频演示

https://www.bilibili.com/video/BV1Be4y1T74q​www.bilibili.com/video/BV1Be4y1T74q

参考资料

GD32F4XX固件库下载
HID键盘值参考
hid键盘值参考
键盘发送数据帧详解文章来源地址https://www.toymoban.com/news/detail-518060.html

到了这里,关于【GD32F427开发板试用】+使用USBFS轻松实现HID键盘应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GD32F303高级定时器输出互补PWM-开发笔记

    ◼ 总通道数:4; ◼ 计数器宽度:16位; ◼ 时钟源可选:内部时钟,内部触发,外部输入,外部触发; ◼ 多种计数模式:向上计数,向下计数和中央计数; ◼ 正交编码器接口:被用来追踪运动和分辨旋转方向和位置; ◼ 霍尔传感器接口:用来做三相电机控制; ◼ 可编程

    2024年02月09日
    浏览(62)
  • 关于STM32F4和GD32F4以太网,LAN8720+lwip+freemodbus,实现modbus tcp

    关于STM32F4和GD32F4以太网,LAN8720+lwip+freemodbus 这里使用了大佬 小灰灰搞电子 的代码,文章看 STM32F407+LAN8720移植Lwip和freeModbus实现MODBUS TCP 代码看 STM32F407+LAN8720+LWIP移植freemodbus TCP.zip 他的代码是基于正点原子F407的板子开发的,如果是别的板子,需要修改引脚 小灰灰的代码里,没

    2024年02月14日
    浏览(39)
  • GD32F303基于USBD库的usb custom hid 双向通讯实现

    默认已经建立好需要移植的GD32F303空白工程 环境:keil   GD库版本: V2.1.4 通讯工具: 链接:https://pan.baidu.com/s/1Ukuy0u52C9ufPGz9QcHONA  提取码:d9rf 正文开始 USBD库植步骤: 找到GD官网的软件包 本文中用的是GD32F30x_Firmware_Library_V2.1.4 将FirmwareGD32F30x_usbd_library 文件夹全部拷贝至工程

    2023年04月09日
    浏览(44)
  • GD32F4单片机实现接收超时中断+DMA实现串口的不定长接收和DMA发送

    环形缓冲区+定时器超时中断的方式 优点 环形缓冲区可以接收多帧数据 数据帧超时间隔可以设置 缺点 设备任务比较繁重时,使用中断接收可能会丢失数据。尤其是在长时间关闭中断或者串口中断优先级不高时 频繁进出中断。在使用RTOS的系统中,每收到一个数据就会进行一

    2024年02月15日
    浏览(63)
  • [GD32F4]基于GD32固件库移植cherryusb[STM32F4]

    [GD32F4]基于GD32固件库移植cherryusb[STM32F4] 使用开发板是淘宝买的不知名开发板,没什么好说的,具体的型号是GD32F450VET6。 使用的cherryusb版本是0.9.0版本。 使用的GD32官方固件库版本是:GD32F4xx_Firmware_Library_V3.0.4 cherryusb最牛的地方在于抛弃掉所有的依赖,只需要知道芯片的usb中断

    2024年02月06日
    浏览(52)
  • GD32F4移植STM32F4

    近期在项目中采用了GD32F407VET6替换原项目中的STM32F407VET6,网传GD的兼容性很好,之前也用F1系统的替换了一下,按照CSND各位大佬的经验一步步改进了代码,测试直接通过,现在也一直在项目中实际应用了,一直没有出问题。 所以这SMT时,嘉立创没有STM的货果断换成了GD,可换时

    2024年02月16日
    浏览(83)
  • GD32F4(9):GD32f4出现上电不工作,必须按复位程序才能跑起来

    绘制一个gd32450的pcb板子,结果烧录程序后发生下面事情: 上电程序不能正常启动或者偶尔可以正常启动一次,很随机。 当上电后程序不启动的时候,我再按一下mcu的reset按键,程序就能正常启动了。 当我debug调试的时候,回回都能正常启动,根本定位不到问题 首先在板子里

    2023年04月08日
    浏览(72)
  • GD32F103输入捕获

    GD32F103输入捕获程序,经过多次测试,终于完成了。本程序将TIMER2_CH2通道映射到PB0引脚,捕获PB0引脚低电平脉冲时间宽度。PB0是一个按钮,第1次按下采集一个值保存到TIMER2_CountValue1中,第2次按下采集一个值保存到TIMER2_CountValue2中,然后计算其低电平时间宽度。 网上也有人写

    2024年02月14日
    浏览(46)
  • 【GD32F303】星空派介绍

    一、开发板介绍 星空派(GD)开发板是由旗点科技推出的一款GD32开发板,板载GD32F303ZET6芯片,可直接替代STM32F103和GD32F103系列。 支持RT-Thread操作系统等,支持WiFi、4G、loRa等物联通信接口。板载Flash、eeprom等,支持3.2寸的TFT - LCD屏幕。所有IO口均引出,可完整地进行外设开发,

    2024年02月16日
    浏览(47)
  • GD32F470 移植STM32F429工程 Keil调试笔记

    keil版本:5.25 安装 GigaDevice.GD32F4xx_DFP.3.0.4.pack Keil.STM32F4xx_DFP.2.15.0.pack 1、原项目为STM32F429 工程,切换到GD32F470 只需在 Options for Target\\\"“对话框的Device菜单中选中“GD32F470II”,重新编译即可,一般不会有编译错误。 2、将项目工程在切换回STM32F429,在 Options for Target”\\\"对话框的D

    2024年02月09日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包