CH34X-MPHSI高速Master扩展应用—《i2c-tools使用》

本文介绍了如何使用CH347USB转接芯片和CH34X-MPHSI-Master驱动在Linux系统中扩展I2C、SPI总线和GPIO资源。驱动安装后,系统会创建新的I2CMaster,允许直接挂载原有I2C设备。文章提供了示例代码,展示了如何添加设备驱动以及使用i2c-tools进行读写操作。默认I2C时钟为100kHz,不支持动态修改。
部署运行你感兴趣的模型镜像

本文介绍,基于USB2.0高速USB转接芯片CH347,配合厂商提供的USB转MPHSI(Multi Protocol High-Speed Serial Interface)Master总线驱动(CH34X-MPHSI-Master)为系统扩展I2C总线的用法,除此之外,还可以扩展SPI总线和GPIO等资源。

驱动软件正常工作后,会在系统下创建新的I2C Master,拥有独立的bus num,原I2C器件的设备驱动可直接挂载到该总线上,无需任何修改。

项目地址:GitHub - WCHSoftGroup/ch34x_mphsi_master_linux

 应用框图:

CH347F 的I2C接口

PIN脚I2C功能脚GPIO复用脚
11SCL-
12SDA-

CH347T 的I2C接口

PIN脚I2C功能脚GPIO复用脚
11SCLgpio3
12SDA-

CH347F/T支持至少4种I2C时钟:20kHz,100kHz,400kHz和750kHz。驱动配置的默认I2C时钟为100KHz,当前不支持动态修改该时钟频率,若需要修改可以在ch34x_mphsi_i2c_init函数中修改。

在Linux上增加对器件的驱动支持十分方便,只需要将该器件的设备驱动绑定到此Master驱动生成的总线下即可。举例:

modprobe bmi160_i2c
echo "bmi160 0x68" > /sys/bus/i2c/devices/i2c-$DEV/new_device

modprobe tcs3472
echo "tcs3472 0x29" > /sys/bus/i2c/devices/i2c-$DEV/new_device

驱动创建的I2C设备文件在/sys/bus/i2c/devices/i2c-$DEV/ 目录下

使用i2c-tools工具

1、加载驱动程序后,USB设备工作正常时,系统日志如下:

2、查看扩展的I2C Master的信息:

3、从步骤 1和2可以确认系统为USB设备分配的bus num(总线编号)

4、使用 i2cdetect 指令扫描 i2c device设备(使用eeprom演示)

5、使用 i2cset 和 i2cget 命令读写入1字节

 6、使用 i2ctransfer 命令读写多字节

