【GD32F427开发板试用】+使用USBFS轻松实现HID键盘应用
创始人
2024-05-14 06:37:20
0

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

前言

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

简介

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

项目结构

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.Htypedef 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.cint 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_FSUSB_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键盘值参考
键盘发送数据帧详解

相关内容

热门资讯

原生安卓系统怎样升级,从基础到... 你有没有发现,你的安卓手机用久了,有时候就像老牛拉车一样,慢吞吞的?别急,今天就来给你支个招,让你的...
安卓13系统怎么开发,开发者的... 你有没有听说安卓13系统已经发布了?这可是个大新闻呢!作为一个热衷于手机开发的小伙伴,你是不是也跃跃...
安卓q系统镜像下载,轻松升级体... 你有没有听说安卓Q系统已经发布了?这可是安卓家族里的一大亮点呢!今天,我就要来给你详细介绍一下安卓Q...
安卓系统色彩校正软件,打造个性... 你有没有发现,手机屏幕的色彩有时候会让人感觉不太对劲?有时候,画面看起来有点灰蒙蒙的,有时候又太艳丽...
苹果能否下个安卓系统,开启新篇... 你有没有想过,苹果的iOS系统会不会有一天突然宣布,它要拥抱安卓的大家庭呢?想象iPhone和iPa...
树莓派 装 安卓系统,轻松安装... 你有没有想过,用树莓派装上安卓系统,那会是怎样一番景象呢?想象一个迷你电脑,竟然能运行起我们日常使用...
安卓系统怎么打印小票,安卓系统... 你是不是也遇到了这样的烦恼:手机里存了好多重要的小票,但是想打印出来保存或者报销,却发现安卓系统里的...
安卓10安装系统应用,轻松上手... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,别急,今天就来给你支个招——升级安卓1...
美国不提安卓系统华为,迈向自主... 华为与美国:一场关于技术、市场与政策的较量在当今这个数字化的世界里,智能手机已经成为我们生活中不可或...
安卓系统怎么打开ppt,选择文... 你有没有遇到过这种情况:手里拿着安卓手机,突然需要打开一个PPT文件,却怎么也找不到方法?别急,今天...
谷歌退回到安卓系统,探索创新未... 你知道吗?最近科技圈可是炸开了锅,谷歌竟然宣布要退回到安卓系统!这可不是一个简单的决定,背后肯定有着...
安卓系统待机耗电多少,深度解析... 你有没有发现,手机电量总是不经用?尤其是安卓系统,有时候明明没怎么用,电量就“嗖”的一下子就下去了。...
小米主题安卓原生系统,安卓原生... 亲爱的手机控们,你是否曾为手机界面单调乏味而烦恼?想要给手机换换“衣服”,让它焕然一新?那就得聊聊小...
voyov1安卓系统,探索创新... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那个让手机焕发青春的Vivo V...
电脑刷安卓tv系统,轻松打造智... 你有没有想过,家里的安卓电视突然变得卡顿,反应迟钝,是不是时候给它来个“大保健”了?没错,今天就要来...
安卓系统即将要收费,未来手机应... 你知道吗?最近有个大消息在科技圈里炸开了锅,那就是安卓系统可能要开始收费了!这可不是开玩笑的,这可是...
雷凌车载安卓系统,智能出行新体... 你有没有发现,现在的汽车越来越智能了?这不,我最近就体验了一把雷凌车载安卓系统的魅力。它就像一个聪明...
怎样拍照好看安卓系统,轻松拍出... 拍照好看,安卓系统也能轻松搞定!在这个看脸的时代,拍照已经成为每个人生活中不可或缺的一部分。无论是记...
安卓车机系统音频,安卓车机系统... 你有没有发现,现在越来越多的汽车都开始搭载智能车机系统了?这不,咱们就来聊聊安卓车机系统在音频方面的...
老苹果手机安卓系统,兼容与创新... 你手里那台老苹果手机,是不是已经陪你走过了不少风风雨雨?现在,它竟然还能装上安卓系统?这可不是天方夜...