更新一下文档
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
# LVGL PC 模拟器部署与使用说明
|
||||
|
||||
> 适用于:`simulator/` 目录(LVGL v9.3.0 SDL2 模拟器)
|
||||
> 用途:在 PC 上预览/调试 160×160 1bpp 单色菜单 UI,无需烧录 MCU
|
||||
|
||||
## 一、方案概述
|
||||
|
||||
### 1.1 背景
|
||||
|
||||
STM32F4-Base 的 UI 是 **160×160 1bpp 单色**菜单(`lv_menu` 树形菜单),使用自定义中文字体 `ui_font_cn_12`。在 MCU 上开发 UI 需要反复烧录调试,效率低。本模拟器在 PC 上直接编译运行相同的 UI 代码(`ui_menu.c`),实现所见即所得。
|
||||
|
||||
### 1.2 架构
|
||||
|
||||
```
|
||||
simulator/main.c ──→ lv_init → sim_port_init(SDL 窗口 + 键盘)→ ui_menu_init(共享 MCU 代码)
|
||||
│
|
||||
└── 主循环:SDL 事件 → lv_timer_handler → lv_refr_now
|
||||
```
|
||||
|
||||
| 模块 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| 入口 | `simulator/main.c` | SDL 初始化、主循环、键盘事件 |
|
||||
| 端口 | `simulator/sim_port.c` | SDL 显示 + 键盘输入 + mono 主题初始化(替代 MCU 端 `ui_port.c`) |
|
||||
| 配置 | `simulator/lv_conf.h` | **模拟器专用** LVGL 配置(1bpp + SDL 启用) |
|
||||
| 共享 UI | `Drivers/BSP/UI/ui_menu.c` | 与 MCU 端共用,不做任何修改 |
|
||||
| 共享字体 | `Drivers/BSP/UI/ui_font_cn_12.c` | 与 MCU 端共用 |
|
||||
| LVGL 源码 | `Lib/lvgl/` | 项目自带 v9.3.0,新增最小 CMakeLists.txt |
|
||||
| SDL2 SDK | `simulator/SDL2/SDL2-2.32.10/` | 本地预编译,无需安装 |
|
||||
|
||||
### 1.3 关键设计决策
|
||||
|
||||
- **SDL2**:LVGL 官方 `lv_port_pc_vscode` 同款显示方案
|
||||
- **CMake + MSVC**:本机使用 Visual Studio 2019 BuildTools(`Visual Studio 16 2019` / `-A x64`)
|
||||
- **仅 UI 预览**:模拟器只跑 UI,不包含网络(netTask/ftpTask)等 MCU 业务
|
||||
- **共享代码不复制**:UI 源码直接引用 `Drivers/BSP/UI/`,MCU 与 PC 同步维护
|
||||
|
||||
## 二、环境要求
|
||||
|
||||
| 依赖 | 版本 | 说明 |
|
||||
|------|------|------|
|
||||
| CMake | ≥ 3.15 | 本机验证 4.3.0-rc1 |
|
||||
| MSVC | VS2019 BuildTools | `Visual Studio 16 2019` 生成器,Hostx64/x64 |
|
||||
| SDL2 | 2.32.10 | 已解压到 `simulator/SDL2/`,无需安装 |
|
||||
| 操作系统 | Windows | 已验证 win32 |
|
||||
|
||||
> 说明:`simulator/SDL2/SDL2-2.32.10/` 是 `SDL2-devel-2.32.10-VC.zip` 解压后的目录,已包含 `include/`、`lib/x64/`。
|
||||
|
||||
## 三、首次部署(一次性)
|
||||
|
||||
### 3.1 下载 SDL2(如未包含)
|
||||
|
||||
若 `simulator/SDL2/` 为空,需手动下载解压:
|
||||
|
||||
1. 下载 `SDL2-devel-2.32.10-VC.zip`(官方 GitHub Releases 或官网)
|
||||
2. 解压到 `simulator/SDL2/`,确保目录结构为:
|
||||
```
|
||||
simulator/SDL2/SDL2-2.32.10/
|
||||
include/ ← SDL.h 及各头文件
|
||||
lib/x64/ ← SDL2.lib, SDL2main.lib, SDL2.dll
|
||||
```
|
||||
|
||||
> ⚠️ **重要**:LVGL SDL 驱动内部写死 `#include "SDL2/SDL.h"`。原版 SDL2 包的头文件直接平铺在 `include/` 下(没有 `SDL2/` 子目录),因此需要先把头文件复制一份到 `include/SDL2/` 子目录:
|
||||
> ```powershell
|
||||
> $inc = "simulator\SDL2\SDL2-2.32.10\include"
|
||||
> New-Item -ItemType Directory -Path "$inc\SDL2" -Force
|
||||
> Copy-Item "$inc\*.h" "$inc\SDL2\"
|
||||
> ```
|
||||
> 如未执行此步骤,编译报 `fatal error C1083: cannot open include file: "SDL2/SDL.h"`。
|
||||
|
||||
### 3.2 配置 CMake 并构建
|
||||
|
||||
```powershell
|
||||
cd simulator
|
||||
cmake -B build -G "Visual Studio 16 2019" -A x64
|
||||
cmake --build build --config Debug
|
||||
```
|
||||
|
||||
生成的可执行文件:`simulator/build/Debug/lvgl_sim.exe`(SDL2.dll 由 POST_BUILD 自动复制到同目录)。
|
||||
|
||||
### 3.3 运行
|
||||
|
||||
```powershell
|
||||
cd simulator\build\Debug
|
||||
.\lvgl_sim.exe
|
||||
```
|
||||
|
||||
或使用 CMake 自定义目标:`cmake --build build --config Debug --target run`。
|
||||
|
||||
## 四、日常使用
|
||||
|
||||
### 4.1 构建 + 运行
|
||||
|
||||
```powershell
|
||||
cd simulator
|
||||
cmake --build build --config Debug # 增量编译
|
||||
.\build\Debug\lvgl_sim.exe # 运行
|
||||
```
|
||||
|
||||
> 改 CMakeLists.txt 后需重新 `cmake -B build`;仅改 .c/.h 时直接 `cmake --build` 即可。
|
||||
> 遇到奇怪问题时先删 `build/` 全量重建:
|
||||
> ```powershell
|
||||
> Remove-Item -Recurse -Force build
|
||||
> cmake -B build -G "Visual Studio 16 2019" -A x64
|
||||
> cmake --build build --config Debug
|
||||
> ```
|
||||
|
||||
### 4.2 键盘操作
|
||||
|
||||
| 按键 | 功能 |
|
||||
|------|------|
|
||||
| ↑ / ↓ | 菜单项上下移动 |
|
||||
| ← / → | 展开/折叠 / 导航 |
|
||||
| Enter | 确认/进入子页 |
|
||||
| Escape | 返回上级 |
|
||||
|
||||
> 说明:模拟器**未创建鼠标**,纯键盘导航(与 MCU 端 keypad 一致)。
|
||||
|
||||
### 4.3 修改 UI 代码
|
||||
|
||||
- 修改 `Drivers/BSP/UI/ui_menu.c` 直接生效(重新编译模拟器即可预览)
|
||||
- 修改 `Drivers/BSP/UI/ui_font_cn_12.c` 同样直接生效
|
||||
- **不要**在 `simulator/` 下复制 UI 源码——保持共享,避免两份代码不同步
|
||||
|
||||
## 五、文件详解
|
||||
|
||||
### 5.1 `simulator/CMakeLists.txt`
|
||||
|
||||
| 配置项 | 作用 |
|
||||
|--------|------|
|
||||
| `SDL2_DIR` | SDL2 SDK 根目录 |
|
||||
| `LVGL_DIR` | 指向 `../Lib/lvgl`(项目自带源码) |
|
||||
| `UI_DIR` | 指向 `../Drivers/BSP/UI`(共享 UI 代码) |
|
||||
| `SDL2_INCLUDE_DIR` | **必须在 `add_subdirectory(lvgl)` 之前定义**,供 LVGL SDL 驱动找到 `SDL2/SDL.h` |
|
||||
| `LV_CONF_DIR` | 指向 `simulator/` 自身,供 LVGL 找到模拟器版 `lv_conf.h` |
|
||||
| `add_subdirectory("${LVGL_DIR}" lvgl_build)` | 编译 LVGL 静态库 |
|
||||
| UI 源文件 | 直接编译 `ui_menu.c` + `ui_font_cn_12.c` |
|
||||
| POST_BUILD | 自动复制 SDL2.dll 到输出目录 |
|
||||
|
||||
### 5.2 `Lib/lvgl/CMakeLists.txt`(新增)
|
||||
|
||||
LVGL 官方源码**原本没有** CMakeLists.txt(只有 `src/`),本工程新增了一个最小化版本:
|
||||
|
||||
- `file(GLOB_RECURSE ...)` 收集 `src/**/*.c` 编译成静态库 `lvgl`
|
||||
- 通过 `LV_CONF_DIR` / `SDL2_INCLUDE_DIR` 两个可选变量注入 include 路径
|
||||
- 这些变量由上层 `simulator/CMakeLists.txt` 在 `add_subdirectory` 前设置
|
||||
- MSVC 下关闭警告(`/W0`)
|
||||
|
||||
> ⚠️ 这个文件只被模拟器使用,**不影响 Keil 的 MCU 编译**(Keil 用自己的 `.uvprojx` 工程)。
|
||||
|
||||
### 5.3 `simulator/lv_conf.h`(模拟器专用)
|
||||
|
||||
与 MCU 端 `Lib/lv_conf.h` 的差异:
|
||||
|
||||
| 配置 | MCU 端 | 模拟器 |
|
||||
|------|--------|--------|
|
||||
| `LV_USE_SDL` | 0 | **1**(SDL 驱动) |
|
||||
| `LV_SDL_RENDER_MODE` | - | `LV_DISPLAY_RENDER_MODE_PARTIAL`(**1bpp 必须**) |
|
||||
| `LV_SDL_INCLUDE_PATH` | - | `"SDL2/SDL.h"` |
|
||||
| `LV_USE_THEME_MONO` | 0 | **1**(否则 1bpp 下文字黑底黑字不可见) |
|
||||
| `LV_FONT_DEFAULT` | `&ui_font_cn_12` | 同 |
|
||||
| `LV_MEM_SIZE` | 40KB | 40KB(模拟器内存充足,可放宽) |
|
||||
|
||||
### 5.4 `simulator/sim_port.c`
|
||||
|
||||
MCU 端 `ui_port.c` 的 PC 替代实现:
|
||||
|
||||
- `lv_sdl_window_create(160,160)` → SDL 窗口
|
||||
- `lv_theme_mono_init(disp, true, LV_FONT_DEFAULT)` → **必须**,否则黑屏
|
||||
- `lv_sdl_keyboard_create()` → 键盘输入(关联默认 group)
|
||||
- 无鼠标/触摸设备(纯键盘导航)
|
||||
|
||||
### 5.5 `simulator/dbg_log.h`
|
||||
|
||||
MCU 端 `Drivers/BSP/dbg_log.h` 会引用 `sys_clock.h`(RTC 时间戳),PC 上无法编译。`simulator/dbg_log.h` 是一个 stub:`DBG_INFO/ERROR/DEBUG` 直接映射到 `printf`,且 `simulator/` 在 include 路径最前会**优先生效**,覆盖 MCU 版本。
|
||||
|
||||
> 若 UI 代码新增 `DBG_*` 输出,会打印到模拟器控制台,方便调试。
|
||||
|
||||
## 六、注意事项与已知坑
|
||||
|
||||
### 6.1 构建相关
|
||||
|
||||
1. **`SDL2/SDL.h` 找不到**:需先执行 3.1 的 `include/SDL2/` 头文件复制步骤。
|
||||
2. **`lv_conf.h` 找不到**:`LV_CONF_DIR` 必须在 `add_subdirectory(lvgl)` **之前**定义(CMake 变量顺序问题)。当前 CMakeLists 已正确处理,勿随意调整顺序。
|
||||
3. **改 CMakeLists.txt 后不生效**:MSVC 生成器可能缓存旧配置,先删 `build/` 重建。
|
||||
4. **中文字符串文件编码**:源码是 UTF-8,CMake 已加 `/utf-8` 编译选项消除 C4819 警告。**不要**用 PowerShell `Set-Content` 等重写含中文的文件(参照 AGENTS.md 编码铁律)。
|
||||
|
||||
### 6.2 渲染相关
|
||||
|
||||
1. **黑屏排查顺序**:
|
||||
- `LV_USE_THEME_MONO` 是否 = 1 且在 `sim_port_init` 中调了 `lv_theme_mono_init`(1bpp 无主题 = 黑底黑字)
|
||||
- 主循环是否调用 `lv_refr_now(NULL)` 强制首帧输出(PARTIAL 模式下保证)
|
||||
- 是否重复设置 tick:SDL 驱动内部 `lv_tick_set_cb(SDL_GetTicks)`,**不要**再 `SDL_AddTimer` + `lv_tick_inc`
|
||||
2. **中文字体缺字**:`ui_font_cn_12` 只覆盖 83 个汉字(ASCII + 指定符号集),完整菜单需要 186 个唯一汉字。**当前菜单部分文字会显示为空白**,需重新生成字体(见下文 6.3)。
|
||||
3. **`LV_SDL_RENDER_MODE` 必须为 `PARTIAL`**:1bpp + SDL 若非 PARTIAL,`lv_sdl_window.c` 会 `#error` 编译失败。
|
||||
|
||||
### 6.3 字体生成(如需补全中文字符)
|
||||
|
||||
用 LVGL 官方 `lv_font_conv`(Node.js)重新生成:
|
||||
|
||||
```bash
|
||||
# 生成包含全部菜单字符 + ASCII 的 12px 1bpp 字体
|
||||
lv_font_conv --font simsun_regular.ttf --size 12 --bpp 1 \
|
||||
-r 0x20-0x7E \
|
||||
--symbols "<全部菜单用到的汉字,用引号包裹>" \
|
||||
--format lvgl --lv-font-name ui_font_cn_12 \
|
||||
-o Drivers/BSP/UI/ui_font_cn_12.c
|
||||
```
|
||||
|
||||
> 菜单字符集合:`主界面 装置信息 实时数据 交流量 直流量 开入量 定值参数 定值 遥调 零压 电压 查看 遥测量 测量值 遥调系数 遥测系数 双字节 装置遥调 装置维护 时间设置 强制复归 手动录波 自动录波 通讯设置 通讯参数 网络配置 SNTP设置 记录查询 SOE记录 事故记录 操作记录 告警记录 变位告警 遥信记录 自检记录 定值记录 录波记录 厂家设置 元件设置 恢复默认 全部恢复 默认参数 默认定值 默认系数 元件参数 版本显示 测量遥调 直流遥调 开出遥调 装置记录 遥调记录 信号复归 版本信息`(去重后 76 字)
|
||||
>
|
||||
> 注意:字体符号集是**有损的**——`lv_font_conv` 对不在符号集内的字符不生成字形,运行时该字符渲染为空白。这是当前缺字的根因。
|
||||
|
||||
### 6.4 与 MCU 端的差异
|
||||
|
||||
| 项 | MCU(Keil) | 模拟器(CMake+MSVC) |
|
||||
|----|------------|---------------------|
|
||||
| LVGL 编译 | Keil 工程添加源文件 | 新增 `Lib/lvgl/CMakeLists.txt` |
|
||||
| lv_conf.h | `Lib/lv_conf.h` | `simulator/lv_conf.h`(独立,互不影响) |
|
||||
| 显示端口 | `ui_port.c`(离屏 framebuffer) | `sim_port.c`(SDL 窗口) |
|
||||
| 输入 | 远端 keypad | SDL 键盘 |
|
||||
| 业务任务 | netTask/ftpTask 等 | 无,纯 UI |
|
||||
|
||||
### 6.5 其他
|
||||
|
||||
1. **`run` 目标**:CMake 定义的 `--target run` 会执行 `build/Debug/lvgl_sim.exe`。
|
||||
2. **窗口无法关闭**:点击窗口关闭按钮会触发 `SDL_QUIT` 正常退出;Escape 由 LVGL 键盘驱动处理(返回上级页)。
|
||||
3. **多显示器/高 DPI**:SDL 窗口固定 160×160 物理像素,Windows 缩放可能放大显示,属正常现象。
|
||||
|
||||
## 七、常见问题(FAQ)
|
||||
|
||||
### Q1: 编译报 `cannot open include file "SDL2/SDL.h"`?
|
||||
A: 未执行 `include/SDL2/` 头文件复制,见 3.1。
|
||||
|
||||
### Q2: 编译报 `cannot open include file "lv_conf.h"`?
|
||||
A: `LV_CONF_DIR` 变量未在 `add_subdirectory(lvgl)` 前定义,检查 `simulator/CMakeLists.txt` 变量顺序。
|
||||
|
||||
### Q3: 运行后窗口全黑?
|
||||
A: 按 6.2 黑屏排查顺序检查:mono 主题 → `lv_refr_now` → tick 不重复。
|
||||
|
||||
### Q4: 菜单某些中文显示空白?
|
||||
A: 中文字体缺字(覆盖 83 字,需要 186 字),见 6.3 重新生成字体。
|
||||
|
||||
### Q5: 修改了 UI 代码但模拟器没变化?
|
||||
A: 确认修改的是 `Drivers/BSP/UI/ui_menu.c` 而非 `simulator/` 内的副本(本工程无副本);然后重新 `cmake --build`。
|
||||
|
||||
### Q6: 能调试网络/存储等功能吗?
|
||||
A: 不能。模拟器仅预览 UI,不含 CH395F/NAND/ADC 等硬件业务。
|
||||
|
||||
## 八、文件清单
|
||||
|
||||
| 路径 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| `simulator/main.c` | 新增 | 入口 |
|
||||
| `simulator/sim_port.c` / `.h` | 新增 | SDL 端口 |
|
||||
| `simulator/lv_conf.h` | 新增 | 模拟器 LVGL 配置 |
|
||||
| `simulator/dbg_log.h` | 新增 | printf 日志 stub |
|
||||
| `simulator/CMakeLists.txt` | 新增 | 构建脚本 |
|
||||
| `simulator/SDL2/SDL2-2.32.10/` | 新增 | SDL2 SDK(含 include/SDL2/ 子目录) |
|
||||
| `Lib/lvgl/CMakeLists.txt` | 新增 | LVGL 最小 CMake(仅模拟器用) |
|
||||
| `Drivers/BSP/UI/ui_menu.c` | 未改 | 共享 UI 代码 |
|
||||
| `Drivers/BSP/UI/ui_font_cn_12.c` | 未改 | 共享字体(缺字待补) |
|
||||
| `simulator/build/` | 生成物 | 构建输出,可随时删除重建 |
|
||||
@@ -0,0 +1,152 @@
|
||||
# UI 中文字体生成与配置
|
||||
|
||||
> **适用范围**:STM32F4-Base 远程单色屏(160×160,1bpp,`LV_COLOR_FORMAT_I1`)的 LVGL 中文显示。
|
||||
> **目标**:把工程实际用到的汉字生成**子集化 1bpp 位图字体**,挂到 `LV_FONT_DEFAULT`,使菜单/标签正常显示中文并推流到客户端。
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景
|
||||
|
||||
- LVGL 内置字体(Montserrat 等)**不含中文**;`LV_FONT_SIMSUN_16_CJK` 等全字库体积过大,不适合 160×160 小屏。
|
||||
- 本工程显示是 **1bpp 单色**:像素 1=亮(白)/0=暗(黑),与客户端 `mono_to_png` 的 `1→白` 语义一致。
|
||||
- 方案:用 `lv_font_conv` 把系统中文字体(**宋体 SimSun**)按"实际用到的汉字 + ASCII"子集,生成 1bpp 的 LVGL 字体 `.c`。
|
||||
|
||||
生成产物:`Drivers/BSP/UI/ui_font_cn_12.c`(变量名 `ui_font_cn_12`)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 工具准备
|
||||
|
||||
### 2.1 工具与环境确认
|
||||
|
||||
| 工具 | 用途 | 安装 |
|
||||
|------|------|------|
|
||||
| Node.js (≥ v14) | 运行 `lv_font_conv` | 已具备 |
|
||||
| `lv_font_conv` | TTF/OTF → LVGL 字体 `.c`(官方离线转换器) | `npm i -g lv_font_conv` |
|
||||
| Python `fontTools` | `make_font.py` 读取 `.ttc` 集合时抽取单字重(仅在字库为 `.ttc` 时需要) | `pip install fonttools` |
|
||||
|
||||
安装完成后验证可用:`lv_font_conv -h` 能打印用法即成功。
|
||||
|
||||
---
|
||||
|
||||
## 3. 提取字符集(只取会显示的汉字)
|
||||
|
||||
已落库脚本 `tools/font_gen/extract_cn.py`:扫描 `Drivers/BSP/UI/*.c/.h` 与 `App/task/ui_task.c/.h` 中**字符串字面量**里的非 ASCII 字符,跳过 `/* */`、`//` 注释与字符常量(避免把注释里的汉字也打进字体、徒增体积),输出 `<仓库根>/ui_cn_chars.txt`。脚本自动定位仓库根,可在任意目录运行。
|
||||
|
||||
**执行命令(在仓库根目录):**
|
||||
|
||||
```bash
|
||||
python tools/font_gen/extract_cn.py
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
scanned 9 files; unique non-ASCII chars: 83
|
||||
-> D:\Code\DTU Code\STM32F4-Base\ui_cn_chars.txt
|
||||
```
|
||||
|
||||
产物 `ui_cn_chars.txt` 为本工程实际显示的汉字清单(当前 83 字),可留作字符集记录。
|
||||
|
||||
---
|
||||
|
||||
## 4. 生成字体
|
||||
|
||||
已落库脚本 `tools/font_gen/make_font.py`:自动定位 `lv_font_conv`(全局安装或 PATH)、自动处理宋体 `.ttc` 的 face0 抽取,直接生成 `Drivers/BSP/UI/ui_font_cn_12.c`。
|
||||
|
||||
**前置依赖(仅需一次):**
|
||||
|
||||
```bash
|
||||
npm i -g lv_font_conv # TTF/OTF -> LVGL 字体 离线转换器
|
||||
pip install fonttools # 仅当使用 .ttc 集合字体(如宋体)时需要
|
||||
```
|
||||
|
||||
> 若 `npm i -g lv_font_conv` 报代理错误,先清代理:`npm config delete proxy` / `npm config delete https-proxy`。
|
||||
|
||||
**执行命令(在仓库根目录):**
|
||||
|
||||
```bash
|
||||
python tools/font_gen/make_font.py # 默认:宋体, 12px, 1bpp
|
||||
python tools/font_gen/make_font.py --bpp 2 # 宋体细笔画发虚时改用 2bpp
|
||||
python tools/font_gen/make_font.py --font C:/path/to/font.ttf # 换其他字体
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
extracted SimSun regular (face0) -> C:\Users\...\Temp\simsun_regular.ttf
|
||||
RUN: lv_font_conv.cmd --font ... --size 12 --bpp 1 -r 0x20-0x7E --symbols ... --no-compress --format lvgl --lv-font-name ui_font_cn_12 -o ...\ui_font_cn_12.c
|
||||
OK 36393 bytes -> ...\Drivers\BSP\UI\ui_font_cn_12.c
|
||||
```
|
||||
|
||||
参数说明:
|
||||
- `--bpp 1`:单色无抗锯齿;体积最小。**注意** lv_font_conv 在 1bpp 下斜线/细笔画偶发"丢像素",宋体尤甚。
|
||||
- `--bpp 2/3`:字形带灰度,渲染到 1bpp 屏时按 `LV_DRAW_SW_I1_LUM_THRESHOLD` 阈值化,笔画更连贯;子集仅几十~上百字,体积仍很小。
|
||||
- `--no-compress`:关闭内置压缩,规避 `LV_FONT_COMPRESSED` 未启用导致的兼容问题。
|
||||
- `--lv-font-name ui_font_cn_12`:生成的 `lv_font_t` 变量名,须与下面 `LV_FONT_DECLARE` 一致。
|
||||
|
||||
---
|
||||
|
||||
## 5. 配置接入
|
||||
|
||||
### 5.1 声明与设为默认字体(`Lib/lv_conf.h`)
|
||||
|
||||
该文件当前为 **UTF-8(带 BOM)**。历史上它曾为 GBK,且工作区版本因某次整文件文本重写导致中文注释被 `U+FFFD` 不可逆损坏(`HEAD` 中的 GBK 版本仍干净)。
|
||||
|
||||
> **损坏恢复**:若二次损坏,不要用整文件文本重写。正确做法:
|
||||
> `git show HEAD:Lib/lv_conf.h` 以 `gbk` 解码得到干净中文 → 叠加第 5.1 节的字体配置改动 → 重新写为 `utf-8-sig`(UTF-8 带 BOM)。这样中文可完整恢复,不会引入 `U+FFFD`。
|
||||
|
||||
```c
|
||||
/* 自定义中文 1bpp 字体:由 lv_font_conv 生成(ASCII + 本工程所需汉字子集) */
|
||||
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(ui_font_cn_12)
|
||||
|
||||
/* 默认字体:中文 1bpp 子集字体(已含 ASCII),菜单/标签均使用它 */
|
||||
#define LV_FONT_DEFAULT &ui_font_cn_12
|
||||
```
|
||||
|
||||
> 字体 `.c` 自身通过 `#ifndef UI_FONT_CN_12` 自包含,编译进工程即生效;无需额外 `#include`。
|
||||
|
||||
### 5.2 加入 Keil 工程
|
||||
|
||||
`MDK-ARM/STM32F407-Demo.uvprojx` 的 `Drivers/BSP/UI` 组追加(纯 ASCII 插入):
|
||||
|
||||
```xml
|
||||
<File>
|
||||
<FileName>ui_font_cn_12.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Drivers\BSP\UI\ui_font_cn_12.c</FilePath>
|
||||
</File>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 编译验证
|
||||
|
||||
```bash
|
||||
@build # 即 MDK-ARM\build.bat,调用 UV4 全量重建
|
||||
```
|
||||
|
||||
要求:`0 Error(s), 0 Warning(s)`。重新生成/修改字体或 `lv_conf.h` 后务必重建验证。当前已验证通过,`ui_font_cn_12.c` 正常编入。
|
||||
|
||||
---
|
||||
|
||||
## 7. 注意事项
|
||||
|
||||
1. **1bpp 细笔画发虚**:宋体在 1bpp 下可能丢像素。若上板/客户端中文偏淡,把第 4 节 `--bpp` 改为 `2` 重生成即可(子集小,体积可接受)。
|
||||
2. **字符集变更**:以后新增中文菜单项,须重跑第 3、4 节(重新提取 `ui_cn_chars.txt` 并生成),否则新字显示为方框。
|
||||
3. **编码**:UI 源文件须为 **UTF-8(带 BOM)**,LVGL 按 UTF-8 解码中文串;字体 `.c` 为纯 ASCII,无编码风险。当前 Keil 已加 Misc Controls 抑制项,无需额外 `--locale=english`。
|
||||
4. **字体体积**:12px + 1bpp + ~83 字 ≈ 36KB(RO-data);改 bpp 2 约翻倍,仍在 F407 Flash 余量内。
|
||||
5. **换字体**:黑体用 `simhei.ttf`(单文件免抽取);其余字体同理替换 `--font` 路径后重生成。
|
||||
|
||||
---
|
||||
|
||||
## 8. 文件清单
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `Drivers/BSP/UI/ui_font_cn_12.c` | 生成的中文 1bpp 字体(变量 `ui_font_cn_12`) |
|
||||
| `Lib/lv_conf.h` | 字体声明与默认字体配置 |
|
||||
| `MDK-ARM/STM32F407-Demo.uvprojx` | UI 组包含该字体 `.c` |
|
||||
| `ui_cn_chars.txt`(工程根) | 实际显示汉字清单记录(可删) |
|
||||
| `tools/font_gen/extract_cn.py` | 提取字符集脚本(见第 3 节) |
|
||||
| `tools/font_gen/make_font.py` | 生成字体脚本,自动定位 lv_font_conv 并处理 `.ttc`(见第 4 节) |
|
||||
Reference in New Issue
Block a user