配置CuBeMX
启用USB,选择从机模式
启用HSE,在时钟树中将USB速率设置为48MHz。
Ctrl+s保存并生成代码
配置HID报告描述符
打开Project\USB_Device\App\usbd_custom_hid_if.c,找到第九十行,在下方大括号内填入描述符:
/* USER CODE BEGIN 0 */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x08, // REPORT_COUNT (8)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x04, // USAGE_MINIMUM (Keyboard a and A)
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x62, // REPORT_COUNT (98)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x06, // REPORT_SIZE (6)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
//0xc0 // END_COLLECTION
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
按住Ctrl点击USBD_CUSTOM_HID_REPORT_DESC_SIZE跳转配置描述符大小为73
点击左上角锤子进行构建工程,并刷入测试。打开设备管理器观察键盘类是否出现多了一个键盘。如果是进行下一步。如果没有出现观察是否在通用串行总线控制器出现未知的的USB设备(设备描述符请求失败),打开STM32CubeProgrammer进行FullChip Erase,再刷入即可。
构建输入函数
发送函数在usbd_custom_hid_if.c中,函数名称USBD_CUSTOM_HID_SendReport()
接收中断函数在usbd_custom_hid_if.c中,函数名称CUSTOM_HID_OutEvent_FS()
/*
* key_if.c
*
* Created on: Jan 17, 2025
* Author: LLL
*/
#include "key_if.h"
uint8_t report[15]={
0};
void ifkey(int command)
{
switch(command)
{
case 1:report[0]|=0x01;break;//LeftCtrl
case 2:report[0]&=(~0x01);break;
case 3:report[0]|=0x02;break;//LeftShift
case 4:report[0]&=(~0x02);break;
case 5:report[0]|=0x04;break;//LeftAlt
case 6:report[0]&=(~0x04);break;
case 7:report[0]|=0x08;break;//LeftGUI
case 8:report[0]&=(~0x08);break;
case 9:report[0]|=0x10;break;//RightCtrl
case 10:report[0]&=(~0x10);break;
case 11:report[0]|=0x20;break;//RightShift
case 12:report[0]&=(~0x20);break;
case 13:report[0]|=0x40;break;//RightAlt
case 14:report[0]&=(~0x40);break;
case 15:report[0]|=0x80;break;//RightGUI
case 16:report[0]&=(~0x80);break;
case 17:report[2]|=0x01;break;//a按下
case 18:report[2]&=(~0x01);break;//a释放
case 19:report[2]|=0x02;break;//b
case 20:report[2]&=(~0x02);break;
case 21:report[2]|=0x04;break;//c
case 22:report[2]&=(~0x04);break;
case 23:report[2]|=0x08;break;//d
case 24:report[2]&=