SOC-ESP32S3部分:36-适配自己的板卡
飞书文档https://x509p6c8to.feishu.cn/wiki/RP4UwPrsKi4xuQkKLAAcKxD3n1b
如果你自己画了PCB板,需要把自己绘制的板卡配置小智AI工程,可以参考此文档。
下载源码
克隆或下载源码到本地,这里以1.5.5为例,大家可以自行修改其它版本
虾哥版本的源码
https://github.com/78/xiaozhi-esp32/tree/v1.5.5
代码结构
仓库包含多个文件和文件夹,主要结构如下:
.gitignore git工程管理文件
CMakeLists.txt 工程cmake构建文件
LICENSE MIT License 允许用户自由使用、修改和分发代码,只需在软件或文档中包含原作者的版权声明和许可声明即可。
README.md README说明文档_中文
README_en.md README说明文档_英文
README_ja.md README说明文档_日文
partitions.csv 分区配置文件:16M Flash的分区表,默认选择,可以通过idf.py menuconfig修改,建议选择支持16M的硬件,后续扩展开发和OTA更方便
partitions_32M_sensecap.csv 分区配置文件:32M Flash的分区表
partitions_4M.csv 分区配置文件:4M Flash的分区表
partitions_8M.csv 分区配置文件:8M Flash的分区表
sdkconfig.defaults idf sdk默认配置,工程目前支持esp32s3和esp32c3两款芯片,只有s3支持唤醒词,基于乐鑫esp-sr实现
sdkconfig.defaults.esp32c3 idf sdk esp32c3默认配置
sdkconfig.defaults.esp32s3 idf sdk esp32s3默认配置
docs/ 文档文件,里面包含README文档使用的图片资料,还有一份服务器websocket交互协议
scripts/ 脚本文件,包含音频编码测试脚本、烧录调试脚本、版本打包相关脚本
.github/ GitHub Actions 的配置文件(.yaml 格式),用于定义项目的自动化工作流程,例如代码的持续集成(CI),可以在每次代码推送到仓库时自动运行测试、代码检查等任务
main/ 主要源码文件夹
添加构建配置
下方配置已经在工程中配置好,如果你需要自己重新设计硬件,可以参考下方流程,添加自己的板卡适配:
在xiaozhi-esp32/main/CMakeLists.txt 添加编译构建指令
elseif(CONFIG_BOARD_TYPE_XINGZHI_Cube_1_54TFT_ML307)set(BOARD_TYPE "xingzhi-cube-1.54tft-ml307")
elseif(CONFIG_BOARD_TYPE_XINGZHI_AIO_S3)set(BOARD_TYPE "xiaozhi-all-in-one-s3")
endif()
在xiaozhi-esp32/main/Kconfig.projbuild添加配置指令
config BOARD_TYPE_XINGZHI_Cube_1_54TFT_ML307bool "无名科技星智1.54(ML307)"config BOARD_TYPE_XINGZHI_AIO_S3bool "xiaozhi All in One 多合一版本"
endchoice
在boards中添加文件夹:
xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3
在xiaozhi-all-in-one-s3文件夹中创建config.h文件xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/config.h
这个文件主要配置板卡的硬件接口和相关参数
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_#include <driver/gpio.h>// 该头文件用于配置 xiaozhi-all-in-one-s3 开发板的相关参数/*
定义音频 I2S 接口相关的 GPIO 引脚
*/
// 音频 I2S 接口的主时钟信号(MCLK)
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_6
// 音频 I2S 接口的字选择信号(WS)
#define AUDIO_I2S_GPIO_WS GPIO_NUM_12
// 音频 I2S 接口的位时钟信号(BCLK)
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_14
// 音频 I2S 接口的数据输入信号(DIN)
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_13
// 音频 I2S 接口的数据输出信号(DOUT)
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_11// 音频编解码器的功率放大器(PA)
#define AUDIO_CODEC_PA_PIN GPIO_NUM_10
// 音频编解码器 I2C 通信的数据信号线(SDA)
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_5
// 音频编解码器 I2C 通信的时钟信号线(SCL)
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_4
// 音频编解码器 ES8311 的默认 I2C 地址
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR/*
音频参数
*/
#define AUDIO_INPUT_SAMPLE_RATE 24000
// 音频输入的采样率设置为 24000Hz
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
// 音频输出的采样率设置为 24000Hz/*
定义显示 SPI 接口相关的 GPIO 引脚*/
// 显示 SPI 接口的时钟信号(SCLK)
#define DISPLAY_SPI_SCLK_PIN GPIO_NUM_16
// 显示 SPI 接口的主输出从输入信号(MOSI)
#define DISPLAY_SPI_MOSI_PIN GPIO_NUM_17
// 显示 SPI 接口的片选信号(CS)
#define DISPLAY_SPI_CS_PIN GPIO_NUM_15
// 显示 SPI 接口的数据/命令选择信号(DC)
#define DISPLAY_SPI_DC_PIN GPIO_NUM_21
// 显示 SPI 接口的复位信号(RESET)
#define DISPLAY_SPI_RESET_PIN GPIO_NUM_18
// 显示 SPI 接口的时钟频率设置为 40MHz
#define DISPLAY_SPI_SCLK_HZ (40 * 1000 * 1000)// 显示屏背光灯控制引脚使用的 GPIO
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_42
// 显示屏背光灯输出是否反转
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true/*
显示参数
*/
// 显示屏的宽度为 172 像素
#define DISPLAY_WIDTH 172
// 显示屏的高度为 320 像素
#define DISPLAY_HEIGHT 320
// 是否交换 X 和 Y 坐标,这里设置为交换
#define DISPLAY_SWAP_XY false
// 是否在 Y 轴上镜像显示,这里设置为镜像
#define DISPLAY_MIRROR_Y false
// 是否在 X 轴上镜像显示,这里设置为不镜像
#define DISPLAY_MIRROR_X false
// 显示屏在 X 轴上的偏移量为 0
#define DISPLAY_OFFSET_X 34
// 显示屏在 Y 轴上的偏移量为 0
#define DISPLAY_OFFSET_Y 0/*** 外设IO配置*/
// 开发板上内置 LED 灯使用的 GPIO
#define BUILTIN_LED_GPIO GPIO_NUM_9
// 开发板上的启动按钮使用的 GPIO
#define BOOT_BUTTON_GPIO GPIO_NUM_0#endif // _BOARD_CONFIG_H_
创建config.json,描述sdk配置说明,目前板卡无需特别配置,所以sdkconfig_append为空
xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/config.json
{"target": "esp32s3","builds": [{"name": "xiaozhi-all-in-one-s3","sdkconfig_append": []}]
}
添加板卡实现xiaozhi_all_in_one_s3.cc文件xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/xiaozhi_all_in_one_s3.cc
这个文件主要对板卡硬件初始化部分进行实现
#include <wifi_station.h>
#include <esp_log.h>
#include <esp_efuse_table.h>
#include <driver/i2c_master.h>
#include <driver/spi_common.h>
#include <driver/gpio.h>
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_panel_vendor.h>#include "wifi_board.h"
#include "audio_codecs/es8311_audio_codec.h"
#include "display/lcd_display.h"
#include "aio_lcd_display.h"
#include "application.h"
#include "button.h"
#include "iot/thing_manager.h"
#include "led/single_led.h"#include "config.h"#define TAG "XiaozhiAioBoard"LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);class XiaozhiAioBoard : public WifiBoard {
private:i2c_master_bus_handle_t codec_i2c_bus_;Button boot_button_;Display* display_;// IIC初始化void InitializeCodecI2c() {i2c_master_bus_config_t i2c_bus_cfg = {.i2c_port = I2C_NUM_0,.sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,.scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,.clk_source = I2C_CLK_SRC_DEFAULT,.glitch_ignore_cnt = 7,.intr_priority = 0,.trans_queue_depth = 0,.flags = {.enable_internal_pullup = 1,},};ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &codec_i2c_bus_));}// SPI初始化void InitializeSpi() {spi_bus_config_t buscfg = {};buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN;buscfg.miso_io_num = GPIO_NUM_NC;buscfg.sclk_io_num = DISPLAY_SPI_SCLK_PIN;buscfg.quadwp_io_num = GPIO_NUM_NC;buscfg.quadhd_io_num = GPIO_NUM_NC;buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));}// 屏幕初始化void InitializeSt7789Display() {esp_lcd_panel_io_handle_t panel_io = nullptr;esp_lcd_panel_handle_t panel = nullptr;ESP_LOGD(TAG, "Install panel IO");esp_lcd_panel_io_spi_config_t io_config = {};io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN;io_config.dc_gpio_num = DISPLAY_SPI_DC_PIN;io_config.spi_mode = 3;io_config.pclk_hz = DISPLAY_SPI_SCLK_HZ;io_config.trans_queue_depth = 10;io_config.lcd_cmd_bits = 8;io_config.lcd_param_bits = 8;ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));// 初始化液晶屏驱动芯片ST7789ESP_LOGD(TAG, "Install LCD driver");esp_lcd_panel_dev_config_t panel_config = {};panel_config.reset_gpio_num = DISPLAY_SPI_RESET_PIN;panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;panel_config.bits_per_pixel = 16;ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));ESP_ERROR_CHECK(esp_lcd_panel_reset(panel));ESP_ERROR_CHECK(esp_lcd_panel_init(panel));ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY));ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y));ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel, true));display_ = new AioLcdDisplay(panel_io, panel,DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,{.text_font = &font_puhui_20_4,.icon_font = &font_awesome_20_4,.emoji_font = font_emoji_64_init(),});}// 按键初始化void InitializeButtons() {boot_button_.OnClick([this]() {auto& app = Application::GetInstance();if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {ResetWifiConfiguration();}app.ToggleChatState();});}// 物联网初始化,添加对 AI 可见设备void InitializeIot() {auto& thing_manager = iot::ThingManager::GetInstance();thing_manager.AddThing(iot::CreateThing("Speaker"));thing_manager.AddThing(iot::CreateThing("Backlight")); }public:XiaozhiAioBoard() : boot_button_(BOOT_BUTTON_GPIO) { InitializeCodecI2c();InitializeSpi();InitializeSt7789Display();InitializeButtons();InitializeIot();GetAudioCodec()->SetOutputVolume(90);GetBacklight()->RestoreBrightness();}virtual Led* GetLed() override {static SingleLed led_strip(BUILTIN_LED_GPIO);return &led_strip;}virtual Display* GetDisplay() override {return display_;}virtual Backlight* GetBacklight() override {static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);return &backlight;}virtual AudioCodec* GetAudioCodec() override {static Es8311AudioCodec audio_codec(codec_i2c_bus_, I2C_NUM_0, 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);return &audio_codec;}
};DECLARE_BOARD(XiaozhiAioBoard);
添加README.md工程使用说明书
xiaozhi-esp32/main/boards/xiaozhi-all-in-one-s3/README.md
# 编译配置命令**配置编译目标为 ESP32S3:**```bash
idf.py set-target esp32s3
```**打开 menuconfig:**```bash
idf.py menuconfig
```**选择板子:**```
Xiaozhi Assistant -> Board Type -> xiaozhi All in One 多合一版本
```**编译:**```bash
idf.py build
```
最后按说明书进行配置编译即可
idf.py set-target esp32s3
idf.py menuconfig
Xiaozhi Assistant -> Board Type -> xiaozhi All in One 多合一版本
idf.py build
相关文章:

SOC-ESP32S3部分:36-适配自己的板卡
飞书文档https://x509p6c8to.feishu.cn/wiki/RP4UwPrsKi4xuQkKLAAcKxD3n1b 如果你自己画了PCB板,需要把自己绘制的板卡配置小智AI工程,可以参考此文档。 下载源码 克隆或下载源码到本地,这里以1.5.5为例,大家可以自行修改其它版…...

LLMs 系列科普文(8)
八、模型的自我认知 接下来我们聊聊另一种问题,即模型的自我认知。 网上经常经常可以看到人们会问大语言模型一些关于认知方面的问题,比如“你是什么模型?谁创造了你?” 说实话,其实这个问题有点无厘头。 之所以这么…...
【明日方舟 × 红黑树】干员调度如何不掉线?算法工程的平衡魔法全揭秘!
【明日方舟 红黑树】干员调度如何不掉线?算法工程的平衡魔法全揭秘! 作者:星之辰 标签:#红黑树 #明日方舟 #工程平衡树 #算法科普 #动态数据结构 引子:为什么你的干员调度能实时平衡,从不崩盘?…...
Vue3 + Vite 中使用 Lodash-es 的防抖 debounce 详解
Vue3 Vite 中使用 Lodash-es 的防抖(debounce)详解 在 Vue3 Vite 项目中,debounce 是 lodash-es 中最常用的功能之一,它可以帮助我们优化高频事件的处理。下面我将详细讲解 debounce 的使用方法,并提供一个完整的示例。 Debounce 核心概念…...

机器学习基础相关问题
机器学习相关的基础问题 K-means是否一定会收敛 K-means是否一定会收敛 K-means算法在有限步数内一定会收敛,但收敛到的可能是局部最优解而非全局最优解。以下是详细分析: K-means 的优化目标是最小化 样本到其所归属簇中心的距离平方和(SSE…...

验证负载均衡与弹性伸缩
什么是弹性伸缩(Auto Scaling)? 弹性伸缩是指 云计算平台根据实时负载自动调整计算资源(如服务器实例、容器Pod)数量,以确保系统在高峰时保持稳定,在低谷时节省成本。 什么时候会触发弹性伸缩&…...

Three.js中AR实现详解并详细介绍基于图像标记模式AR生成的详细步骤
文档地址 Three.js中AR实现详解 以下是Three.js中实现AR功能的详细解析,涵盖技术原理、实现步骤、核心组件及优化策略: 🧩 一、技术基础 AR.js框架的核心作用 AR.js是Three.js实现AR的基石,提供以下核心能力: 多模…...
CSS高级技巧及新增属性
CSS高级技巧及新增属性 jarringslee 文章目录 CSS高级技巧及新增属性精灵图 Sprite字体图标 iconfontCSS几何图形的写法更改鼠标样式更改表单轮廓取消文本域的拖拽行内块元素的垂直居中对齐溢出文字处理 CSS布局技巧CSS5新增内容及其他属性新增选择器新增基础属性及其他属性ca…...

GeoBoundaries下载行政区划边界数据(提供中国资源shapefile)
要下载山东省济南市各个区的行政区划边界数据,你可以通过 geoBoundaries 提供的数据来实现。下面是详细步骤,包括网页操作和可选的 Python 自动化方式。 目录 ✅ 一、通过 geoBoundaries 官网手动下载1. 打开官网:2. 查找中国数据:…...
《深入理解 Nacos 集群与 Raft 协议》系列四:日志复制机制:Raft 如何确保提交可靠且幂等
《深入理解 Nacos 集群与 Raft 协议》系列 大家好,我是G探险者! 在前几篇中我们介绍了选主与日志对比机制,它们保证了“谁能成为 Leader”以及“Leader 的日志是否可靠”。 而当 Leader 已选定,系统需要把客户端的写请求写入所…...

大模型如何选型?嵌入模型如何选型?
欢迎来到啾啾的博客🐱。 记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。 有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。 目录 引言模型优劣认知与模型选择大模型(L…...
float转换为整型过程中关于小数部分的处理
在大多数编程语言中,将 float 类型转换为整型时,小数部分不会自动进行四舍五入,而是会直接截断(即丢弃小数部分,仅保留整数部分)。具体行为可能因语言而异,以下是常见语言的示例: 1.…...

开源大模型网关:One API实现主流AI模型API的统一管理与分发
以下是对One API的简单介绍: One API是一个使用go语言开发的大语言模型 API 管理与分发系统支持Docker一键快速部署,且资源占用小,高性能开箱支持多平台大模型快速接入,包括OpenAI、Gemini、xAI、Grop、Anthropic Claude、Ollama…...
Java线程工厂:定制线程的利器
在Java中,线程工厂(Thread Factory)是一个创建新线程的工厂。它提供了一种方式,允许你在创建线程时定制线程的属性,比如设置线程名称、线程的优先级、守护线程属性等。 线程工厂的主要目的是将线程的创建逻辑从使用线…...

智慧充电:新能源汽车智慧充电桩的发展前景受哪些因素影响?
全球能源结构转型与碳中和目标的推进,新能源汽车产业迎来爆发式增长,而智慧充电桩作为其核心基础设施,发展前景备受关注。智慧充电不仅关乎用户充电体验的优化,更是电网平衡、能源效率提升的关键环节。 然而,其发展并…...
在Pnetlab6上绕过TPM、安全启动和 RAM 检查安装windows 11笔记
笔者本次安装的windows11的镜像为: zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso 1、创建镜像目录并上传iso文件 mkdir /opt/unetlab/addons/qemu/win-win11x64-2024-LTSC //目录名称务必按照官方文档格式,否则无法识别 目录创建完成后,将.iso格式镜像上…...

【网站建设】不同类型网站如何选择服务器?建站项目实战总结
做了几个建站项目后,深刻体会到一件事:不同类型的网站,所采用的服务器策略是完全不同的。 如果选错了服务器方案,可能带来过高的成本、过低的性能,甚至上线失败。 这篇文章分享一下我在实战中的经验,供正在做建站项目的朋友参考。 🚩 1️⃣ 纯展示型网站 —— 静态服务…...
利用Pandas AI完成Excel大模型的结合实现自然语言问数
需求说明 实现对Excel工具的自然语言问数,即可以通过界面上传Excel文件,然后在文本框里通过语言对话的形式问出要统计的内容。比如: 用户数有多少? 语文成绩低于90的用户有多少? ..... 实现思路 Pandas AI是基于…...

iptables实验
实验一:搭建web服务,设置任何人能够通过80端口访问。 1.下载并启用httpd服务器 dnf -y install httpd 开启httpd服务器 systemctl start httpd 查看是否启用 下载并启用iptables,并关闭firewalld yum install iptable…...

前后端分离开发 和 前端工程化
来源:黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖SpringMyBatisSpringMVCSpringBoot等)_哔哩哔哩_bilibili 前后端混合开发: 需要使用前端的技术栈开发前端的功能,又需要使用Java的技术栈…...

web端rtmp推拉流测试、抽帧识别计数,一键式生成巡检报告
本文旨在实现无人机城市交通智慧巡检中的一个模块——无人机视频实时推拉流以及识别流并在前端展示,同时,统计目标数量以及违停数量,生成结果评估,一并发送到前端展示。对于本文任何技术上的空缺,可在博主主页前面博客…...

Excel 表格内批量添加前缀与后缀的实用方法
我们经常需要为 Excel 表格中的内容统一添加前缀或后缀,例如给编号加“NO.”、给姓名加“会员_”等。手动操作效率低,本文将介绍几种实用的方法,帮助你快速完成批量添加前缀和后缀的操作。 使用“&”运算符添加前缀或后缀(推…...
Vulkan 3D Tiles渲染器开发笔记1-脚手架搭建
一、项目简介 项目技术栈 CesiumNative + Dear ImGui + Vulkan 1.3 三维地理可视化系统 详细项目功能说明 1. 3DTiles渲染功能 实现完整的3DTiles格式解析与加载引擎支持LOD(Level of Detail)分层细节渲染可加载建筑模型、点云等3DTiles资产示例:加载城市级建筑3DTiles数据…...

2024 CKA题库+详尽解析| 15、备份还原Etcd
目录 免费获取题库配套 CKA_v1.31_模拟系统 15、 备份还原Etcd 题目: 开始操作: 1)、切换集群 2)、登录master并提权 3)、备份Etcd现有数据 4)、验证备份数据快照 5)、查看节点和Pod状态 6&am…...
【C/C++】std::vector成员函数清单
文章目录 std::vector使用指南1 不同版本提供的能力基础:C98 / C03 提供的成员函数C11 新增的成员函数C14:基本无变化(主要是标准库泛化,非 vector 成员变化)C17 引入的新特性(间接影响)C20 新增…...
如何借助Hyper - V在Windows 10中构建安全软件测试环境
视频演示 手把手教你激活 Hyper-V 并安装 Windows 10 虚拟机 一、引言:软件探索的风险与解决方案 在数字化时代,软件更新换代的速度日新月异,对于热衷于探索新软件的朋友而言,主系统中安装新软件时的谨慎态度无可厚非。恶意软件的威胁犹如高悬的达摩克利斯之剑,稍不留…...

西门子 S7-1200 PLC 海外远程运维技术方案
西门子 S7-1200 PLC 海外远程运维技术方案 一、面向海外场景的核心优势 针对跨国企业、海外项目及远程技术支持需求,本方案基于巨控GRM552Y-CHE模块提供无缝的全球化远程PLC运维能力,突破地域及时差限制,显著提升国际项目响应效率。 二、海…...
如何对Video视频进行SEO优化?
如何对Video视频进行SEO优化? 在现代互联网的海洋中,搜索引擎优化(SEO)无疑是每一个网站管理员和内容创作者必须掌握的技能。而今天,我要向大家介绍一个极为强大的工具——Schema.org。它不仅能提升你的网站在搜索引擎…...

嵌入式学习--江协stm32day5
USART 1. 引脚与接口层 异步引脚: TX:发送数据输出;RX:接收数据输入;SW_RX:单线半双工模式的接收引脚(替代 RX)。 同步引脚:SCLK:同步模式下的时钟输出&…...

(LeetCode 动态规划(基础版))96. 不同的二叉搜索树 (递推 || 递归)
题目:96. 不同的二叉搜索树 思路:二叉树长度为n时,枚举每个点u作为根节点root,那么root左边的数构成左子树种数left,root右边的数构成右子树种数right,那么当前u为根节点下,二叉树的种数为left*…...