前言
最近有项目需要用到键盘自动输入功能,提升工作效率。故使用该开发板实现自定义输入内容并通过按键控制自动通过usb输出。
简介
在官方GD32F4xx_Firmware_Library_V3.0.2 里的example上进行修改,使用外设分别有USB device(HID)、gpio(KEY,LED)、time2(usb)
项目结构
Application
CMSIS
GD32F4xx_StdPeriph_Driver
USB_Drivers
USB_Device
USB_Class
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
__ALIGN_BEGIN const usb_desc_dev hid_dev_desc __ALIGN_END =
{
.header =
{
.bLength = USB_DEV_DESC_LEN,
.bDescriptorType = USB_DESCTYPE_DEV
},
.bcdUSB = 0x0200U,
.bDeviceClass = 0x00U,
.bDeviceSubClass = 0x00U,
.bDeviceProtocol = 0x00U,
.bMaxPacketSize0 = USB_FS_EP0_MAX_LEN,
.idVendor = USBD_VID,
.idProduct = USBD_PID,
.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),
.bDescriptorType = USB_DESCTYPE_CONFIG
},
.wTotalLength = USB_HID_CONFIG_DESC_LEN,
.bNumInterfaces = 0x01U,
.bConfigurationValue = 0x01U,
.iConfiguration = 0x00U,
.bmAttributes = 0xA0U,
.bMaxPower = 0x32U
},
.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,
.bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD,
.iInterface = 0x00U
},
.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();
while(USBD_CONFIGURED != hid_keyboard.dev.cur_status)
{
}
while(1)
{
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);
}
}
}
原作者:不锈钢铁侠