找回密码
 立即注册
查看: 199|回复: 2

使用STC8H8K64U核心板做成虚拟键盘输出

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-09-19 22:03:15
已绑定手机

2

主题

0

回帖

18

积分

新手上路

积分
18
发表于 2025-9-19 22:03:15 | 显示全部楼层 |阅读模式

使用STC8H8K64U核心板,参考17-USB-CDC虚拟串口转串口+USB-HID键盘的复合设备的例程修改,
怎么修改成为虚拟键盘呀,我想把另外一个传感器接收到的数据通过虚拟键盘输出到电脑,该怎么修改例程呀

一串双雕的参考例程

一串双雕的参考例程
回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 2025-9-19 22:08:00 | 显示全部楼层
你好!你提到使用 STC8H8K64U 核心板,并参考 “17-USB-CDC虚拟串口转串口+USB-HID键盘的复合设备” 的例程,希望将其修改为一个 虚拟键盘设备,并能将另一个传感器的数据通过虚拟键盘的形式输出到电脑上。下面我将从几个方面为你提供专业性的指导,帮助你完成该目标。

一、理解USB HID键盘的基本原理

USB HID(Human Interface Device)是一种标准设备类,用于与人机交互设备通信,如键盘、鼠标等。HID键盘通过发送按键扫描码(Key Code)来模拟按键动作。

1.1 HID键盘的数据格式(Report Descriptor)

HID设备通过描述符(Report Descriptor)定义其数据格式。对于标准键盘,通常包含如下字段:
Modifier(修饰键,如Ctrl、Shift等)
Reserved(保留)
Key Codes(最多6个普通按键)

例如一个标准键盘的HID Report结构如下(单位:bit):
  1. 8 bits: Modifier
  2. 8 bits: Reserved
  3. 8 bits: Key Code 1
  4. 8 bits: Key Code 2
  5. 8 bits: Key Code 3
  6. 8 bits: Key Code 4
  7. 8 bits: Key Code 5
  8. 8 bits: Key Code 6
复制代码

所以每个HID键盘包是 8字节,用于描述当前按下的按键状态。

1.2 标准键盘扫描码

可以参考USB HID Usage Tables中的标准键盘扫描码(如A=0x04,B=0x05等)。你可以通过查找表将字符或数字转换为对应的键码。

二、STC8H8K64U的USB功能支持

STC8H8K64U支持USB 2.0 Full Speed(12Mbps),并内置USB控制器,可以实现HID设备、CDC虚拟串口等功能。其SDK中通常包含多个USB复合设备的例程,比如你提到的 CDC+HID 的复合设备例程。

2.1 复合设备的结构

复合设备(Composite Device)是指一个USB设备同时具有多个功能接口,例如:
接口0:CDC类(虚拟串口)
接口1:HID类(键盘)

你可以选择只保留HID接口,或者继续保留CDC用于调试。

三、如何修改例程实现虚拟键盘功能

你已经参考了“17-USB-CDC虚拟串口转串口+USB-HID键盘”的例程,说明你已经具备USB复合设备的基础知识。下面我将指导你如何专注于实现HID键盘功能。

3.1 修改设备描述符和HID描述符

在USB描述符中,需要确保:
bDeviceClass = 0x00(接口定义类)
bInterfaceClass = 0x03(HID类)
bInterfaceSubClass = 0x00(非启动设备)
bInterfaceProtocol = 0x00(无协议)

在HID描述符中指定Report Descriptor的长度和地址。

3.2 编写或修改Report Descriptor

你需要在代码中定义一个标准的键盘Report Descriptor,例如:
  1. c
  2. const uint8t hidkeyboardreportdesc[] = {
  3.     0x05, 0x01,        // USAGEPAGE (Generic Desktop)
  4.     0x09, 0x06,        // USAGE (Keyboard)
  5.     0xA1, 0x01,        // COLLECTION (Application)
  6.     0x05, 0x07,        //   USAGEPAGE (Keyboard/Keypad)
  7.     0x19, 0xE0,        //   USAGEMINIMUM (Keyboard LeftControl)
  8.     0x29, 0xE7,        //   USAGEMAXIMUM (Keyboard Right GUI)
  9.     0x15, 0x00,        //   LOGICALMINIMUM (0)
  10.     0x25, 0x01,        //   LOGICALMAXIMUM (1)
  11.     0x75, 0x01,        //   REPORTSIZE (1)
  12.     0x95, 0x08,        //   REPORTCOUNT (8)
  13.     0x81, 0x02,        //   INPUT (Data,Var,Abs)
  14.     0x95, 0x01,        //   REPORTCOUNT (1)
  15.     0x75, 0x08,        //   REPORTSIZE (8)
  16.     0x81, 0x03,        //   INPUT (Const,Var,Abs)
  17.     0x95, 0x06,        //   REPORTCOUNT (6)
  18.     0x75, 0x08,        //   REPORTSIZE (8)
  19.     0x15, 0x00,        //   LOGICALMINIMUM (0)
  20.     0x25, 0x65,        //   LOGICALMAXIMUM (101)
  21.     0x05, 0x07,        //   USAGEPAGE (Keyboard/Keypad)
  22.     0x19, 0x00,        //   USAGEMINIMUM (Reserved (no event indicated))
  23.     0x29, 0x65,        //   USAGEMAXIMUM (Keyboard Application)
  24.     0x81, 0x00,        //   INPUT (Data,Array,Abs)
  25.     0xC0               // ENDCOLLECTION
  26. };
复制代码

3.3 实现HID数据发送函数

你需要实现一个函数,用于构造并发送HID键盘数据包。例如:
  1. c
  2. void SendKeyboardReport(uint8t modifier, uint8t key1, uint8t key2, uint8t key3, uint8t key4, uint8t key5, uint8t key6)
  3. {
  4.     uint8t buf[8] = {0};
  5.     buf[0] = modifier; // 修饰键
  6.     buf[2] = key1;
  7.     buf[3] = key2;
  8.     buf[4] = key3;
  9.     buf[5] = key4;
  10.     buf[6] = key5;
  11.     buf[7] = key6;
  12.     USBDHIDSendReport(buf, 8);
  13. }
复制代码

3.4 模拟按键按下与释放

每次发送完按键后,需要发送一个“释放”包(所有键码清零)来模拟按键松开:
  1. c
  2. SendKeyboardReport(0, 0, 0, 0, 0, 0, 0); // 释放所有按键
复制代码

四、如何将传感器数据映射为键盘输入

你提到希望将传感器接收到的数据通过虚拟键盘输出到电脑,这需要将数据“编码”为对应的键盘键码。

4.1 数据映射策略
如果是数字数据(如温度、湿度等),可以将其转换为ASCII字符,再映射为对应键码。
如果是状态数据(如开关、按钮),可直接映射为特定键(如F1-F12)。

例如:
  1. c
  2. // 将字符 'A' 转换为键码
  3. uint8t keycode = 'A' - 'A' + 0x04; // A=0x04, B=0x05 ...
  4. SendKeyboardReport(0, keycode, 0, 0, 0, 0, 0);
复制代码

4.2 示例:发送字符串“HELLO”

```c
void SendString(const char str)
{
    while (str) {
        uint8t code = 0;
        if (str >= 'A' && str = 'a' && str = '1' && str

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-10-15 11:03:15

787

主题

1万

回帖

1万

积分

管理员

积分
19768
发表于 2025-9-19 23:11:35 | 显示全部楼层
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-10-16 07:58 , Processed in 0.122734 second(s), 60 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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