# GD32E23x 工程模板 本仓库为兆易创新 GD32E23x 系列 MCU 的 CMake + VSCode 工程模板,适合嵌入式开发快速上手和团队协作。 --- ## 目录 - [适用范围](#适用范围) - [默认配置](#默认配置) - [快速开始](#快速开始) - [工程结构](#工程结构) - [板级配置](#板级配置) - [Flash 偏移配置(配合 Bootloader)](#flash-偏移配置配合-bootloader) - [工具链准备](#工具链准备) - [使用说明](#使用说明) - [时钟配置说明](#时钟配置说明) - [vcpkg 依赖管理(可选)](#vcpkg-依赖管理可选) --- ## 适用范围 - 适用于兆易创新 GD32E23x 系列 Cortex-M23 内核单片机 - 支持标准外设库开发 - 推荐开发环境:VSCode + CMake + ARM GCC 工具链 --- ## 默认配置 - MCU 主频:内部 RC 振荡器,系统时钟配置为 72MHz - 调试串口:USART0(PA2 TX / PA3 RX),115200 波特率 - I2C:默认硬件 I2C0(PF0 SDA / PF1 SCL),可通过 `board_config.h` 切换为软件 I2C --- ## 快速开始 ### 基于模板创建新项目 1. **克隆或复制本仓库** ```bash git clone https://gitea.hulk.wang/hulk/gd32e23x_template_cmake_vscode.git my-new-project cd my-new-project ``` 2. **修改项目配置** — 编辑 `cmake/project_config.cmake`: ```cmake set(PROJECT_NAME "MyProject") # 项目名称 set(BOARD_TYPE_CODE 20) # 板卡类型码(协议帧中的标识) set(VERSION_MAJOR 1) # 主版本号 set(VERSION_MINOR 0) # 次版本号 set(VERSION_PATCH 0) # 修订号 set(BUILD_VARIANT "APP") # 编译变体 ``` 3. **添加业务源文件** — 编辑 `CMakeLists.txt`,在 `TARGET_SRC` 中添加你的 `.c` 文件。 4. **配置板级引脚** — 编辑 `Inc/board_config.h`,修改 I2C、UART、LED 等引脚定义。 5. **编译** ```bash cmake --preset Debug cmake --build build/Debug ``` 产物在 `build/Debug/` 下,包含 `.elf`、`.hex`、`.bin`、`.map`、`.list`。 ### 分支说明 | 分支 | 用途 | |------|------| | `template_pc` | **主模板**(推荐),用于桌面端 VSCode 开发 | | `template_xl` | 小琅适配版 | | `main` | 早期版本,不推荐使用 | --- ## 工程结构 ``` . ├── CMakeLists.txt # 主构建文件 ├── CMakePresets.json # CMake 预设(Debug/Release) ├── cmake/ │ ├── arm-none-eabi-gcc.cmake # ARM GCC 工具链配置 │ ├── project.cmake # 编译选项(-Os/-O0, -mcpu=cortex-m23) │ ├── project_config.cmake # 项目名/版本号/编译变体 │ └── version.h.in # 自动生成固件版本头 ├── Inc/ # 头文件 │ ├── board_config.h # 板级引脚定义 + 功能开关 │ ├── command.h # 串口命令协议 │ ├── i2c.h / led.h / systick.h / uart.h │ └── uart_ring_buffer.h / gd32e23x_it.h / gd32e23x_libopt.h ├── Src/ # 源码 │ ├── main.c # 入口函数 │ ├── command.c # 命令解析处理 │ ├── board_config.c # MCU 型号自动检测 │ ├── i2c.c / led.c / systick.c / uart.c / uart_ring_buffer.c │ └── gd32e23x_it.c / system_gd32e23x.c / syscalls.c ├── SDK/ │ ├── CMSIS/ # ARM CMSIS Core (Cortex-M23) + GD 启动文件 │ └── GD32E23x_standard_peripheral/ # GD32 标准外设库 ├── LD/gd32e23x_flash.ld # 链接脚本 ├── doc/ # 芯片数据手册 └── .vscode/ # VSCode 调试/烧录配置 ``` --- ## 板级配置(`Inc/board_config.h`) 所有功能开关和引脚定义集中在 `Inc/board_config.h`。功能开关均为单行数值宏:将右侧的 `ENABLE` 或 `DISABLE` 改为另一值即可;其中 `ENABLE` 为 `1`,`DISABLE` 为 `0`。以下为完整的宏开关说明和推荐使用方式。 ### 功能开关速查表 | 宏 | 作用 | 默认值 | Release 建议 | |---|------|:---:|:---:| | `SOFTWARE_IIC` | I2C 实现方式 | `DISABLE`(硬件) | `DISABLE` | | `DEBUG_MODE` | printf 串口输出 | `DISABLE` | `DISABLE` | | `COM_DEBUG` | 命令帧调试打印 | `DISABLE` | `DISABLE` | | `DEBUG_VERBOSE` | 详细调试信息 | `DISABLE` | `DISABLE` | | `SEGGER_RTT_DETECTION` | SEGGER RTT 支持 | `ENABLE` | `DISABLE` | --- ### `SOFTWARE_IIC` — I2C 实现方式 选择 I2C 使用硬件外设还是软件 GPIO 模拟。 > 当前工程尚未实现 `SOFTWARE_IIC` 的条件编译驱动选择;该宏已迁移为数值配置,但改值不会在此版本切换 I2C 实现。 ```c #define SOFTWARE_IIC DISABLE // DISABLE: 硬件 I2C(默认);ENABLE: 软件 I2C(GPIO 模拟) ``` | 选项 | 优点 | 缺点 | |------|------|------| | 硬件 I2C | DMA 支持、CPU 占用低 | 仅限固定引脚、调试复杂 | | 软件 I2C | 任意 GPIO、移植方便 | CPU 占用高、速率受限 | > 切换后需同步修改下方 I2C 引脚定义。 --- ### `DEBUG_MODE` — 调试模式 开启后 USART0 输出 printf 调试信息。**Release 固件必须关闭。** ```c #define DEBUG_MODE DISABLE // DISABLE: 关闭(默认);ENABLE: 开启调试输出 ``` **影响范围:** - 使能 `USART0` 初始化和 `printf` 重定向到串口 - 会占用 PA2/PA3 引脚和 USART0 硬件资源 - 增加 ROM 约 2~4KB(取决于 printf 调用量) --- ### `COM_DEBUG` — 命令帧调试打印 开启后串口命令解析过程打印每帧的详细内容(地址、长度、数据、校验)。**仅调试通信协议时开启。** ```c #define COM_DEBUG DISABLE // DISABLE: 关闭(默认);ENABLE: 开启命令帧调试 ``` **依赖:** 需要先开启 `DEBUG_MODE`,否则输出无法外发。 **输出示例:** ```text [CMD] ADDR=01 LEN=05 DATA: AA BB CC DD EE CHK=OK ``` > ⚠️ Release 必须关闭,否则大量串口输出会严重拖慢主循环。 --- ### `DEBUG_VERBOSE` — 详细调试信息 在 `DEBUG_MODE` 基础上输出更底层的信息,如 I2C 总线扫描结果、MCU 型号识别等。 ```c #define DEBUG_VERBOSE DISABLE // DISABLE: 关闭(默认);ENABLE: 开启详细调试 ``` **额外输出:** - 启动时打印 MCU Flash 容量检测结果 - I2C 初始化时扫描总线上的设备地址 - 其他诊断信息 > 依赖 `DEBUG_MODE`,开启后 ROM 进一步增加约 1~2KB。 --- ### `SEGGER_RTT_DETECTION` — SEGGER RTT 支持 RTT(Real-Time Transfer)是 SEGGER 的调试通道技术,通过 SWD 接口传输数据,不占用串口引脚,速度远超 UART。 ```c #define SEGGER_RTT_DETECTION ENABLE // DISABLE: 禁用 RTT;ENABLE: 启用 RTT(默认) ``` **启用时:** - 自动包含 `SEGGER_RTT.h`,提供 `RTT_printf` / `RTT_WriteString` / `RTT_PutChar` 宏 - `SDK/SEGGER_RTT/` 模块参与编译和链接 - 可用 J-Link RTT Viewer 或 VSCode + cortex-debug 查看实时日志 **禁用时:** - 应用层 RTT 头文件引用与调用代码均在预处理阶段排除 - RTT 宏展开为空操作;应用目标不生成 RTT 调用代码 - 为保持现有 CMake SDK 加载方式,`SDK/SEGGER_RTT/` 仍会参与构建;静态库中未被引用的对象不会被链接器提取 > **Release 建议关闭** — RTT 依赖调试器连接,量产固件中无意义且占用 ROM。 **依赖关系总览:** ``` COM_DEBUG ──── 依赖 ──→ DEBUG_MODE DEBUG_VERBOSE ─ 依赖 ──→ DEBUG_MODE SEGGER_RTT_DETECTION ─ 独立,与 DEBUG_MODE 并行 ``` --- ### 引脚定义 所有引脚宏集中在 `board_config.h` 尾部,按需修改: ```c /* I2C */ #define I2C_SCL_PORT GPIOF #define I2C_SCL_PIN GPIO_PIN_1 #define I2C_SDA_PORT GPIOF #define I2C_SDA_PIN GPIO_PIN_0 /* LED */ #define LED_RCU RCU_GPIOB #define LED_PORT GPIOB #define LED_PIN GPIO_PIN_1 /* UART */ #define UART_GPIO_PORT GPIOA #define UART_TX_PIN GPIO_PIN_2 #define UART_RX_PIN GPIO_PIN_3 #define UART_BAUDRATE 115200U ``` ### MCU 型号自动检测 `board_config.c` 中的 `mcu_detect_and_config()` 上电自动识别 GD32E230 的 Flash 容量(F4=16K / F6=32K / F8=64K),结果存入全局变量 `g_mcu_flash_size`,并自动选择对应的 UART 外设(USART0 或 USART1)。 --- ## Flash 偏移配置(配合 Bootloader) 如果固件需要通过 Bootloader 启动(Bootloader 占用 Flash 前部区域),需修改两处: **1. 链接脚本** — `LD/gd32e23x_flash.ld` 第 15 行: ```c // 默认:从 Flash 起始运行 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K // 配合 Bootloader:前 8KB 留给 Bootloader,App 从 0x08002000 开始 FLASH (rx) : ORIGIN = 0x08002000, LENGTH = 8K ``` **2. 向量表偏移** — `Src/system_gd32e23x.c` 第 44 行: ```c // 默认 #define VECT_TAB_OFFSET (uint32_t)0x00 // 配合 Bootloader(值 = Flash 偏移量,不含 0x0800 前缀) #define VECT_TAB_OFFSET (uint32_t)0x2000 ``` > ⚠️ 两个偏移值必须对应修改:`LD` 中的 `ORIGIN` 减去 `0x08000000` 应等于 `VECT_TAB_OFFSET`。 --- ## 工具链准备 ### 1. ARM GCC 工具链 - **版本**:xpack-arm-none-eabi-gcc-11.3.1-1.1 - **建议解压路径**:工程根目录下 `Toolchain/xpack-arm-none-eabi-gcc-11.3.1-1.1` - **官方下载地址**:https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases - **路径自定义**: 如需自定义工具链路径,修改 `cmake/arm-none-eabi-gcc.cmake` 中的 `_TOOLCHAIN_CANDIDATES` 列表,或通过 CMake 参数传入: ```bash cmake --preset Debug -DTOOLCHAIN_DIRECTORY=/your/path/bin ``` ### 2. OpenOCD(调试/烧录) - **版本**:xpack-openocd-0.11.0-3 - **建议解压路径**:任意位置(在 `.vscode/launch.json` 中配置路径) - **获取地址**:https://github.com/burakenez/gd32-tools-xpack-openocd/tree/v0.11.0-3 - **说明**: - 本版本提取自 Embedded Builder V1.4.1.23782。 - ⚠️ 请勿随意更换版本,因 GD32 MCU 支持有限,推荐严格使用此版本。 - **路径自定义**: 修改 `.vscode/launch.json` 中 `miDebuggerPath` 和 `serverpath` 指向你的 OpenOCD 路径。 --- ## 使用说明 ### 编译 ```bash # Debug 构建(-O0, -g3) cmake --preset Debug cmake --build build/Debug # Release 构建(-Os, -g0) cmake --preset Release cmake --build build/Release ``` ### 烧录 通过 VSCode 任务栏运行 `Flash MCU` 任务,或命令行: ```bash openocd -f interface/cmsis-dap.cfg -f target/gd32e23x.cfg -c "program build/Debug/Application.elf verify reset exit" ``` ### 产物 编译输出位于 `build//`: | 文件 | 说明 | |------|------| | `Application.elf` | ELF 固件(调试用) | | `{项目名}_{版本}_{编译条件}_{日期}.hex` | Hex 文件 | | `{项目名}_{版本}_{编译条件}_{日期}.bin` | 二进制文件 | | `{项目名}_{版本}_{编译条件}_{日期}.list` | 反汇编清单 | | `{项目名}_{版本}_{编译条件}_{日期}.map` | 内存映射 | --- ## 时钟配置说明 本工程默认系统时钟为内部 IRC8M 振荡器经 PLL 倍频后的 72MHz。 如需修改主频或时钟源,请编辑 `Src/system_gd32e23x.c` 文件: 1. 查找如下宏定义区: ```c // #define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL) // #define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) // #define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) #define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000) ``` 2. 取消你需要的时钟方案的注释,并注释掉其它方案。 3. 保存后重新编译工程即可生效。 详细时钟初始化流程可参考 `Src/system_gd32e23x.c` 文件中的 `system_clock_config` 及相关函数实现。 --- ## vcpkg 依赖管理(可选) 本工程可选支持 vcpkg 作为 C/C++ 工具链和构建工具的自动化依赖管理方案。 - 自动下载和管理如 CMake、Ninja 等构建工具,简化环境配置。 - 可扩展用于第三方 C/C++ 库的统一管理。 **启用方法**: 1. 在项目根目录创建 `vcpkg-configuration.json` 文件,内容如下: ```json { "registries": [ { "name": "microsoft", "location": "https://aka.ms/vcpkg-ce-default", "kind": "artifact" }, { "name": "arm", "location": "https://aka.ms/vcpkg-artifacts-arm", "kind": "artifact" } ], "requires": { "arm:tools/ninja-build/ninja": "^1.12.0", "arm:tools/kitware/cmake": "^3.28.4" } } ``` 2. 启动 VSCode 或命令行,vcpkg 会自动检测并安装所需工具。 如不需要 vcpkg,可忽略本文件。