找回密码
 立即注册
查看: 63|回复: 1

STC8H8K64U如何做个HID鼠标

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 7 天前 | 显示全部楼层 |阅读模式

STC8H8K64U如何做个HID鼠标

image.png

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 7 天前 | 显示全部楼层

好的!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鼠标"

📌 相关论坛讨论

  1. USB拓展库及使用示例 | 本贴 咨询 USB,基本帮您把USB程序开发完成
  2. AI8H8K64U和32G64K关于USB键盘的问题
  3. 调试 STC8H8K64U的USB程序时,如何进行仿真?
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-5 14:04 , Processed in 0.067544 second(s), 48 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表