好,现在信息就非常完整了。基于 数据手册第28章 和 官方论坛范例,我来给你一个完整的指南。
🖱️ STC32G12K128 制作 HID 鼠标完整指南
一、所需软硬件
| 项目 |
说明 |
| 芯片 |
STC32G12K128(任意封装均可,需引出 USB-DP/P3.0、USB-DN/P3.1) |
| 下载/调试 |
AiCube-ISP 软件,设置 IRC 频率为24MHz |
| 开发环境 |
Keil C251,Memory Model 推荐XSmall 模式 |
| USB 连接 |
P3.0 (USB-DP)、P3.1 (USB-DN) 直接连到电脑 USB 口(或用 STC-USB Link1D) |
| 按键 |
接普通 GPIO,作为鼠标左/右/中键和移动方向 |
二、两种实现路线
🔵 路线 A:使用 STC 官方 USB 库(推荐,代码更简洁)
这是论坛帖子(thread-24404)中官方给出的方式,使用 STC 封装好的 USB 库函数。
关键文件:
stc.h — STC 头文件
usb.h — USB 底层驱动
usb_req_class.h — HID 类请求处理
timer.h — 定时器(1ms 按键扫描)
项目创建步骤:
- 在 Keil 中新建 C251 工程,芯片选 STC32G12K128
- Memory Model 设为 XSmall
- 添加 USB 库文件(通过 AiCube-ISP → 下载软件 → USB库 获取)
- 添加以上头文件和主程序
主程序骨架:
#include "stc.h"
#include "usb.h"
#include "usb_req_class.h"
#include "timer.h"
void main()
{
WTST = 0; // 最快速度
EAXFR = 1; // 使能XFR
CKCON = 0; // 提高XRAM速度
usb_init();
timer_init();
EA = 1;
while (1)
{
usb_class_in(); // USB HID 数据上报
if (f1ms) // 每 1ms 扫描按键
{
f1ms = 0;
scan_key(); // 读取按键值并更新鼠标状态
}
}
}
按键映射关系(实验箱默认):
| 按键 |
鼠标动作 |
按键 |
鼠标动作 |
| KEY0 |
左键 |
KEY4 |
左移 |
| KEY1 |
中键 |
KEY5 |
右移 |
| KEY2 |
右键 |
KEY6 |
上移 |
| — |
— |
KEY7 |
下移 |
完整代码包请到官网下载 "STC32G实验箱演示程序",找到 "72-基于HID协议的USB鼠标范例"。
🔵 路线 B:纯寄存器操作(更底层,不需要库文件)
数据手册 第28.5.1节《HID人机接口设备范例》 给出了完整的寄存器级代码,手写 USB 枚举和 HID 报告描述符。
关键描述符(需修改的部分):
① 设备描述符 DEVICEDESC
char code DEVICEDESC[18] = {
0x12, 0x01, // bLength, bDescriptorType(Device)
0x00, 0x02, // bcdUSB(2.00)
0x00, 0x00, 0x00, // class, subclass, protocol
0x40, // bMaxPacketSize0(64)
0xbf, 0x34, // idVendor(STCUSB:34bf)
0x80, 0x43, // idProduct(4380)
0x00, 0x01, // bcdDevice(1.00)
0x01, 0x02, 0x00, // iManufacturer, iProduct, iSerialNumber
0x01 // bNumConfigurations
};
② HID Report Descriptor(鼠标协议)
数据手册中的范例是 Consumer Control 设备,要做鼠标需改为 鼠标专用的 Report Descriptor:
char code HIDREPORTDESC[50] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
这个描述符定义了标准的 3键 + X/Y/Wheel 相对位移 的鼠标协议。
③ 发送鼠标数据
在端点1的 IN 中断中,向 FIFO1 写入 4字节鼠标数据:
字节0: [按键状态] bit0=左键, bit1=右键, bit2=中键
字节1: X轴位移(有符号,-127~+127)
字节2: Y轴位移(有符号)
字节3: 滚轮(有符号)
示例代码段:
BYTE MouseData[4];
// 更新鼠标数据
MouseData[0] = (按键左 ? 0x01 : 0) | (按键右 ? 0x02 : 0) | (按键中 ? 0x04 : 0);
MouseData[1] = X移动量; // 正数右移,负数左移
MouseData[2] = Y移动量; // 正数下移,负数上移
MouseData[3] = 0; // 滚轮
// 写入端点 FIFO 并通知 USB 发送
WriteReg(INDEX, 1);
WriteFifo(FIFO1, MouseData, 4);
WriteReg(INCSR1, INIPRDY);
三、下载设置
在 AiCube-ISP 中:
- 芯片型号:STC32G12K128
- IRC 频率:24MHz(必须,USB 需要精确时钟)
- USB 下载:勾选"USB 下载",按住 P3.2 再上电进入下载模式
四、范例代码获取方式
| 方式 |
路径 |
| 官方完整工程 |
官网 → 资料下载 →STC32G实验箱演示程序包 → 72-基于HID协议的USB鼠标范例 |
| 数据手册源码 |
STC32G数据手册第28.5.1节(HID基础框架)和 第28.5.5节(鼠标专用说明) |
| 论坛帖子 |
thread-24404 有完整主程序 |
如果你需要,我可以帮你进一步梳理:
- 如何改 Pin 脚(不用实验箱矩阵键盘,改用普通独立按键)
- 如何改成 鼠标+键盘复合设备
- 如何自定义 VID/PID
欢迎继续提问!🎯
🔍 搜索 "STC32G12K128如何做个hid鼠标"
📌 相关论坛讨论
- 72-基于HID协议的USB鼠标范例,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64
- STC32G12K128 HID出不来了?
- 51 开源:【HID-鼠标+HID-键盘】的USB-HID复合设备 + 绝对坐标|手写笔