xiaozhi-esp32 板级适配指南:Waveshare ESP32-S3-Touch-LCD-3.49 V2 的 IO 扩展器接线方案解析
xiaozhi-esp32 板级适配指南Waveshare ESP32-S3-Touch-LCD-3.49 V2 的 IO 扩展器接线方案解析【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32本文以 Waveshare ESP32-S3-Touch-LCD-3.49 V2 开发板在 xiaozhi-esp32 项目中的板级适配为线索系统讲解该板与初版在背光 PWM、LCD 复位、背光使能与触摸中断引脚上的差异并结合config.h、config.json与板级源码完整还原基于 TCA9554 IO 扩展器的初始化流程、QSPI 屏驱动、电容触摸读取与编译烧录方法帮助开发者理解“屏幕/触摸/音频逻辑复用、板级接线不同”的移植思路并可作为自行移植同系列 Waveshare 屏幕板卡的参考范本。一、V2 与初版的定位关系逻辑共用接线分家在 xiaozhi-esp32 仓库中Waveshare ESP32-S3-Touch-LCD-3.49 有两个板级目录初版main/boards/waveshare/esp32-s3-touch-lcd-3.49/waveshare-s3-touch-lcd-3.49.ccV2 版main/boards/waveshare/esp32-s3-touch-lcd-3.49-v2/waveshare-s3-touch-lcd-3.49-v2.cc根据 V2 的 README.md两者共用屏幕、触摸和音频逻辑仅板级接线不同。也就是说LCD 面板型号AXS15231BQSPI 接口、触摸芯片I2C 地址 0x3b与音频 CodecES8311 ES7210完全相同差异全部集中在引脚分配上。README 明确列出的四处差异如下背光 PWM 从 GPIO8 调整为 GPIO42GPIO8 改用于 TCA9554 的 EXIO_INT扩展器中断输入LCD 复位由 TCA9554 的 EXIO5 控制不再由 MCU GPIO 直接驱动背光使能由 TCA9554 的 EXIO1 控制。这四处改动的本质是V2 硬件把原本占用 MCU 引脚的背光使能与 LCD 复位信号统一挪到了 TCA9554 这颗 I2C IO 扩展器上从而释放 GPIO 资源同时引入扩展器中断用于按键/状态监测。下面逐一对照源码进行验证。二、差异一背光 PWM 引脚迁移与反向输出对比两份config.h可以非常直观地看到背光控制的变化初版 esp32-s3-touch-lcd-3.49/config.h#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_8 #define DISPLAY_BACKLIGHT_OUTPUT_INVERT trueV2 版 esp32-s3-touch-lcd-3.49-v2/config.h#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_42 #define DISPLAY_BACKLIGHT_OUTPUT_INVERT true背光 PWM 输出从 GPIO8 移到 GPIO42且两者都声明了DISPLAY_BACKLIGHT_OUTPUT_INVERT true说明该板背光控制为低电平有效反向输出即 PWM 占空比按反相处理。在板级实现中背光对象通过以下代码创建waveshare-s3-touch-lcd-3.49-v2.ccvirtual Backlight* GetBacklight() override { static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT); return backlight; }PwmBacklight是仓库 main/boards/common/backlight.cc 提供的通用 PWM 背光实现构造时传入引脚号与反相标志即可无需板级额外逻辑。系统上电后通过构造函数末尾的GetBacklight()-RestoreBrightness()waveshare-s3-touch-lcd-3.49-v2.cc恢复上次保存的亮度。注意背光使能亮/灭开关与背光 PWM亮度调节在 V2 上是两个独立信号——PWM 由 GPIO42 输出而开关由 TCA9554 EXIO1 控制见下文第四节。三、差异二GPIO8 让位给 TCA9554 中断线初版中 GPIO8 是背光 PWMV2 中 GPIO8 改作 TCA9554 的 EXIO_INT 输入。由于 TCA9554 默认的 8 个 IOEXIO0~EXIO7中部分被用于 LCD 复位、背光使能、电源保持等控制扩展器需要把“外部事件”通过 INT 引脚上报给 MCUGPIO8 正是这根中断线。这颗扩展器由乐鑫组件espressif/esp_io_expander_tca9554提供在 main/idf_component.yml 中声明为~2.0.3。V2 板级源码在InitializeTca9554()中创建扩展器实例waveshare-s3-touch-lcd-3.49-v2.ccesp_err_t ret esp_io_expander_new_i2c_tca9554(i2c_bus_, ESP_IO_EXPANDER_I2C_TCA9554_ADDRESS_000, io_expander); ret esp_io_expander_set_dir(io_expander, IO_EXPANDER_PIN_NUM_1 | IO_EXPANDER_PIN_NUM_5 | IO_EXPANDER_PIN_NUM_6 | IO_EXPANDER_PIN_NUM_7, IO_EXPANDER_OUTPUT); ret esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_1, 0); ret esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_5 | IO_EXPANDER_PIN_NUM_6 | IO_EXPANDER_PIN_NUM_7, 1);这里将 EXIO1、EXIO5、EXIO6、EXIO7 全部配置为输出其中EXIO1 背光使能初值为 0关闭待 LCD 初始化完成后置 1 点亮EXIO5 LCD 复位在 LCD 驱动初始化过程中执行“拉高→拉低→拉高”的复位时序EXIO6 电源保持/关机控制长按电源键后拉低以关闭系统电源EXIO7 常置 1保持高电平硬件上通常用作使能或未使用的固定电平。对比初版 esp32-s3-touch-lcd-3.49/waveshare-s3-touch-lcd-3.49.cc初版只配置了 EXIO6、EXIO7 两个输出引脚复位和背光使能都还是 MCU 直连——这正是两版在扩展器使用上的核心差异。四、差异三与四LCD 复位与背光使能改由扩展器接管4.1 初版GPIO 直接驱动复位初版在InitializeLcdDisplay()中先用gpio_config把LCD_RSTGPIO21配置为输出然后执行复位时序esp32-s3-touch-lcd-3.49/waveshare-s3-touch-lcd-3.49.ccgpio_set_level(LCD_RST, 1); vTaskDelay(pdMS_TO_TICKS(30)); gpio_set_level(LCD_RST, 0); vTaskDelay(pdMS_TO_TICKS(250)); gpio_set_level(LCD_RST, 1); vTaskDelay(pdMS_TO_TICKS(30)); esp_lcd_panel_init(panel);4.2 V2扩展器输出模拟复位时序V2 的LCD_RST在 config.h 中被定义为GPIO_NUM_NC未连接面板复位改为通过 EXIO5 电平翻转完成waveshare-s3-touch-lcd-3.49-v2.ccESP_ERROR_CHECK(esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_5, 1)); vTaskDelay(pdMS_TO_TICKS(30)); ESP_ERROR_CHECK(esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_5, 0)); vTaskDelay(pdMS_TO_TICKS(250)); ESP_ERROR_CHECK(esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_5, 1)); vTaskDelay(pdMS_TO_TICKS(30)); esp_lcd_panel_init(panel);时序参数30ms 高、250ms 低、30ms 高与初版完全一致只是驱动方式从 MCU GPIO 换成 I2C 扩展器输出。LCD 初始化完成后紧接着通过esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_1, 1)第 134 行打开背光使能——这就是 README 中所说“背光使能由 TCA9554 EXIO1 控制”的实现位置。五、板级配置全景config.h 逐项解析V2 的完整引脚定义集中在 main/boards/waveshare/esp32-s3-touch-lcd-3.49-v2/config.h按功能域划分如下5.1 音频通路I2S Codec宏引脚说明AUDIO_INPUT_SAMPLE_RATE/AUDIO_OUTPUT_SAMPLE_RATE24000 Hz输入/输出采样率AUDIO_INPUT_REFERENCEtrue使能 AEC 参考信号输入AUDIO_I2S_GPIO_MCLKGPIO7主时钟AUDIO_I2S_GPIO_WSGPIO46字选择AUDIO_I2S_GPIO_BCLKGPIO15位时钟AUDIO_I2S_GPIO_DINGPIO6录音数据输入AUDIO_I2S_GPIO_DOUTGPIO45播放数据输出AUDIO_CODEC_PA_PINGPIO_NUM_NC功放使能为空无独立 PA 脚AUDIO_CODEC_I2C_SDA_PIN/SCLGPIO47 / GPIO48Codec I2C 总线AUDIO_CODEC_ES8311_ADDR/ES7210_ADDR默认地址播放 Codec / 录音 ADC音频采用BoxAudioCodecmain/audio/codecs/box_audio_codec.cc在 waveshare-s3-touch-lcd-3.49-v2.cc 中通过GetAudioCodec()创建ES8311 负责播放、ES7210 负责录音两者挂在同一路 I2C0 上。5.2 触摸独立 I2C1 总线宏值说明I2C_Touch_ADDRESS0x3b触摸控制器地址I2C_Touch_SDA_PIN/SCL_PINGPIO17 / GPIO18触摸 I2C 总线触摸芯片挂在独立的 I2C1 上与 Codec 的 I2C0 分离见InitializeTouch()waveshare-s3-touch-lcd-3.49-v2.cc总线时钟 300 kHz。5.3 按键宏引脚说明BOOT_BUTTON_GPIOGPIO0短按切换对话/进入配网PWR_BUTTON_GPIOGPIO16长按关机配合 EXIO6按键逻辑见InitializeButtons()第 137-159 行启动过程中单击 BOOT 进入 Wi-Fi 配网模式运行中单击切换聊天状态电源键“抬起”使能电源保持标志、长按则通过esp_io_expander_set_level(EXIO6, 0)关闭系统。5.4 LCDQSPI 接口宏值说明LCD_CS/LCD_PCLKGPIO9 / GPIO10片选 / 时钟LCD_D0~LCD_D3GPIO11~14QSPI 四线数据LCD_RSTGPIO_NUM_NC复位改由 TCA9554 EXIO5 控制LCD_LIGHT-1背光引脚不再由 LCD 逻辑管理DISPLAY_WIDTH/HEIGHT172 × 640分辨率DISPLAY_ROTATION_90false不旋转DISPLAY_MIRROR_X/Y、DISPLAY_SWAP_XYfalse无镜像/交换LVGL_DMA_BUFF_LEN172×64×2DMA 缓冲64 行LVGL_SPIRAM_BUFF_LEN172×640×2全屏 SPIRAM 缓冲LCD 采用 QSPI 模式io_config.flags.quad_mode true、spi_mode 3、40 MHz 像素时钟、32 位命令宽度驱动芯片为 AXS15231B初始化命令只有两条第 29-32 行static const axs15231b_lcd_init_cmd_t lcd_init_cmds[] { {0x11, (uint8_t []){0x00}, 0, 100}, // 退出睡眠延时 100ms {0x29, (uint8_t []){0x00}, 0, 100}, // 开启显示延时 100ms };刷新路径由CustomLcdDisplay实现custom_lcd_display.ccLVGL 全屏渲染到 SPIRAM 大缓冲再按LVGL_DMA_BUFF_LEN分片拷贝到 DMA 缓冲、通过esp_lcd_panel_draw_bitmap逐段刷入 QSPI 屏并用信号量在“传输完成回调”与主刷新循环之间同步避免撕裂。5.5 触摸数据读取触摸坐标通过 I2C 读命令从触摸控制器取回第 188-207 行uint8_t read_touchpad_cmd[11] {0xb5, 0xab, 0xa5, 0x5a, 0x0, 0x0, 0x0, 0x0e, 0x0, 0x0, 0x0}; i2c_master_transmit_receive(i2c_dev, read_touchpad_cmd, 11, buff, 32, 1000); pointX (((uint16_t)buff[2] 0x0f) 8) | (uint16_t)buff[3]; pointY (((uint16_t)buff[4] 0x0f) 8) | (uint16_t)buff[5];当buff[1]位于 (0, 5) 区间表示有触点按下坐标做裁剪与旋转映射后写入 LVGL 的lv_indev_data_t并注册为LV_INDEV_TYPE_POINTER输入设备第 182-185 行。六、构建配置与烧录方法6.1 config.json 与构建链V2 的构建描述见 main/boards/waveshare/esp32-s3-touch-lcd-3.49-v2/config.json{ manufacturer: waveshare, type: esp32-s3-touch-lcd-3.49-v2, target: esp32s3, builds: [ { name: esp32-s3-touch-lcd-3.49-v2, sdkconfig_append: [ CONFIG_USE_WECHAT_MESSAGE_STYLEn, CONFIG_USE_DEVICE_AECy ] } ] }要点target为esp32s3即乐鑫 ESP32-S3 芯片编译时需选择对应的 sdkconfig.defaults.esp32s3构建名variant为esp32-s3-touch-lcd-3.49-v2追加的 SDK 配置关闭了“微信消息气泡风格”界面并开启设备端 AEC回声消除——这与config.h中AUDIO_INPUT_REFERENCE true相呼应录音通路上必须提供参考信号才能实现 AEC。根据 AGENTS.md 描述的构建链板级选择遵循config.json → scripts/build.py → main/Kconfig.projbuild → main/CMakeLists.txt → 板级源码与 config.h的耦合链路每次构建只会通过DECLARE_BOARD(CustomBoard)waveshare-s3-touch-lcd-3.49-v2.cc导出一个板级实现。6.2 编译与烧录步骤先加载 ESP-IDF 环境仓库要求优先使用 ESP-IDF v6.0.2见 AGENTS.mdsource /path/to/esp-idf/export.sh idf.py --version查看可用板卡与变体名称python3 scripts/build.py --list-boards编译 V2 变体板级目录 --name指定构建名python3 scripts/build.py main/boards/waveshare/esp32-s3-touch-lcd-3.49-v2 --name esp32-s3-touch-lcd-3.49-v2编译完成后按常规 ESP-IDF 流程烧录到开发板idf.py -p /dev/ttyUSB0 flash monitor说明以上命令基于仓库 AGENTS.md 提供的标准构建入口python3 scripts/build.py board-directory --name variant-name整理具体串口设备名请以本机实际环境为准。七、移植要点小结对比 V2 与初版可以总结出同类“硬件改版”板级移植的四条经验复用一切可复用的逻辑屏幕型号、触摸芯片、音频 Codec 完全一致时直接复用同一套CustomLcdDisplay、触摸读取回调与BoxAudioCodec只改引脚宏IO 扩展器接管低速控制信号复位、使能这类“慢信号”非常适合通过 I2C 扩展器输出模拟时序释放 MCU GPIOV2 由此把背光 PWM 让给了 GPIO42、中断线占用了 GPIO8保持复位时序参数不变无论用 GPIO 还是扩展器LCD 复位时序高 30ms → 低 250ms → 高 30ms必须一致改动的是驱动载体而非时序规格构建链同步更新新增/修改板级时需要同步维护config.json、sdkconfig追加项与板级目录且保持一个构建只导出一个DECLARE_BOARD。如需进一步了解板级适配的通用规范可参考仓库 docs/custom-board.md该板所用屏幕驱动 AXS15231B 与 TCA9554 扩展器分别由espressif/esp_lcd_axs15231b、espressif/esp_io_expander_tca9554组件提供依赖版本可在 main/idf_component.yml 中查阅。【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考