ESP32S3N16R8操作鼠标

37 阅读2分钟

效果

用usb连接电脑和开发板,开发板程序启动,控制鼠标一直在屏幕移动。好处是电脑不会熄屏啦,啊哈哈哈!

硬件

ESP32S3 N16R8开发板

image.png

环境

ESP-IDF v5.5.2

主函数

执行前,用ESP-IDF新建空白工程,初始化好N16R8开发板的配置,然后需要添加组件(espressif/tinyusb: ^0.19.0~2、espressif/esp_tinyusb: ^2.1.1) 添加完组件后,可以先清空,再构建一下,确保没有问题后,复制一下代码,清空,再构建,最后烧录。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "tinyusb.h"
#include "class/hid/hid_device.h"

//--------------------------------------------------------------------+
// HID 报告描述符:标准鼠标
//--------------------------------------------------------------------+
static const uint8_t hid_report_descriptor[] = {
    TUD_HID_REPORT_DESC_MOUSE()
};

//--------------------------------------------------------------------+
// USB 设备描述符
//--------------------------------------------------------------------+
static const tusb_desc_device_t device_descriptor = {
    .bLength            = sizeof(tusb_desc_device_t),
    .bDescriptorType    = TUSB_DESC_DEVICE,
    .bcdUSB             = 0x0200,
    .bDeviceClass       = 0x00,
    .bDeviceSubClass    = 0x00,
    .bDeviceProtocol    = 0x00,
    .bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE,
    .idVendor           = 0x303A,
    .idProduct          = 0x4004,
    .bcdDevice          = 0x0100,
    .iManufacturer      = 0x01,
    .iProduct           = 0x02,
    .iSerialNumber      = 0x03,
    .bNumConfigurations = 0x01,
};

//--------------------------------------------------------------------+
// 全速配置描述符
//--------------------------------------------------------------------+
#define EPNUM_HID        0x81
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN)

static const uint8_t fs_configuration_descriptor[] = {
    TUD_CONFIG_DESCRIPTOR(1, 1, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
    TUD_HID_DESCRIPTOR(0, 0, HID_ITF_PROTOCOL_MOUSE, sizeof(hid_report_descriptor), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5),
};

//--------------------------------------------------------------------+
// 字符串描述符
//--------------------------------------------------------------------+
static const char *string_descriptor[] = {
    (const char[]){0x09, 0x04},
    "Espressif",
    "ESP32 HID Mouse",
    "000001",
};

//--------------------------------------------------------------------+
// HID 回调
//--------------------------------------------------------------------+
uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) { return hid_report_descriptor; }
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { return 0; }
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) {}

//--------------------------------------------------------------------+
// TinyUSB 配置
//--------------------------------------------------------------------+
static const tinyusb_config_t tusb_cfg = {
    .port  = TINYUSB_PORT_FULL_SPEED_0,
    .task  = {.size=4096, .priority=5, .xCoreID=0},
    .descriptor = {
        .device = &device_descriptor,
        .qualifier = NULL,
        .string = string_descriptor,
        .string_count = sizeof(string_descriptor)/sizeof(string_descriptor[0]),
        .full_speed_config = fs_configuration_descriptor,
        .high_speed_config = NULL,
    },
};

//--------------------------------------------------------------------+
// 画正方形函数
//--------------------------------------------------------------------
void draw_square(void)
{
    const int step = 8;      // 每步移动像素(越小越丝滑)
    const int length = 80;   // 正方形边长

    // 1. 向右 →
    for(int i=0; i<length; i++){
        tud_hid_n_mouse_report(0,0,0, step, 0,0,0);
        vTaskDelay(pdMS_TO_TICKS(10));
    }

    // 2. 向下 ↓
    for(int i=0; i<length; i++){
        tud_hid_n_mouse_report(0,0,0, 0, step,0,0);
        vTaskDelay(pdMS_TO_TICKS(10));
    }

    // 3. 向左 ←
    for(int i=0; i<length; i++){
        tud_hid_n_mouse_report(0,0,0,-step, 0,0,0);
        vTaskDelay(pdMS_TO_TICKS(10));
    }

    // 4. 向上 ↑
    for(int i=0; i<length; i++){
        tud_hid_n_mouse_report(0,0,0, 0,-step,0,0);
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

//--------------------------------------------------------------------+
// 主函数
//--------------------------------------------------------------------+
void app_main(void)
{
    ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
    printf("✅ USB 鼠标初始化成功!开始画正方形……\n");

    while (1) {
        if (tud_mounted()) {
            draw_square(); // 循环画正方形
        }
        vTaskDelay(pdMS_TO_TICKS(200));
    }
}