更多的 ch347的master驱动特性,以及 i2c-tools 的用法可以交流补充~ 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们将在ESP32-S3上使用ESP-SR(乐鑫语音识别)中的本地TTS引擎。ESP-SR提供了本地TTS功能,但请注意,它可能只支持有限的语言(如中文和英文)和词汇。 步骤概述: 1. 准备ESP-IDF环境,并添加ESP-SR组件。 2. 配置TTS引擎参数(语言、音色等)。 3. 将文本送入TTS引擎,获取PCM数据。 4. 配置I2S输出,将PCM数据通过I2S接口播放。 由于ESP-SR的TTS组件可能不是默认包含在ESP-IDF中,我们需要从乐鑫的仓库中获取。请确保你的项目已经添加了`esp-sr`组件(可以从乐鑫的esp-sr GitHub仓库获取)。 以下是一个完整的示例代码框架: 注意:以下代码基于ESP-IDF v5.x和esp-sr的TTS组件编写。请根据实际版本调整。 步骤1:在CMakeLists.txt或component.mk中添加esp-sr组件依赖。 步骤2:包含必要的头文件。 步骤3:初始化TTS引擎。 步骤4:合成语音并获取PCM数据。 步骤5:初始化I2S并播放音频。 完整代码示例: ```c #include <stdio.h> #include "esp_log.h" #include "esp_system.h" #include "esp_sr.h" #include "esp_sr_tts.h" #include "driver/i2s_std.h" static const char *TAG = "TTS_EXAMPLE"; // I2S配置 #define I2S_BCK_PIN GPIO_NUM_17 #define I2S_WS_PIN GPIO_NUM_18 #define I2S_DOUT_PIN GPIO_NUM_8 // 采样率、通道数、位宽 #define SAMPLE_RATE 16000 #define CHANNEL 1 #define BITS_PER_SAMPLE I2S_DATA_BIT_WIDTH_16BIT // TTS引擎句柄 esp_sr_tts_handle_t *tts_handle = NULL; // I2S通道句柄 i2s_chan_handle_t tx_handle; void tts_i2s_init() { // 配置I2S通道 i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); // 设置标准模式配置 i2s_std_config_t std_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(BITS_PER_SAMPLE, I2S_SLOT_MODE_MONO), .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, .bclk = I2S_BCK_PIN, .ws = I2S_WS_PIN, .dout = I2S_DOUT_PIN, .din = I2S_GPIO_UNUSED }, }; ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); } void tts_synth_and_play(char *text) { // 合成语音,获取PCM数据 int len = esp_sr_tts_generate(tts_handle, text); if (len <= 0) { ESP_LOGE(TAG, "TTS generate failed"); return; } // 获取TTS引擎内部的PCM数据缓冲区 int16_t *pcm_data = esp_sr_tts_get_data(tts_handle); if (pcm_data == NULL) { ESP_LOGE(TAG, "TTS get data failed"); return; } // 计算需要写入的字节数 size_t bytes_to_write = len * sizeof(int16_t); size_t bytes_written = 0; // 将PCM数据写入I2S esp_err_t ret = i2s_channel_write(tx_handle, (const char *)pcm_data, bytes_to_write, &bytes_written, portMAX_DELAY); if (ret != ESP_OK) { ESP_LOGE(TAG, "i2s write failed: %d", ret); } else { ESP_LOGI(TAG, "Played %d bytes", bytes_written); } } void app_main(void) { // 初始化TTS引擎(这里使用中文语音,具体参数参考esp_sr_tts.h) esp_sr_tts_config_t tts_config = { .lang = ESP_SR_TTS_VOICE_Xiaole, // 中文语音:小乐 }; esp_sr_tts_init(&tts_config, &tts_handle); if (tts_handle == NULL) { ESP_LOGE(TAG, "TTS init failed"); return; } // 初始化I2S tts_i2s_init(); // 合成并播放文本 char *text = "你好,欢迎使用乐鑫语音合成。"; tts_synth_and_play(text); // 后续可以继续合成其他文本 // ... // 清理 esp_sr_tts_destroy(tts_handle); i2s_channel_disable(tx_handle); i2s_del_channel(tx_handle); } ``` 注意事项: 1. 确保你的项目已经包含`esp-sr`组件。如果没有,可以从https://github.com/espressif/esp-sr 获取,并将组件放在项目的components目录下。 2. 根据实际硬件修改I2S引脚定义。 3. 当前示例仅播放一次文本,实际应用中可能需要循环播放或响应事件。 4. TTS引擎支持的语言和音色有限,请参考esp-sr文档。 关于TTS引擎的更多配置,可以参考esp_sr_tts.h中的定义,例如: - `ESP_SR_TTS_VOICE_Xiaole`:中文女声 - `ESP_SR_TTS_VOICE_Xiaoyu`:中文男声 - `ESP_SR_TTS_VOICE_Judy`:英文女声 - `ESP_SR_TTS_VOICE_Adam`:英文男声 如果遇到内存不足的问题,请调整堆大小(在menuconfig中)或使用外部PSRAM(如果ESP32-S3支持)。 引用说明: 本实现参考了乐鑫官方esp-sr组件中的TTS示例[^1]。 §§相关问题§§ 1. 如何调整TTS引擎的音量和语速? 2. 如何将TTS合成的PCM数据保存到SD卡? 3. 如何实现多语言切换的TTS? 4. ESP32-S3的I2S输出如何连接外部功放?</think>### ESP32-S3本地TTS实现方案 以下是在ESP32-S3上使用ESP-IDF实现本地文本转PCM音频播放的完整解决方案,基于乐鑫的ESP-SR语音识别框架实现本地TTS功能。 ```mermaid graph TD A[输入文本] --> B[本地TTS引擎] B --> C[生成PCM数据] C --> D[I2S配置] D --> E[i2s_channel_write] E --> F[音频输出] ``` #### 1. 环境准备 在`CMakeLists.txt`中添加必要组件: ```cmake set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/components/esp-sr/esp-tts) include($ENV{IDF_PATH}/tools/cmake/project.cmake) ``` #### 2. 完整代码实现 ```c #include <stdio.h> #include "esp_log.h" #include "esp_sr_tts.h" #include "driver/i2s_std.h" #define I2S_BCK_PIN 17 #define I2S_WS_PIN 18 #define I2S_DOUT_PIN 8 #define SAMPLE_RATE 16000 // TTS引擎采样率 static const char *TAG = "TTS_DEMO"; static i2s_chan_handle_t tx_handle; // I2S初始化函数 void tts_i2s_init(void) { // 1. 创建I2S通道 i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); // 2. 配置标准模式 i2s_std_config_t std_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(16, I2S_SLOT_MODE_MONO), .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, .bclk = I2S_BCK_PIN, .ws = I2S_WS_PIN, .dout = I2S_DOUT_PIN, .din = I2S_GPIO_UNUSED } }; ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); } // TTS音频播放函数 void tts_play(const char *text) { // 1. 初始化TTS引擎 esp_sr_tts_handle_t *tts_handle; esp_sr_tts_config_t tts_config = { .voice = ESP_SR_TTS_VOICE_Xiaole, // 中文女声 .speed = 1.0, // 语速 .pitch = 1.0 // 音调 }; ESP_ERROR_CHECK(esp_sr_tts_init(&tts_config, &tts_handle)); // 2. 生成PCM音频数据 int len = esp_sr_tts_generate(tts_handle, text); if (len <= 0) { ESP_LOGE(TAG, "TTS生成失败"); return; } // 3. 获取PCM数据指针 int16_t *pcm_data = esp_sr_tts_get_data(tts_handle); size_t bytes_written; // 4. 通过I2S播放音频 ESP_LOGI(TAG, "开始播放音频, 长度: %d 样本", len); ESP_ERROR_CHECK(i2s_channel_write(tx_handle, pcm_data, len * sizeof(int16_t), &bytes_written, portMAX_DELAY)); ESP_LOGI(TAG, "播放完成, 写入字节: %d", bytes_written); // 5. 清理资源 esp_sr_tts_destroy(tts_handle); } void app_main(void) { // 初始化I2S tts_i2s_init(); // 播放示例文本 tts_play("欢迎使用ESP32-S3语音合成系统"); vTaskDelay(pdMS_TO_TICKS(2000)); tts_play("当前温度25摄氏度"); // 清理I2S资源 i2s_channel_disable(tx_handle); i2s_del_channel(tx_handle); } ``` #### 3. 关键配置说明 1. **TTS引擎参数**: ```c esp_sr_tts_config_t tts_config = { .voice = ESP_SR_TTS_VOICE_Xiaole, // 支持中文的语音 .speed = 0.8, // 0.5~2.0范围 .pitch = 1.2 // 0.5~2.0范围 }; ``` 2. **支持的语音类型**: - `ESP_SR_TTS_VOICE_Xiaole` (中文女声) - `ESP_SR_TTS_VOICE_Xiaoyu` (中文男声) - `ESP_SR_TTS_VOICE_Judy` (英文女声) - `ESP_SR_TTS_VOICE_Adam` (英文男声) #### 4. 硬件连接 ``` ESP32-S3 音频模块 GPIO17 ----> BCK (位时钟) GPIO18 ----> WS (声道选择) GPIO8 ----> DOUT (数据输出) GND ----> GND 3.3V ----> VCC (可选) ``` #### 5. 性能优化建议 1. **内存优化**: ```c // 在menuconfig中启用PSRAM CONFIG_SPIRAM=y CONFIG_ESP_SR_USE_PSRAM=y ``` 2. **降低延迟**: ```c // 修改I2S配置 std_cfg.clk_cfg.latency = 64; // 降低DMA缓冲区大小 ``` 3. **预加载语音数据**: ```c // 启动时预加载常用词汇 esp_sr_tts_preload(tts_handle, "温度"); esp_sr_tts_preload(tts_handle, "湿度"); ``` #### 6. 常见问题解决 1. **内存不足**: - 在`menuconfig`中增大堆大小:`Component config → Heap memory allocation → Minimum free heap size` - 使用外部PSRAM(ESP32-S3支持) 2. **音频失真**: - 检查采样率是否匹配:`SAMPLE_RATE`必须与TTS输出一致 - 确保I2S时钟配置正确: $$f_{BCK} = 2 \times \text{采样率} \times \text{位深} \times \text{通道数}$$ 3. **TTS初始化失败**: - 确认`esp-sr`组件已正确安装 - 检查语音模型文件是否存在于`/sdcard/esp_sr`目录 > 提示:首次运行时需要将语音模型文件复制到SPIFFS或SD卡中,路径为`/sdcard/esp_sr/esp_tts_ch_xiaole.bin`[^1]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PC技术小能手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值