尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

xiaozhi-esp32 板卡移植实战:Waveshare ESP32-S3-Touch-AMOLED-2.06 手表式 AMOLED 语音助手的完整适配解析

xiaozhi-esp32 板卡移植实战:Waveshare ESP32-S3-Touch-AMOLED-2.06 手表式 AMOLED 语音助手的完整适配解析 xiaozhi-esp32 板卡移植实战Waveshare ESP32-S3-Touch-AMOLED-2.06 手表式 AMOLED 语音助手的完整适配解析【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32本篇技术指南以 ESP32-S3-Touch-AMOLED-2.06 板卡支持文档 为核心围绕该板卡在 xiaozhi-esp32 项目中的完整适配实现展开从硬件规格、引脚映射、编译配置到 AXP2101 电源管理、SH8601 QSPI AMOLED 显示、FT5x06 电容触摸、ES8311/ES7210 双编解码音频链路等底层源码逐层拆解。读完本文你将掌握如何为一块手表形态的 ESP32-S3 开发板配置、编译并运行 xiaozhi-esp32 语音助手固件并能理解其各外设驱动的移植模式为自行适配其他板卡提供可直接套用的范本。一、板卡硬件概览一块能戴在手腕上的语音助手开发板根据板卡目录下的 README 支持文档Waveshare ESP32-S3-Touch-AMOLED-2.06 是一款专为可穿戴场景设计的高性能手表风格开发板主控基于乐鑫 ESP32-S3R8 微控制器内置 8MB PSRAM支持 Wi-Fi 与 BLE具备充足的 AI 语音处理算力与内存余量显示2.06 英寸 AMOLED 电容触摸屏分辨率 410×502色彩鲜艳、对比度高适合作为语音助手的可视化交互界面传感与时钟板载 6 轴 IMU惯性测量单元与 RTC 实时时钟芯片音频板载音频编解码芯片支持麦克风采集与扬声器播放电源集成电源管理 ICPMIC配合锂电池供电支持充电状态检测与电池电量读取形态附带定制外壳外观接近智能手表非常适合可穿戴应用的样机原型验证。在 xiaozhi-esp32 项目中这块板卡被归入waveshare厂商目录其完整的板级适配代码位于 esp32-s3-touch-amoled-2.06/esp32-s3-touch-amoled-2.06.cc包括引脚定义、驱动初始化与按键逻辑等全部板级实现。二、板卡支持文件结构一个板卡的标准三件套在仓库中一块受支持的板卡通常由三个文件组成本板卡位于main/boards/waveshare/esp32-s3-touch-amoled-2.06/目录文件作用config.h板级引脚宏定义将 GPIO、I2C 地址、显示参数等以编译期宏的形式固化config.json板卡元信息厂商、类型、目标芯片与构建时追加的 sdkconfig 选项esp32-s3-touch-amoled-2.06.cc板级驱动实现继承公共基类完成 PMIC、显示、触摸、音频、按键等初始化2.1 config.json板卡构建元信息config.json 声明了板卡的厂商waveshare、类型标识esp32-s3-touch-amoled-2.06、目标芯片esp32s3并定义了构建时追加的 sdkconfig 项{ manufacturer: waveshare, type: esp32-s3-touch-amoled-2.06, target: esp32s3, builds: [ { name: esp32-s3-touch-amoled-2.06, sdkconfig_append: [ CONFIG_USE_WECHAT_MESSAGE_STYLEn, CONFIG_USE_DEVICE_AECy ] } ] }其中CONFIG_USE_DEVICE_AECy表明该板卡启用设备端回声消除AEC——得益于 ES7210 ADC 提供了独立的参考信号输入通道详见下文音频部分可在设备本地完成回声抑制CONFIG_USE_WECHAT_MESSAGE_STYLEn则关闭微信气泡消息风格使用默认的交互界面样式。2.2 Kconfig编译时的板卡选择入口在 main/Kconfig.projbuild 中该板卡注册为config BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_AMOLED_2_06 bool Waveshare ESP32-S3-Touch-AMOLED-2.06 depends on IDF_TARGET_ESP32S3这表示该板卡选项仅对esp32s3目标芯片生效。从 main/CMakeLists.txt 中if(CONFIG_BOARD_TYPE_...)的编译分支结构可以推断编译时通过idf.py set-target esp32s3设定目标芯片再经idf.py menuconfig在 Board Type 选项中选择 Waveshare ESP32-S3-Touch-AMOLED-2.06随后执行idf.py build即可产出对应固件。板级源码通过DECLARE_BOARD(WaveshareEsp32s3TouchAMOLED2inch06)宏定义于 board.h注册为唯一板卡实例在 board.h 的Board::GetInstance()中由create_board()工厂函数创建。三、引脚定义解析config.h 的完整继承与逐项说明config.h 是理解整块板卡外设布局的第一手资料全部宏定义如下3.1 音频接口I2S 编解码#define AUDIO_INPUT_SAMPLE_RATE 24000 #define AUDIO_OUTPUT_SAMPLE_RATE 24000 #define AUDIO_INPUT_REFERENCE true #define AUDIO_I2S_GPIO_MCLK GPIO_NUM_16 #define AUDIO_I2S_GPIO_WS GPIO_NUM_45 #define AUDIO_I2S_GPIO_BCLK GPIO_NUM_41 #define AUDIO_I2S_GPIO_DIN GPIO_NUM_42 #define AUDIO_I2S_GPIO_DOUT GPIO_NUM_40 #define AUDIO_CODEC_PA_PIN GPIO_NUM_46 #define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_15 #define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_14 #define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR #define AUDIO_CODEC_ES7210_ADDR ES7210_CODEC_DEFAULT_ADDR输入/输出采样率均设为24 kHz这是本项目语音链路的统一采样率AUDIO_INPUT_REFERENCE true启用参考输入通道为设备端 AEC 提供播放参考信号I2S 采用 MCLK/WS/BCLK/DIN/DOUT 五线制其中ES8311 承担 DAC 播放DOUT、ES7210 承担 ADC 采集DIN两者地址均取各自驱动默认值扬声器功放使能脚PA为 GPIO46。3.2 显示接口QSPI AMOLED#define EXAMPLE_PIN_NUM_LCD_CS GPIO_NUM_12 #define EXAMPLE_PIN_NUM_LCD_PCLK GPIO_NUM_11 #define EXAMPLE_PIN_NUM_LCD_DATA0 GPIO_NUM_4 #define EXAMPLE_PIN_NUM_LCD_DATA1 GPIO_NUM_5 #define EXAMPLE_PIN_NUM_LCD_DATA2 GPIO_NUM_6 #define EXAMPLE_PIN_NUM_LCD_DATA3 GPIO_NUM_7 #define EXAMPLE_PIN_NUM_LCD_RST GPIO_NUM_8 #define DISPLAY_WIDTH 410 #define DISPLAY_HEIGHT 502 #define DISPLAY_MIRROR_X false #define DISPLAY_MIRROR_Y false #define DISPLAY_SWAP_XY false #define DISPLAY_OFFSET_X 0 #define DISPLAY_OFFSET_Y 0 #define DISPLAY_BACKLIGHT_PIN GPIO_NUM_NC #define DISPLAY_BACKLIGHT_OUTPUT_INVERT false显示屏为410×502分辨率注意这是一个接近方形的高分 AMOLED而非常见的矩形屏数据线多达 4 根DATA0~DATA3配合 CS、PCLK、RST走QSPI 四线模式以实现高分辨率下的刷新带宽无需镜像、无需交换 XY、无偏移说明面板默认方向即正确背光引脚为GPIO_NUM_NC未连接因为该屏的背光调节并非通过 GPIO PWM而是通过LCD 命令寄存器 0x51实现见下文 CustomBacklight 实现。3.3 按键与触摸#define BOOT_BUTTON_GPIO GPIO_NUM_0BOOT 按键映射到 GPIO0承担语音助手的核心交互单击对话、双击 AEC 切换、配网模式进入。四、电源管理AXP2101 PMIC 的精细化配置本板卡使用AXP2101电源管理芯片I2C 地址 0x34板级代码中Pmic类见 esp32-s3-touch-amoled-2.06.cc在构造函数中通过直接写寄存器完成整套电源策略class Pmic : public Axp2101 { public: Pmic(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : Axp2101(i2c_bus, addr) { WriteReg(0x22, 0b110); // PWRON OFFLEVEL as POWEROFF Source enable WriteReg(0x27, 0x10); // hold 4s to power off // Disable All DCs but DC1 WriteReg(0x80, 0x01); // Disable All LDOs WriteReg(0x90, 0x00); WriteReg(0x91, 0x00); // Set DC1 to 3.3V WriteReg(0x82, (3300 - 1500) / 100); // Set ALDO1 to 3.3V WriteReg(0x92, (3300 - 500) / 100); WriteReg(0x93, (3300 - 500) / 100); // Enable ALDO1(MIC) WriteReg(0x90, 0x03); WriteReg(0x64, 0x02); // CV charger voltage setting to 4.1V WriteReg(0x61, 0x02); // set Main battery precharge current to 50mA WriteReg(0x62, 0x0A); // set Main battery charger current to 400mA ( 0x08-200mA, 0x09-300mA, 0x0A-400mA ) WriteReg(0x63, 0x01); // set Main battery term charge current to 25mA } };逐项解读寄存器写入值含义0x220b110使能 PWRON 按键作为关机触发源0x270x10长按 4 秒关机0x800x01仅保留 DC1 输出关闭其余 DC-DC 通道以省电0x90 / 0x910x00 / 0x03先关闭全部 LDO再单独使能 ALDO1麦克风供电0x82(3300-1500)/100DC1 输出 3.3V 主电源0x92 / 0x93(3300-500)/100ALDO1 输出 3.3V0x640x02恒压充电电压上限 4.1V0x610x02预充电电流 50mA0x620x0A主充电电流 400mA注释还给出 0x08200mA、0x09300mA 的备选档位0x630x01终止充电电流 25mA板级代码在InitializeCodecI2c()中先以 I2C_NUM_0 总线SDA15、SCL14内部上拉初始化 I2C 主控随后InitializeAxp2101()将Pmic挂载到 0x34 地址。运行时通过GetBatteryLevel()见 esp32-s3-touch-amoled-2.06.cc调用pmic_-IsCharging() / IsDischarging() / GetBatteryLevel()接口定义见 axp2101.h上报电量与充放电状态并据此启停省电定时器。五、显示子系统SH8601 QSPI 驱动 圆角渲染 命令式背光5.1 SH8601 面板初始化序列AMOLED 面板由SH8601 驱动芯片控制。板级代码先为 SPI2 主机配置 4 根数据线并启用SPICOMMON_BUSFLAG_QUAD四线模式随后以 32 位命令字、40MHz 时钟建立 QSPI panel IO再下发厂商专用初始化命令序列static const sh8601_lcd_init_cmd_t vendor_specific_init[] { // set display to qspi mode {0x11, (uint8_t []){0x00}, 0, 120}, {0xC4, (uint8_t []){0x80}, 1, 0}, {0x44, (uint8_t []){0x01, 0xD1}, 2, 0}, {0x35, (uint8_t []){0x00}, 1, 0}, {0x53, (uint8_t []){0x20}, 1, 10}, {0x63, (uint8_t []){0xFF}, 1, 10}, {0x51, (uint8_t []){0x00}, 1, 10}, {0x2A, (uint8_t []){0x00,0x16,0x01,0xAF}, 4, 0}, {0x2B, (uint8_t []){0x00,0x00,0x01,0xF5}, 4, 0}, {0x29, (uint8_t []){0x00}, 0, 10}, {0x51, (uint8_t []){0xFF}, 1, 0}, };关键点0x11 唤醒后先切入 QSPI 模式0x2A/0x2B 设置列/行地址窗口0x16~0x1AF、0x00~0x1F5对应 410×502 有效区域0x53/0x51 配置显示与亮度0x29 开显示。随后通过esp_lcd_new_panel_sh8601创建面板驱动并调用esp_lcd_panel_set_gap(panel, 0x16, 0)补偿列偏移、esp_lcd_panel_invert_color(panel, false)保持颜色极性、esp_lcd_panel_mirror(...)应用镜像配置。5.2 CustomLcdDisplay高分辨率屏的圆角渲染与刷新区域对齐由于 AMOLED 为圆角手表屏若 LVGL 以矩形区域刷新四个角会绘出黑边影响观感。CustomLcdDisplay见 esp32-s3-touch-amoled-2.06.cc通过注册 LVGL 的LV_EVENT_INVALIDATE_AREA事件回调把每次待刷新区域外扩为偶对齐的整 2×2 块x1/y1 向下取偶、x2/y2 向上取奇避免因奇坐标导致的面板写入错位同时兼容圆角屏的刷新要求static void rounder_event_cb(lv_event_t* e) { lv_area_t* area (lv_area_t*)lv_event_get_param(e); // round the start of coordinate down to the nearest 2M number area-x1 (x1 1) 1; area-y1 (y1 1) 1; // round the end of coordinate up to the nearest 2N1 number area-x2 ((x2 1) 1) 1; area-y2 ((y2 1) 1) 1; }此外SetupUI()在完成父类界面搭建后还为状态栏设置了 10% 屏宽的内边距lv_obj_set_style_pad_left/right(status_bar_, LV_HOR_RES * 0.1, 0)使顶部状态图标避开圆角区域。5.3 CustomBacklight通过 LCD 命令 0x51 调节背光由于DISPLAY_BACKLIGHT_PIN为GPIO_NUM_NC背光不能走 GPIO PWM。CustomBacklight见 esp32-s3-touch-amoled-2.06.cc重写SetBrightnessImpl将 0~100 的亮度百分比映射为 0~255 字节通过esp_lcd_panel_io_tx_param以 32 位命令字命令 0x51 写命令操作码写入面板virtual void SetBrightnessImpl(uint8_t brightness) override { uint8_t data[1] {((uint8_t)((255 * brightness) / 100))}; int lcd_cmd 0x51; lcd_cmd 0xff; lcd_cmd 8; lcd_cmd | LCD_OPCODE_WRITE_CMD 24; esp_lcd_panel_io_tx_param(panel_io_, lcd_cmd, data, sizeof(data)); }这样 AMOLED 的亮度调节与 LVGL 背光抽象backlight.h无缝衔接休眠/唤醒时的亮度切换同样走此通道。六、触摸子系统FT5x06 电容触摸的接入触摸屏控制芯片为FT5x06通过 I2C 与主控通信。InitializeTouch()见 esp32-s3-touch-amoled-2.06.cc的关键配置触摸坐标上限设为DISPLAY_WIDTH - 1与DISPLAY_HEIGHT - 1409 / 501与面板分辨率严格对应复位脚 GPIO9、中断脚 GPIO38I2C 设备地址取ESP_LCD_TOUCH_IO_I2C_FT5x06_ADDRESS时钟 400kHz通过esp_lcd_touch_new_i2c_ft5x06创建触摸驱动再经lvgl_port_add_touch挂接到 LVGL 默认显示对象实现触摸事件与 UI 的自动绑定。七、音频子系统ES8311 ES7210 双编解码与设备端 AEC音频部分复用项目通用的BoxAudioCodecbox_audio_codec.h在GetAudioCodec()见 esp32-s3-touch-amoled-2.06.cc中实例化static BoxAudioCodec audio_codec( i2c_bus_, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN, AUDIO_CODEC_PA_PIN, AUDIO_CODEC_ES8311_ADDR, AUDIO_CODEC_ES7210_ADDR, AUDIO_INPUT_REFERENCE);其链路构成为ES8311 DAC 负责播放同时提供 AEC 参考输出ES7210 ADC 负责录音采集并接收参考信号构成回采通道。因为AUDIO_INPUT_REFERENCE true且构建配置开启CONFIG_USE_DEVICE_AECy设备可在本地执行回声消除即使远端未下发 AEC 参数也能获得较好的免提通话体验。板级还配套了 AEC 模式的按键快捷切换见下文按键逻辑运行时可在设备端 AEC 开启 / 关闭之间实时切换。八、按键交互与 MCP 工具注册8.1 按键逻辑InitializeButtons()见 esp32-s3-touch-amoled-2.06.cc基于 BOOT 按键GPIO0定义了三类交互boot_button_.OnClick([this]() { auto app Application::GetInstance(); if (app.GetDeviceState() kDeviceStateStarting) { EnterWifiConfigMode(); // 启动阶段单击 → 进入 WiFi 配网模式 return; } app.ToggleChatState(); // 运行阶段单击 → 切换对话开关 }); #if CONFIG_USE_DEVICE_AEC boot_button_.OnDoubleClick([this]() { if (app.GetDeviceState() kDeviceStateIdle) { app.SetAecMode(app.GetAecMode() kAecOff ? kAecOnDeviceSide : kAecOff); } }); #endif单击开机启动阶段进入 WiFi 配网模式正常运行阶段切换对话状态开始/结束对话双击仅在启用设备端 AEC 时编译空闲状态下在kAecOff与kAecOnDeviceSide之间切换 AEC 模式。8.2 MCP 工具注册InitializeTools()通过项目内置的 MCP Servermcp_server.h向大模型注册了一个系统级工具mcp_server.AddTool(self.system.reconfigure_wifi, End this conversation and enter WiFi configuration mode.\n **CAUTION** You must ask the user to confirm this action., PropertyList(), this { EnterWifiConfigMode(); return true; });即 AI 助手可在征得用户确认后通过 MCP 工具主动中断当前对话并进入 WiFi 配网模式实现语音驱动重新配网的闭环体验。九、电源策略省电定时器与低功耗链路InitializePowerSaveTimer()见 esp32-s3-touch-amoled-2.06.cc配置了多级省电机制PowerSaveTimer实现见 power_save_timer.hpower_save_timer_ new PowerSaveTimer(-1, 60, 300); power_save_timer_-OnEnterSleepMode([this]() { GetDisplay()-SetPowerSaveMode(true); GetBacklight()-SetBrightness(20); }); power_save_timer_-OnExitSleepMode([this]() { GetDisplay()-SetPowerSaveMode(false); GetBacklight()-RestoreBrightness(); }); power_save_timer_-OnShutdownRequest([this](){ pmic_-PowerOff(); });空闲 60 秒进入睡眠模式——屏幕进入省电态、背光降至 20%空闲 300 秒5 分钟触发关机请求直接调用pmic_-PowerOff()由 AXP2101 切断电源同时GetBatteryLevel()在充放电状态翻转时同步启停省电定时器仅在使用电池放电时启用省电策略插电调试时不干扰。十、编译与烧录要点结合 Kconfig.projbuild 与板卡 config.json 提供的信息面向该板卡构建固件的关键步骤如下以 ESP-IDF 标准流程为准设定目标芯片该板卡仅支持 ESP32-S3需执行idf.py set-target esp32s3选择板卡型号执行idf.py menuconfig在板卡类型Board Type选项中选择BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_AMOLED_2_06即 Waveshare ESP32-S3-Touch-AMOLED-2.06确认附加配置构建系统会自动套用 config.json 中sdkconfig_append的两项配置——启用设备端 AECCONFIG_USE_DEVICE_AECy、关闭微信消息样式CONFIG_USE_WECHAT_MESSAGE_STYLEn编译烧录执行idf.py build编译随后idf.py flash monitor烧录并观察串口日志。注意构建前请确保 ESP-IDF 环境已就绪且组件清单main/idf_component.yml中声明的依赖含esp_lcd_sh8601面板驱动、LVGL 等可正常拉取。十一、总结与移植参考从本板卡的适配实现可以看到 xiaozhi-esp32 板级移植的通用范式以WifiBoard为基类wifi_board.h按固定顺序完成 I2C → PMIC → SPI → 显示 → 触摸 → 按键 → 工具注册并以虚函数重写的方式向应用层暴露GetAudioCodec、GetDisplay、GetBacklight、GetBatteryLevel等能力。对可穿戴板卡而言AXP2101 的寄存器级电源策略、SH8601 的 QSPI 初始化序列、圆角刷新区域对齐、以及命令式背光 双击切 AEC等实现细节均为同类 ESP32-S3 手表/圆形屏设备的适配提供了可直接复用的工程样板。若需将固件部署到实际手表形态设备上请务必配合 AXP2101 完成锂电池充电参数电压 4.1V、电流 400mA的确认并在量产前依据实际电池规格调整 esp32-s3-touch-amoled-2.06.cc 中 0x61~0x64 寄存器的充电策略。【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表