好的!STC8H8K64U 也内置 USB 2.0-FS 硬件,完全支持做 HID 鼠标。和 STC32G 思路类似,但有几个关键区别(Keil C51、USB 初始化方式等),下面给你梳理好。
🖱️ STC8H8K64U HID 鼠标 — 完整实现指南
第1步:硬件连接
电脑 USB ─┬─ DP → P3.0 (USB_D+)
├─ DN → P3.1 (USB_D-)
├─ VCC → 3.3V/5V
└─ GND → GND
按键(接任意IO,以P1为例):
P1.0 → 左移 P1.1 → 右移
P1.2 → 上移 P1.3 → 下移
P1.4 → 左键 P1.5 → 右键 P1.6 → 中键
第2步:获取官方范例(最快方式)
STC8H8K64U 实验箱有 现成的 HID 鼠标范例,可以直接用:
官方路径: 官网资料 → STC8H8K64U实验箱-V9.3程序包 → 找到 "63-基于HID协议的USB鼠标范例"
也可以在 AiCube-ISP 下载软件 → 选择 STC8H8K64U → 范例程序 → 找到该例程直接下载。
第3步:两种实现方式
🔵 方式一:使用 USB-HID 库(推荐,代码极简)
STC8H 提供了封装好的 USB 库(手册第3章),支持 USB-HID 库函数,使用 usb_init() + USB_SendData() 即可。
所需文件(通过 AiCube-ISP 下载):
stc8h.h — 头文件
ai_usb.h / stc32_stc8_usb.h — USB 库头文件
- USB-HID 库文件(
.lib)
完整示例代码:
#include "stc8h.h"
#include "ai_usb.h"
// 按键定义
#define KEY_LEFT P10
#define KEY_RIGHT P11
#define KEY_UP P12
#define KEY_DOWN P13
#define KEY_BTN_L P14
#define KEY_BTN_R P15
#define KEY_BTN_M P16
// 鼠标数据缓冲区(4字节)
u8 xdata MouseBuf[4]; // [按键, X位移, Y位移, 滚轮]
void main()
{
// 初始化I/O
P0M0 = 0; P0M1 = 0;
P1M0 = 0; P1M1 = 0;
P2M0 = 0; P2M1 = 0;
P3M0 = 0; P3M1 = 0;
P4M0 = 0; P4M1 = 0;
P5M0 = 0; P5M1 = 0;
usb_init(); // USB初始化(包含48MHz时钟开启)
EA = 1; // 开总中断
while(1)
{
// 等待USB枚举完成
if(DeviceState != DEVSTATE_CONFIGURED) continue;
// 读取按键 → 填写MouseBuf
MouseBuf[0] = 0;
if(KEY_BTN_L) MouseBuf[0] |= 0x01; // 左键
if(KEY_BTN_R) MouseBuf[0] |= 0x02; // 右键
if(KEY_BTN_M) MouseBuf[0] |= 0x04; // 中键
MouseBuf[1] = 0; // X
if(KEY_LEFT) MouseBuf[1] = -5;
if(KEY_RIGHT) MouseBuf[1] = 5;
MouseBuf[2] = 0; // Y
if(KEY_UP) MouseBuf[2] = -5; // 负=上移
if(KEY_DOWN) MouseBuf[2] = 5;
MouseBuf[3] = 0; // 滚轮
// 将4字节鼠标数据发送到PC
USB_SendData(MouseBuf, 4);
// 注意:HID一次固定发64字节,库内部会补0
// 发完后稍作延时,避免连续发太快
delay_ms(10);
}
}
⚠️ 注意: 使用 USB-HID 库时,USB_SendData() 每次发送固定 64字节(HID 报告最大长度),库内部会自动将你的 4 字节数据补 0 到 64 字节后发送。
库方式的优点:
- 只需调用
usb_init() 和 USB_SendData(),无需关心 USB 枚举细节
- 内置描述符自动配置
- 支持 printf_usb 调试输出
🔵 方式二:寄存器操作(更底层,灵活修改描述符)
数据手册 第28.5.1节《HID人机接口设备范例》 给出了完整的寄存器级框架,适合需要自定义 VID/PID/描述符的场景。
核心区别(与方式一对比):
| 项目 |
库方式 |
寄存器方式 |
| 代码量 |
几十行 |
几百行 |
| 需自行写中断 |
❌ 不需要 |
✅ 需要写 USB 中断 (interrupt 25) |
| 可定制描述符 |
有限 |
✅ 完全可控 |
| 官方参考 |
手册第3章 |
手册第28.5.1节 + 28.5.5节 |
关键修改点(在28.5.1节范例基础上改):
① USB 初始化(STC8H 和 STC32G 不同!):
void UsbInit()
{
P3M0 = 0x00;
P3M1 = 0x03; // P3.0/P3.1 设置为高阻(USB专用)
IRC48MCR = 0x80; // ⭐ 开启内部48MHz(STC8H用这个,不是PLLCR!)
while (!(IRC48MCR & 0x01)); // 等待48MHz稳定
USBCLK = 0x00;
USBCON = 0x90; // 使能USB
// ... 后续寄存器配置同范例 ...
}
② HID Report Descriptor 改为鼠标协议(范例中默认是 Consumer Control,需改为 Mouse):
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)
// ---- 3个按键(绝对值) ----
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)
// ---- X/Y/Wheel(相对位移) ----
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
};
③ 在主循环或中断中发送鼠标数据(写端点1 FIFO):
BYTE MouseData[4];
// 填写数据
MouseData[0] = 按键状态;
MouseData[1] = X位移量; // 有符号
MouseData[2] = Y位移量; // 有符号
MouseData[3] = 0;
// 发送
WriteReg(INDEX, 1);
WriteFifo(FIFO1, MouseData, 4);
WriteReg(INCSR1, INIPRDY); // 通知USB主机取数据
STC8H8K64U vs STC32G12K128 关键区别一览
| 项目 |
STC8H8K64U |
STC32G12K128 |
| 内核 |
8051 (C51编译器) |
C251 (C251编译器) |
| 头文件 |
#include "stc8h.h" |
#include "stc32g.h" |
| XFR使能 |
`P_SW2 |
= 0x80;` |
| USB时钟初始化 |
IRC48MCR = 0x80; + 等待标志位 |
PLLCR + CLKSEL 配置 |
| USB库头文件 |
ai_usb.h / stc32_stc8_usb.h |
usb.h + usb_req_class.h |
| 下载频率 |
任意频率(USB用独立48MHz) |
需设24MHz(USB时钟从系统时钟PLL得来) |
| 官方鼠标例程 |
63-基于HID协议的USB鼠标范例 |
72-基于HID协议的USB鼠标范例 |
下载设置
在 AiCube-ISP 中选择:
| 项目 |
设置 |
| 芯片型号 |
STC8H8K64U |
| IRC 频率 |
任意(如 11.0592MHz),USB 时钟是独立的 48MHz |
| 下载方式 |
按住 P3.2 → 上电 → 松手 → 点击下载 |
💡 STC8H8K64U 的一大优势: USB 有独立的 48MHz 内部振荡器(IRC48M),所以系统主频可以随意设置(如 11.0592MHz 方便串口波特率),不影响 USB 工作,比 STC32G 更灵活。
总结一句话: 去 AiCube-ISP 下载 "63-基于HID协议的USB鼠标范例",这是 STC8H8K64U 实验箱的官方例程,改按键引脚即可用。如果希望代码更精简,用 USB-HID 库方式,usb_init() + USB_SendData() 两行核心函数就能跑起来。🎯
🔍 搜索 "STC8H8K64U如何做个HID鼠标"
📌 相关论坛讨论
- USB拓展库及使用示例 | 本贴 咨询 USB,基本帮您把USB程序开发完成
- AI8H8K64U和32G64K关于USB键盘的问题
- 调试 STC8H8K64U的USB程序时,如何进行仿真?