一、STM32CubeMX配置

1、选择相应芯片(本文使用STM32F070F6P6)

2、RCC时钟配置和Debug设置

注:这里的PA9/10要重映射为PA11/12供USB接口使用(大部分芯片是分开的不用设置)

3、配置USB

注:这里的PID和VID默认就可以了(多设备时可以更改)

4、时钟配置

二、应用层代码编写

1、修改usbd_hid.c文件

①、修改USBD_HID_CfgFSDesc参数

首先长度,跳转至定义修改为41U(之前是34U)

端点数1改为2,接口协议2(鼠标)改为1(键盘),报告描述符长度重定义为HID_KEYBOARD_REPORT_DESC_SIZE    63U

最后配置集合中增加一部分端点描述符(添加到末尾),因为USB键盘对主机来说,不光有输入,还有输出。所以,增加的这部分端点描述符,用来描述输出

②、修改USBD_HID_Desc描述符长度

③、把USB鼠标的报告描述符删掉,换成USB键盘的报告描述符

__ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SIZE]  __ALIGN_END =
{
    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)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
    0x95, 0x05,                    //   REPORT_COUNT (5)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x05, 0x08,                    //   USAGE_PAGE (LEDs)
    0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
    0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x03,                    //   REPORT_SIZE (3)
    0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0                           // END_COLLECTION
};

④、修改USBD_HID_Setup函数

2、main编写

①、添加头文件和句柄

#include "usbd_hid.h"

extern USBD_HandleTypeDef hUsbDeviceFS;

②、数据包分析

/*
    *keyBoardData[0]:特殊键D0:Ctrl D1:Shift D2:Alt
    *keyBoardData[1]:预留
    普通按键可以一起按下(从0x04开始对应的按键为a)
    *keyBoardData[2]:
    *keyBoardData[3]:
    *keyBoardData[4]:
    *keyBoardData[5]:
    *keyBoardData[6]:
    *keyBoardData[7]:
  */

③、USB发送数据

USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&keyBoardData,sizeof(keyBoardData));

3、下面是笔者实现Ctrl+C/V键盘代码逻辑

uint8_t keyBoardData[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t keyBoardDataEmpty[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};


extern USBD_HandleTypeDef hUsbDeviceFS;
extern struct KEY key; 


static void keyboard_key_test(void)
{
    memset(keyBoardData, 0x00, sizeof(keyBoardData));
    key_scan(1);   //支持连续按下
    if(key.key0 == 1)
    {
        keyBoardData[0] = 0x01;     //ctrl
    }
    if(key.key1 == 1)
    {
        keyBoardData[2] = 0x06;     //C
    }
    if(key.key2 == 1)
    {
        keyBoardData[2] = 0x19;     //V
    }
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&keyBoardData,sizeof(keyBoardData));
    HAL_Delay(15);
}


int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USB_DEVICE_Init();
    while (1)
    {
        keyboard_key_test();
    }
}

4、代码开源

链接:https://pan.baidu.com/s/1TK_te2Yv031mls00Ue1Vnw

提取码:9icj

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