From 44172e861a11da5035e8e98e488465bb7c58a46d Mon Sep 17 00:00:00 2001 From: "evan.liu" <583229071@qq.com> Date: Sun, 13 Sep 2026 10:45:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E3=80=8A=E6=95=B0=E7=A0=81?= =?UTF-8?q?=E7=AE=A1=E6=98=BE=E7=A4=BA=E8=AE=BE=E8=AE=A1=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E4=B9=A6=E3=80=8B(=E4=BB=85=E6=96=87=E6=A1=A3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 docs/数码管显示设计说明书.md: 汇总当日数码管联调成果 (脚号映射/位序/Charlieplexing公式/段码表/温度解码/软件接口/CLI命令/踩坑/示例) - docs/开发日志.md: 新增 §69 --- docs/开发日志.md | 7 ++ docs/数码管显示设计说明书.md | 147 +++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 docs/数码管显示设计说明书.md diff --git a/docs/开发日志.md b/docs/开发日志.md index f033731..95cf713 100644 --- a/docs/开发日志.md +++ b/docs/开发日志.md @@ -1656,3 +1656,10 @@ APP2 链接的镜像发向 APP1 区。设备端 END 校验(向量表 Reset PC 数值原样显示。 - 版本:APP `V1.00.39` → `V1.00.40`(`APP_FW_VERSION_NUM` 0x00010027 → 0x00010028)。Boot 不动(仍 V1.00.07)。 + +## 69. 整理《数码管显示设计说明书》(2026-09-06,仅文档) + +- 新增 `docs/数码管显示设计说明书.md`:汇总当日数码管联调成果(§58~§68), + 涵盖硬件脚号映射、修正后的位序(DIG1百/DIG2十/DIG3个/DIG4单位F-C/DIG5小数/ + DIG6-A°F/DIG6-B小数点)、Charlieplexing 段→脚公式、字符段码表、温度解码、 + 软件接口、CLI 命令、踩坑记录与显示示例。无代码改动。 diff --git a/docs/数码管显示设计说明书.md b/docs/数码管显示设计说明书.md new file mode 100644 index 0000000..000ed20 --- /dev/null +++ b/docs/数码管显示设计说明书.md @@ -0,0 +1,147 @@ +# YF30137 数码管显示设计说明书 + +> 版本:V1.1(2026-09-06,融合当日数码管联调的位序修正与 GPIOA 时钟修复) +> 关联文档:`docs/YF30137_驱动真值表.md`(完整段→脚真值表)、`docs/开发日志.md` §58~§68 +> 固件:`mcm-ddc-ble/src/app_display.c/h`(驱动)、`mcm-ddc-ble/src/cli_core.c`(CLI 命令) + +--- + +## 1. 概述 + +数码屏为 **YF30137 七脚 Charlieplexing 温度显示模块**:7 个 IO 脚两两复用电极,点亮 5 个数字位 + 2 个指示段。驱动由独立的 FreeRTOS 任务 `display_task` 逐段扫描完成。 + +温度显示格式:**`[百][十][个][F/C][小数]` + `°F` + 小数点**,量程 **0.0 ~ 999.9**(1 位小数)。 + +--- + +## 2. 硬件连接(脚号 → MCU 引脚) + +数码管脚 1~7(网络 `LED_1`~`LED_7`)与 MCU 引脚一一对应: + +| 数码管脚 | 网络 | MCU 引脚 | | 数码管脚 | 网络 | MCU 引脚 | +|---|---|---|---|---|---|---| +| pin1 | LED_1 | **PB0** | | pin5 | LED_5 | **PB11** | +| pin2 | LED_2 | **PB1** | | pin6 | LED_6 | **PB13** | +| pin3 | LED_3 | **PA0** | | pin7 | LED_7 | **PA6** | +| pin4 | LED_4 | **PA1** | | | | | + +- 7 个脚分布在 **GPIOA**(PA0/PA1/PA6)与 **GPIOB**(PB0/PB1/PB11/PB13)两个端口。 +- ⚠️ **两个端口时钟都必须使能**(`RCC_APB2_PERIPH_GPIOA` / `RCC_APB2_PERIPH_GPIOB`),否则 PA0/PA1/PA6 无输出(见 §9 踩坑 1)。 + +--- + +## 3. 显示位序定义(重要:当日修正) + +| 位 | 含义 | 说明 | +|---|---|---| +| **DIG1** | 百位 | 数字 0~9,前导零消隐 | +| **DIG2** | 十位 | 数字 0~9,前导零消隐 | +| **DIG3** | 个位 | 数字 0~9,恒显示 | +| **DIG4** | 单位字母 | **华氏显 `F`、摄氏显 `C`**(非数字位、非固定 F)| +| **DIG5** | 小数位(十分位) | 数字 0~9,恒显示 | +| **DIG6-A** | 华氏标志 °F | 华氏点亮、摄氏熄灭 | +| **DIG6-B** | 小数点 | 恒点亮(小数位恒显示) | + +> 旧代码曾把 DIG1~5 当作 5 个全功能数字位、DIG4 当普通数字位——**已修正**。 +> 注意 DIG6-A/DIG6-B 是**两个独立的单指示段**,不是逐位小数点(硬件特性)。 + +--- + +## 4. Charlieplexing 驱动原理 + +**段 S(A=0…G=6)在位 D(DIG1=1…DIG5=5)点亮**,由一对脚 `高→低` 驱动,其余 5 脚高阻: + +``` +高脚索引 h = (S + D) % 7 → 脚号 = h + 1 +低脚索引 l = (D - 1) + (S + D) / 7 → 脚号 = l + 1 +``` + +**DIG6 两个固定脚对**: + +| 段 | 功能 | 点亮方式 | +|---|---|---| +| A6 | 华氏 °F | 脚7 高、脚6 低(`PA6 高 → PB13 低`)| +| B6 | 小数点 | 脚1 高、脚7 低(`PB0 高 → PA6 低`)| + +**扫描要点**:逐段点亮(每段 250µs)→ 点完立即把两脚切回高阻(输入)→ 点下一段;同一数字的多段不能同时点(脚共用,否则鬼影)。一个完整扫描帧约 20ms。 + +--- + +## 5. 字符段码表(bit0=A … bit6=G) + +| 字符 | 段码 | 字符 | 段码 | 字符 | 段码 | +|---|---|---|---|---|---| +| 0 | 0x3F | 1 | 0x06 | 2 | 0x5B | +| 3 | 0x4F | 4 | 0x66 | 5 | 0x6D | +| 6 | 0x7D | 7 | 0x07 | 8 | 0x7F | +| 9 | 0x6F | A | 0x77 | b | 0x7C | +| **C** | **0x39** | d | 0x5E | E | 0x79 | +| **F** | **0x71** | — | 负号 G 段 | 0x40 | | + +- `F`(单位字母)= **0x71**(AEFG)、`C`(单位字母)= **0x39**(ADEF),用于 DIG4。 +- 完整每个数字位的段→脚真值表见 `docs/YF30137_驱动真值表.md`(段→脚公式不变,只是位语义按 §3 修正)。 + +--- + +## 6. 温度解码(`display_decode`) + +输入温度 `value`(float),输出 5 个位字符码: + +1. 钳位:`value < 0 → 0`;`value > 999.9 → 999.9`; +2. `scaled = (int)(value × 10 + 0.5)`(×10 转 0.1℃ 分辨率); +3. 落位:`DIG5(小数)=scaled%10` → `DIG3(个)=(scaled/10)%10` → `DIG2(十)=(scaled/100)%10` → `DIG1(百)=(scaled/1000)%10`; +4. 前导零消隐:百位为 0 消隐,百位已消隐且十位为 0 再消隐十位;个位与小数位恒显示; +5. **DIG4 = 华氏 `0x0F`(F) / 摄氏 `0x0C`(C)**; +6. 小数点(DIG6-B)恒亮;华氏标志(DIG6-A)随华氏/摄氏开关。 + +> 驱动**不做 F/C 数值换算**:华氏/摄氏只切换 DIG4 字母与 DIG6-A 指示,数值原样显示(单位换算由上层完成)。 + +--- + +## 7. 软件架构与接口(`app_display.c/h`) + +| 接口 | 说明 | +|---|---| +| `void display_set(float value, uint8_t type, uint8_t base)` | 设温度值 0.0~999.9;`type` 华氏/摄氏;`base` 已废弃(兼容保留)| +| `void display_set_raw(const uint8_t digits[5], uint8_t type)` | 直接写 5 个位字符码(绕过温度解码,用于 `Err`/`Lo`/`Hi` 等状态字)| +| `void display_auto_set(uint8_t on)` / `uint8_t display_auto_get(void)` | 自动扫描开关(关后 7 脚置高阻,交出手动控制)| +| `int display_pin_map(uint8_t pin_no, GPIO_Module**, uint16_t*)` | 数码管脚号 1~7 → GPIO 端口+掩码 | +| `void display_task(void*)` | 扫描任务:优先级 1、栈 256 字、20ms/帧、每段 250µs,循环喂狗 | + +内部状态:`g_disp_value/g_disp_type/g_disp_base`(数值)、`g_disp_raw/g_disp_raw_digits`(裸码模式)、`g_disp_auto`(自动开关)。 + +--- + +## 8. CLI 命令(`cli_core.c`) + +| 命令 | 说明 | +|---|---| +| `disp [f]` | 设温度显示;`f` = 华氏(DIG4 显 F + DIG6-A 亮),默认摄氏 | +| `dispauto [on|off]` | 自动扫描开关(查询/设置)| +| `dispset [0\|1\|z]` | 手动驱动数码管脚:`0` 低 / `1` 高 / `z` 高阻;`all` 一键全脚 | +| `disptest` | 显示自检:0.0~9.0 → 12.3/456.7/999.9 → 36.5F/36.5C | +| `apptest` | 温度量程扫测:0.1~9.9(步0.1) → 10~99(步1) → 100~990(步10) → 999.0,摄氏+华氏各一轮 | +| `pinset [0\|1]` | 通用 GPIO 读写(非数码管专用)| + +--- + +## 9. 关键踩坑与修正记录(当日) + +1. **GPIOA 时钟未使能 → PA0/PA1/PA6 无输出**:数码管驱动删掉 `LedInit` 后 GPIOA 时钟失去使能点(GPIOB 因 USART 仍在使能)。修复:`display_task` 开头显式使能 GPIOA+GPIOB,`dispset` 内再防御性使能一次。 +2. **位序理解错误**:旧代码把 DIG1~5 当 5 个全功能数字位、DIG4 当数字位。修正:DIG4 是单位字母、DIG5 是小数位。 +3. **DIG4 从"固定 F"改为"F/C"**:华氏显 F、摄氏显 C。 +4. **量程**:0.0~999.9(百十个小·数共 4 位数字 + 1 位单位),非 9999.9。 +5. **裸码模式**:`display_set_raw` 用于显示 0~9/A~F 之外的状态字符(如 Err),`display_set` 会清掉裸码回到数值解码。 + +--- + +## 10. 温度显示示例 + +| 温度 | DIG1(百) | DIG2(十) | DIG3(个) | DIG4 | DIG5(小数) | 小数点 | °F | +|---|---|---|---|---|---|---|---| +| 0.0 ℃ | (空) | (空) | 0 | C | 0 | 亮 | 灭 | +| 8.5 ℃ | (空) | (空) | 8 | C | 5 | 亮 | 灭 | +| 36.5 ℃ | (空) | 3 | 6 | C | 5 | 亮 | 灭 | +| 36.5 ℉ | (空) | 3 | 6 | **F** | 5 | 亮 | **亮** | +| 100.0 ℃ | 1 | 0 | 0 | C | 0 | 亮 | 灭 | +| 999.9 ℉ | 9 | 9 | 9 | **F** | 9 | 亮 | **亮** |