esp32s3 esp-idf 怎么把中文转Unicode码 然后通过USB HID 中的tud_hid_report函数发送给电脑端
时间: 2025-06-24 19:35:03 浏览: 14
### 在 ESP32-S3 使用 ESP-IDF 将中文转换为 Unicode 并通过 USB HID 接口发送
#### 背景说明
ESP32-S3 支持 USB OTG 功能,能够作为 USB 设备运行。借助 TinyUSB 库(已集成至 ESP-IDF),开发者可以配置设备为 HID 类型并通过 `tud_hid_report` 函数发送数据。为了实现将中文字符转换为 Unicode 码点并通过 USB HID 接口传输,需要分两步完成:一是将中文字符转换为 Unicode;二是通过 USB HID 接口发送这些码点。
---
#### 步骤一:中文转 Unicode 码点
参考之前的实现方式,可使用如下代码片段将 UTF-8 编码的中文字符转换为 Unicode 码点:
```c
#include <stdio.h>
#include <stdint.h>
// 函数:将单个 UTF-8 字符转换为 Unicode 码点
uint32_t utf8_to_unicode(const char *utf8_char) {
uint32_t unicode = 0;
unsigned char byte;
// 处理第一个字节以判断后续字节数量
byte = (unsigned char)*utf8_char++;
if ((byte >> 7) == 0b0) { // 单字节序列
unicode = byte;
} else if ((byte >> 5) == 0b110) { // 双字节序列
unicode = (byte & 0x1F);
unicode <<= 6;
unicode |= (*utf8_char++ & 0x3F);
} else if ((byte >> 4) == 0b1110) { // 三字节序列
unicode = (byte & 0xF);
unicode <<= 6;
unicode |= ((*utf8_char++) & 0x3F);
unicode <<= 6;
unicode |= ((*utf8_char++) & 0x3F);
}
return unicode;
}
```
---
#### 步骤二:通过 USB HID 接口发送数据
TinyUSB 提供了 `tud_hid_report` 函数用于发送报告数据。以下是如何配置和使用的示例代码:
##### 配置 USB HID 描述符
在项目的 `usb_descriptors.c` 文件中定义 HID 报告描述符。这里假设我们发送的数据是简单的数组形式:
```c
#define REPORT_ID_KEYBOARD 1
const uint8_t desc_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD)),
};
```
##### 初始化 USB HID
在主程序中初始化 USB 和 HID 模块:
```c
#include "tinyusb.h"
void init_usb_hid() {
tusb_init();
tud_set_config_descriptor((uint8_t *)desc_report, sizeof(desc_report));
}
```
##### 发送 Unicode 数据
将转换后的 Unicode 码点打包成适合 USB HID 的格式,并调用 `tud_hid_report` 进行发送:
```c
void send_unicode_via_hid(uint32_t unicode_code_point) {
uint8_t report_data[sizeof(uint32_t)] = {0}; // 创建缓冲区存储 Unicode 码点
memcpy(report_data, &unicode_code_point, sizeof(uint32_t)); // 将码点复制到缓冲区
tud_hid_report(REPORT_ID_KEYBOARD, report_data, sizeof(report_data)); // 发送报告
}
```
---
#### 完整流程示例
以下是完整的代码示例,展示如何从读取中文字符串开始,经过转换和发送的过程:
```c
#include <stdio.h>
#include <stdint.h>
#include "tinyusb.h"
#include "esp_log.h"
static const char *TAG = "MAIN";
// 中文转 Unicode 码点函数
uint32_t utf8_to_unicode(const char *utf8_char) {
uint32_t unicode = 0;
unsigned char byte;
byte = (unsigned char)*utf8_char++;
if ((byte >> 7) == 0b0) { // 单字节序列
unicode = byte;
} else if ((byte >> 5) == 0b110) { // 双字节序列
unicode = (byte & 0x1F);
unicode <<= 6;
unicode |= (*utf8_char++ & 0x3F);
} else if ((byte >> 4) == 0b1110) { // 三字节序列
unicode = (byte & 0xF);
unicode <<= 6;
unicode |= ((*utf8_char++) & 0x3F);
unicode <<= 6;
unicode |= ((*utf8_char++) & 0x3F);
}
return unicode;
}
// 发送 Unicode 码点到 USB HID
void send_unicode_via_hid(uint32_t unicode_code_point) {
uint8_t report_data[sizeof(uint32_t)] = {0};
memcpy(report_data, &unicode_code_point, sizeof(uint32_t));
tud_hid_report(1, report_data, sizeof(report_data));
}
// 主函数
void app_main(void) {
// 初始化 NVS 和 Wi-Fi (如果需要)
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// 初始化 USB HID
init_usb_hid();
// 测试数据:发送 “你好”
const char* chinese_str = "你好";
while (*chinese_str != '\0') {
uint32_t unicode_code_point = utf8_to_unicode(chinese_str);
ESP_LOGI(TAG, "Sending Unicode Code Point: U+%X", unicode_code_point);
send_unicode_via_hid(unicode_code_point);
int bytes_in_sequence = 1;
if (((unsigned char)(*chinese_str) >> 5) == 0b110) {
bytes_in_sequence += 1;
} else if (((unsigned char)(*chinese_str) >> 4) == 0b1110) {
bytes_in_sequence += 2;
}
chinese_str += bytes_in_sequence; // 移动指针到下一个字符
}
}
```
---
### 注意事项
1. **HID 描述符设计**
根据具体需求调整 HID 报告描述符的内容。例如,如果仅发送键盘事件,则可以选择预定义的键盘描述符[^2]。
2. **数据长度限制**
USB HID 报告的最大长度由硬件决定,默认情况下可能较小。如果需要发送较大的数据包,应拆分为多个报告逐一发送。
3. **主机端接收**
计算机上的应用程序需正确解析来自 USB HID 的数据流。建议使用工具如 `hid_listen` 或自定义脚本捕获并显示收到的 Unicode 码点。
---
### 结论
通过上述方法,可以在 ESP32-S3 上基于 ESP-IDF 框架实现中文字符向 Unicode 码点的转换,并通过 USB HID 接口发送给计算机端。这种方法适用于定制化的人机交互场景,例如虚拟键盘输入或其他嵌入式控制应用。
---
阅读全文
相关推荐

















