Files
STM32F4-Base/docs/任务规划/数据可信.md
T
wandering1 4a4ad6bc5f chore(全仓): @build/@test 旧文档别名清退为技能调用名
现状口径:/keil-build 与 /serial-boot-test 是 DSH 会话的技能调用名,
不是 shell 命令;「名 + 命令行参数」的命令形态改为可执行体
run_boot_test.py 的真实调用。

- AGENTS.md:别名说明重写为「技能调用名不是 shell 命令」,两条目改
  「编译(/keil-build)」「串口回归(/serial-boot-test)」
- keil-build / serial-boot-test 两 skill 调用名与示例同步;task-worktree
  方案文档去掉 @build/@test 惯例从句;@task 保留(不在点名范围)
- 123 文件现状陈述全改;台架捕获、变更记录/时间线、rename 映射输入
  等 41 行历史证据保留旧名
- gen_memory_svg.py 6 处措辞随改,3 张 SVG 产物同批重跑
- 顺手补并行方案同行漏网计数 51→52 钩子

验证:提交期快钩子对 123 文件实跑全 Passed;check_doc_links --all
rc=0(3038 处、无法判定 0);check_mermaid --all rc=0;YAML 解析 52
钩子不变;skill-size rc=0;py_compile 全过;字节卫生零漂移。
2026-10-30 13:03:12 +08:00

481 lines
46 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据可信(等待台架与外部资源)
> **这篇是什么**:把"采集出来的数到底能不能信"一次讲完——已经证到哪一步、按构造还证不到什么、
> 下一跳怎么跨、哪些必须等外部资源。
> **它同时是设计约束的归属文件**:§2.1 / §2.3 / §2.6 / §4.1~§4.5 / §7 / §8 / §9 / §10 被**代码与测试头注释**
> 当口径出处引用(`adc_cal.*` / `meas.*` / `cfg_file.*` / `prot_elm` / `protect_task.c` / `ui_data*` /
> `test/host/prot_dim/*`),它们是**现行规范,不是"已完成记录"**。已完成的事项按"完成即销项"只删 §5 表里的行。
> 排序权威只有一处:`docs/任务规划/README.md` §2;后续事项索引在 `docs/任务规划/登记簿.md` §7。
> **最该先知道的一条**:保护判据现在处于**未标定闭锁**态。判据 = `App/algo/adc_cal.c` 的
> `adc_cal_prot_blocked()`——UA / UN / IA 的 `ADC_CAL_F_VALID` **全置位**才放行,`protect_task` 拿它的返回值
> 停走判据(判据已从 `protect_task.c` 搬进 `adc_cal.c`,旧行号引用作废;只有 `DTU_BENCH` 构建旁路,**且只旁路这一处**)。
> 用户裁定(2026-10-25):**保持闭锁到标准源到位**,不缩短解锁路径(不用万用表走捷径)。
---
## 1. 三十秒看清全局
图由 `tools/arch_diagram/gen_data_trust_ladder_svg.py` 生成(改图改脚本重跑,勿手改 SVG)。
![数据可信是五级台阶,现在踩在第 2 级](../images/数据可信台阶.svg)
每升一级只多答一个问题,台阶之间的高度差就是"下游能多信多少":
| 台阶 | 多答的问题 | 状态 |
|---|---|---|
| 1 通路活 | 9 路都在转换、没串道、极性没反? | ✅ 2026-10-27 已证 |
| 2 静态引脚电压 | 注 1 V 直流,读数是不是 1 V? | ✅ 2026-10-27 已证(六项判据全 PASS,§2.6) |
| **3 动态引脚波形** | **注 1 V 正弦,算出来还是不是 1 V?** | **⬜ 一次也没做过(§2.7 → 方案见 §4.6)** |
| 4 端子二次值 | 引脚上这 1 V 对应端子侧几 V? | 🟡 等子板原理图或实物 |
| 5 精度等级验收 | 额定工况下整条链误差够几级? | 🟡 等标准源 |
**三条结论**:
1. **第 1、2 级已闭环**,证据与判据的属主是 `docs/硬件平台/ADC通道映射说明.md` §8.1,执行步骤属主是
`docs/测试说明/专项验证/ADC前端注入验证流程.md`——本文不重抄,只写"证到哪、为什么不能再往外推"。
2. **第 3 级是当前唯一的空白,而且不需要任何外部资源**:一台能出 50 Hz 正弦的交流信号发生器,
接在**已经验证过的那个注入点**上就行。它比第 4、5 级安全一个量级——只需 ±2 V 以内的正弦,
而端子级验证要上 100 V / 220 V 二次值。**不用烧高压、不用标准源,这是把它排最前的理由**(§4.6)。
3. **第 4、5 级在等外部**:④ 子板/端子板变比(仓库里没有原理图)与标准源两点标定,
两者完成前 `eng` 保持 0,本波只承诺"ADC 引脚电压"。
**本文怎么读**:
| 你想做什么 | 直接看 |
|---|---|
| 判断现在这些数能信到什么程度 | §1 这张图 + §2.6(静态证到哪)+ §2.7(动态没证什么) |
| 改采集 / 算法 / 品质位相关代码 | §2.1 §2.2 §2.3(口径)+ §4.1~§4.5(设计依据) |
| 上台架做正弦验证 | §4.6(接法、六轮判据、读数出口、坑)+ §5 的「信号发生器动态波形验证」卡 |
| 看还差谁、按什么顺序做 | §5 任务卡 + §6 顺序图 |
| 确认某件事是**故意不做**而不是漏了 | §9;有没有踩坑风险看 §8 |
---
## 2. 事实基线(2026-10-29 代码级核对;行号是核对时快照)
### 2.1 通道与量纲(锚点:`adc_cal.*` / `meas.*` / `ui_data*`)
**已证的**:9 路语义 ↔ 物理通道 ↔ 转换器这三者一一对应(`k_adc_map` 与 CubeMX 标签逐条对齐 + 开机自检)。
**没证的**:这张表的系数只到**引脚**,不到端子。
| 语义通道 | 转换器 | 码值格式 | LSB(@ 引脚) | 前端 | ROM 默认系数(@ 引脚) | 交流可用性 |
|---|---|---|---|---|---|---|
| UA | TPAFE5160 | 16 位双极性 ±5 V | 152.59 µV | 1k 串 + 滤波 C(③ = 1:1,无分压) | **152.59 µV/码** | ✅ 可用 |
| UN | TPAFE5160 | 同上 | 152.59 µV | 同上 | **152.59 µV/码** | ✅ 可用 |
| IA | TPAFE5160 | 同上 | 152.59 µV | 同上 | **152.59 µV/码** | ✅ 可用(缺 A/V 变比) |
| UB / UC | STM32 ADC1 | 12 位单极性 0~3.3 V | 805.66 µV | 同上 | **805.66 µV/码** | ❌ 削顶(无中点偏置) |
| IB / IC / IN | STM32 ADC1 | 同上 | 805.66 µV | 同上 | **805.66 µV/码** | ❌ 削顶 |
| TEMP | STM32 ADC1 | 同上 | 805.66 µV | 同上 | 热敏非线性 | — 不纳入线性标定 |
- 通道数 `ADC_SEM_COUNT = 9`(8 电气 + 温度),枚举定义 `App/algo/adc_input.h:38-49`。
- 唯一折算点:`App/task/adc_task.c:382` 的 `frame[s] = adc_cal_apply((adc_semantic_t)s, code)`——
**全仓只有这一处**把码值变成工程量,现单位 = **ADC 引脚电压 V**(`eng = 0`)。
- 端到端链路分四段(① 语义↔网名↔通道、② 引脚电压↔码值、③ `AINn` ↔ 引脚、④ 端子 ↔ `AINn`),
属主 `docs/硬件平台/ADC通道映射说明.md` §7.1:①②③ 已定死(③ 变比 1:1),**只有 ④ 是缺口**。
### 2.2 量纲错配与量纲回归(锚点:`test/host/prot_dim/*`;M4 退出判据⑥)
**这一节为什么必须在**:台架此前"通过",是因为**没有一条判据检查"不该动作时不动作"**。
"码值当工程量"的错配曾让 OC 拿 ~11000 码值去比 10 A 定值 → **恒假动作**。这类错的可怕之处不是
"测不准",而是**每次都跳**,而且三处消费者(判据、104、UI)一起错、一处都不报错。
固化它的回归 = `test/host/prot_dim/`:从 **ADC 码值**出发、**显式写出码值↔二次值换算**,走真实的
折算 → 采样环 → 全周傅氏 → 元件判据链;任何一环把量纲弄丢(例如折算点被旁路),断言立刻翻转
(TC-PROTDIM-002 就是反错配对照,专门复现那次历史事故)。它用的是**合成系数 10 mV/码**,
不是板上 152.59 / 805.66 µV/码——**它证的是"链条别丢量纲",不证"变比数值对不对"**(后者归 §2.6 与 §4.6)。
| 量纲档 | 怎么进入这个档 | 现在的处置 |
|---|---|---|
| `eng = 0`(ADC 引脚电压 V) | `VALID` 未置位——**当前产品构建恒此态** | §4.3 闭锁停走整条判据链;UI 第 7 行显示"未标定"徽标 |
| `eng = 1`(二次值 V / A) | ④ 变比到手 **且** 电气 8 路 `adc_cal_flags()` 的 VALID 全置位(`App/app/ui_data_feed.c` 的 `feed_eng()`) | 定值与工程量同域,判据才名副其实 |
| 混档(最坏情况) | 只改折算系数、不改下游常数 | §2.3 那三处必须跟着动,这正是 §2.3 存在的理由 |
### 2.3 三个必须同步重定的下游常数(锚点:`freq.h` / `iec104_pts.*` / `prot_set.c`)
> 这节的意义是**"动一处量纲要同步三处"**,不是待办清单——三行现在两行已落地。
| # | 位置 | 现值与语义 | 状态 |
|---|---|---|---|
| 1 | `App/algo/freq.h:62` | `FREQ_AMP_MIN 50.0f`——测频幅值门,已按**二次值 V 口径**重定(50 V = 0.5×Un,与 `prot_set.c` 头部量纲基准同源) | ✅ 已重定;⚠ **副作用**:`eng=0` 期间帧值 ≤5 V < 50 V → 本门**恒不过** → `freq_valid()` 恒 0(`freq.h:58-60` 自陈)。这条直接决定 §4.6 里测频腿怎么读、为什么测频轮的"过判据"是"如实报不可测" |
| 2 | `App/protocol/iec104/iec104_pts.c:69-80` | `k_yc[].deadband` 已按点重定:电压 0.5 V、电流 0.005 A、频率 0.5 Hz(真源在 `run_par`,UI 可改) | ✅ 已重定;④ 变比到手后需再复核一次量纲 |
| 3 | `App/algo/prot_set.c:25-70` | `g_prot_set_meta[]` 定值 = 二次值 A / V(基准 100 V / 1 A):OC1 10 A、OV 120 V、UV 20 V、3U0 15 V… | 🟡 口径对,但**标定前无法在板上验真**;§7 #1 定了精度目标后连同 `min`/`max` 复核 |
### 2.4 / 2.5 —— 2026-10-25 瘦身时删除,编号不复用(防止被重新取走)
### 2.6 静态验证:已知电压注入已于 2026-10-27 台架闭环(锚点:`adc_cal.*` / `meas.*` / `ui_data*`)
判据与实测记录的属主 = `docs/硬件平台/ADC通道映射说明.md` §8.1,执行步骤属主 =
`docs/测试说明/专项验证/ADC前端注入验证流程.md`。一块万用表 + 一个电位器 + 串口 `adc:` 心跳行就够,
**不需要**示波器、信号源、标准源;注入点在串联电阻的端子侧 `U5` 排针(不碰 LQFP 引脚)。
| 项 | 实测 | 判据 |
|---|---|---|
| 零点(8 路逐路短接 AGND) | 0~5 码 | TPAFE ≤30 / STM32 ≤5 码 |
| 三点线性(UA 0.3 / 1.0 / 2.0 V) | R² = 0.9999997,截距 −7.2 码 | ≥0.999 |
| 斜率(UA,TPAFE) | **6544.2 码/V**(理论 6553.6,偏差 −0.14 %) | 偏差 ≤2 % |
| 逐通道映射 | 8 路各自塌到**本路** | 注入哪路只动哪路 |
| 极性(TPAFE 三路 −1.0 V) | −6566 / −6568 / −6566,对称性 ≤0.34 % | 落在 −6554 附近且 ≤2 % |
| 节奏 | Δ9998 / 10 s ≈ 1000 Hz,`idle=0`、`adc1_err=0` | 注入期间仍 1000 Hz |
六项全 PASS ⇒ ③ 段(`AINn` ↔ 转换器引脚)**变比 = 1:1**(若存在 2:1 分压,斜率应约 3277)、
`k_adc_map[]` 逐路对应、TPAFE 补码符号位解释正确、§2.1 的 ROM 默认系数被实测支持。
空载浮空读数(TPAFE ~11450 / STM32 ~1000)是**上电瞬态 + 输入悬空**,不是零点,别拿首帧当零点用。
**这一轮证到的是"一条水平线的高度"**:给定直流电压 → 码值 → 折算,斜率、零点、线性度、极性、
通道对位、节拍全在 ±2 % 内。**直流信号在时间轴上没有形状**,所以相位、频率、波形相关性、真实削顶、谐波
这五类**按构造**不在本节证据范围内——逐条列在 §2.7。另有两项**本轮未覆盖**:
串扰(零点步骤时其余七路浮空本身在漂)与"注入进行中"的节奏(只测了注入前后),口径同
`docs/硬件平台/ADC通道映射说明.md` §8.1 尾注。
**一个必须记住的区分**:`CLIPPED` 位是**来源派生**(`App/algo/adc_cal.c:291-293`:系数来自 STM32 就置位,
V0.1 恒命中 UB/UC/IB/IC/IN,位图 `0xE6`),它表示"这路不能测交流",**不等于**"这路此刻正在削顶"。真削顶的签名是
`cal:` 行的 `rail=` 位图与 `rail: edge=…` 那行 `[ERR]`——这条路径至今只在直流饱和里起过(§4.6 削顶轮)。
> **M4 承诺边界**:只到 **ADC 引脚电压**(`eng = 0`)。"端子二次值"要等
> §5「端子/子板变比确认」拿到变比、「两点标定与精度验收」用标准源写入 `[adc_cal]` 并置 `VALID`;
> `eng` 升 1 的条件是电气 8 路 VALID **全置位**(`App/app/ui_data_feed.c` 的 `feed_eng()`)。
> **本节编号与承诺边界口径勿删**——`adc_cal.*` / `meas.*` / `ui_data*` / `simulator/main.c` 的头注释都指到这里。
### 2.7 动态验证:正弦波一次也没采过
**一句话**:整条计算链现在只在**PC 合成数据**上验过,从没在**真实交流波形**上验过。
不是"精度差一点",是"这一档完全空白"。
证据(逐条可查,全部是各套件自己的自陈,不是推测):
| 出处 | 原话要点 |
|---|---|
| `test/host/phasor/run_unit_test.py` | 「板端**无信号源**,无法注入已知幅值/相位/频率的标准波形,因而无法验证"读数 = 设定有效值"」 |
| `test/host/meas/run_unit_test.py` | 「读数与注入源比对类判据仍归台架(实测采样类,本套件不覆盖)」 |
| `test/host/prot_dim/prot_dim_test.c` | 系数是合成覆写的 10 mV/码,非板上 152.59 / 805.66 µV/码 |
| `App/algo/adc_cal.h` | `adc_cal_two_point()`:「实测注入未做(台架待跑),本函数即"公式齐备"的交付物」 |
| `docs/测试说明/专项验证/ADC前端注入验证流程.md` | 「**只验直流**:零点 / 线性 / 通道映射 / 极性。不验交流有效值——台架无信号源」 |
| `App/task/adc_task.c` 心跳块 | `adc:` 是当拍瞬时码值、`meas:` 是 200 ms 快照——**没有一行能给出波形形状** |
按下游列一遍"现在能不能信":
| 下游 | 现在 | 为什么 |
|---|---|---|
| 基波有效值(RMS) | 🟡 算法在 PC 上证过(幅值 ≤1 %、49/51 Hz 下 ≤1.5 %),**经真 ADC 后一次没测** | 1 V 正弦进 ADC 后 `fAmSQ` 是否 = 1 V,无实测 |
| 相位 | ❌ 从未在真信号上比过;且代码里**没有跨通道相位符号约定** | 只许比同片内通道(§9 的硬件限制) |
| 频率 | ❌ **恒不启动** | 幅值门 50 V 是二次值口径,引脚域 ≤5 V 恒不过(§2.3 #1)→ UI `Hz` 行恒 `--`、104 `0x401D` 恒 IV |
| 削顶 / 品质 | 🟡 位图逻辑对,真削顶路径没跑过 | `rail:` 那条 `[ERR]` 至今只在直流饱和里起过 |
| 谐波 C04 / C05 | ❌ 实例建了,**无消费者、无出口** | `prot_elm.c` 无引用,`meas` 只算 `harm=1` |
| 保护判据 | 🔒 闭锁中 | §4.3 |
→ **下一跳就是 §4.6**:把一根真正的 50 Hz 正弦从**已经验证过的那个注入点**灌进去,
一次把上表里"手边设备能改"的几行改掉。
---
## 3. 目标与里程碑
**波次目标**:把"数"从原始码值推进到**有物理含义、有品质、有死区、能上送**的工程量。
M4 的六条退出判据(逐条对齐现状,别整格打勾):
| 退出判据 | 状态 | 证据 / 缺口 |
|---|---|---|
| ① 至少 1 路电压通道经已知电压注入验证,斜率与理论 LSB 偏差 ≤2 % | ✅ 2026-10-27 | UA 6544.2 vs 6553.6 码/V(−0.14 %),`docs/硬件平台/ADC通道映射说明.md` §8.1 |
| ② `adc_cal` 折算落地,采样环里是**引脚电压 V** 而非码值 | ✅ | `App/task/adc_task.c:382`(全仓唯一折算点) |
| ③ 8 通道系数 / 零点可落盘,加载失败回退 ROM 默认 | ✅ | `[adc_cal]` / `[adc_cal_ofs]`,见 §4.4 |
| ④ 三处下游常数按工程量重定并注明依据 | ✅(有尾巴) | §2.3;#1 在 `eng=0` 恒失效已记因于 `freq.h:58-60` |
| ⑤ "未标定 → 保护闭锁"生效 | 🟡 软件道 ✅;**"解锁"这半程要等 `VALID` 置位**才能上台架验 | `adc_cal_prot_blocked()` + `App/task/protect_task.c:245` |
| ⑥ 量纲回归用例(不该动作时不动作)通过 | ✅ | `test/host/prot_dim/`,见 §2.2 |
**所以 M4 差的是"台架面",而且它分两半**:
**动态这半(§4.6)手边就能做、不要外部资源**;端子与精度那半要等子板与标准源(§5 后两张卡)。
**M5 遥测链 / M6 运行参数与点表**:均已达成,口径沉淀在 `App/algo/meas.h`、`App/algo/run_par.h`
头注释与 §4.5;其中"104 上送值与**工程量**一致"仍挂在变比确认与两点标定上(注入验证只证到引脚电压口径)。
---
## 4. 设计要点
### 4.1 折算模型:板级事实进 ROM,现场标定进 cfg
```
工程量[V 或 A] = (code + b) × k_f
k_f = k[µV/码] × 1e-6 (float,init/load 时算一次)
```
| 符号 | 含义 | 存哪 | 定标 |
|---|---|---|---|
| `k` | µV/码(通道灵敏度) | cfg 段,int32 **Q16**(µV/码 × 65536) | 默认 = 板级理论系数(§2.1 表) |
| `b` | 零点偏移(码值) | cfg 段,int32 | 默认 0 |
| `k_f` | V/码(运行时) | RAM,`adc_cal_init/load` 时由 `k` 派生 | 不落盘 |
- **为什么存 µV 而不是 V/码**:`k` 在 V/码 量级是 3×10⁻⁴,Q16 只有 20 个刻度(5 % 分辨率);
换成 µV/码是 305,Q16 有 2000 万个刻度。
- **为什么 Q16 而不是参考项目的 Q10**:TPAFE 通道 Q10 只能表达 312(+0.16 %),Q16 误差 < 0.001 %;
两者都占 4 字节,Q16 把"系数定点舍入"这一项从误差预算里直接抹掉。参考项目用 2^10 是因为定点 DSP
乘法成本,本机有 FPU、运行时本来就是 float。int32 上限可表达 32767 µV/码,远够。
- **运行时不走定点**:`k` 预乘成 `float k_f`,逐点只做一次浮点乘——1 kHz × 9 通道 = 9k 次/秒,可忽略。
### 4.2 三态可用性:标定 ≠ 可测
`k` 的默认值是**板级理论系数**,此时工程量单位是"ADC 引脚电压",不是二次值——还缺互感器/子板变比。
所以通道状态必须让消费者区分三档,不能把引脚电压当二次值用:
```c
#define ADC_CAL_F_VALID 0x01u /* 该通道 k 已按变比标定 → 工程量为二次值 */
#define ADC_CAL_F_CLIPPED 0x02u /* 硬件削顶(单极性无偏置)→ 交流量不可信 */
```
| 通道 | `VALID` | `CLIPPED` | 消费者应如何对待 |
|---|---|---|---|
| UA / UN / IA | 标定后置位 | 0 | 可用于保护、计量、上送 |
| UB / UC / IB / IC / IN | 永不置位(V0.2 硬件改版前) | **1,且是来源派生**(不是实测削顶,见 §2.6 表) | 只作码值监视;点表**已绑定**,靠品质位把 104 侧驱动成 IV、值清零 |
| TEMP | 0 | 0 | 不参与线性标定,页面显示 `--` |
`adc_cal_flags(sem)` 是三处(UI / 104 / 保护)唯一的可用性查询入口;`adc_cal_apply()` **不返回**可用性,
所以"只看系数不看 flags"这种用法在接口层就被堵掉(对应 §8 的"削顶通道被当成可测"一行)。
### 4.3 未标定即闭锁(本波唯一的行为变更)
保护判据拿"ADC 引脚电压"跟"二次值定值"比必然误动作,所以 `protect_task` 多一个闭锁源:
**UA / UN / IA 的 `VALID` 未全置位 → 判据停走**(实现已搬进 `App/algo/adc_cal.c` 的
`adc_cal_prot_blocked()`,`App/task/protect_task.c:245` 消费并打 INFO + 记 SOE)。
- 与"自检失败 / 采样故障闭锁"同构(`PROT_HF_LOCK_MASK` 那一套),**不新增机制**。
- 现有台架 `/serial-boot-test` 的期望会因此变化——**这是有意的**,任务卡里同步更新判据。
- 台架调试要旁路只能走编译期开关 `DTU_BENCH`,不进 cfg、不进 104。
⚠ **`DTU_BENCH` 只旁路这一处**:它**不**旁路 §2.3 #1 的测频幅值门,也不产生任何读数出口。
### 4.4 落盘:拆两段,不碰引擎
`CFG_FILE_MAX_KEYS = 16`,8 通道 ×(k + b)= 16 正好顶格,将来加一个键就爆。故拆两段:
| 段名 | 键 | 字节 | 回调 |
|---|---|---|---|
| `[adc_cal]` | `k_ua` `k_un` `k_ia` `k_ub` `k_uc` `k_ib` `k_ic` `k_in` + `valid`(uint8 位图) | 8×4 + 1 = 33 | 不挂(RAM 副本即生效值) |
| `[adc_cal_ofs]` | `b_ua` … `b_in` | 8×4 = 32 | 不挂 |
段名 7 / 11 字符、键名 4 字符,均在 15 字符上限内;段数总计 5/8(含 `[run_par]` 9 键死区),未逼近上限。
- 系数唯一真源仍是这两段——104 写 k/b 经 `adc_cal_set()` 代理,`run_par` **不存第二份**;
落盘链走 `SYS_EVT_RUN_PAR_SAVE`(iec104Task peek 投递 → defaultTask 整档 save),`p_cb` 依旧未用。
- ⚠ **负零点**:引擎原本只有 `CFG_VAL_UINT`(`strtoul` + 上界校验),负的零点偏移会落成
`4294967291` 这种现场看不懂的数——**这就是补 `CFG_VAL_INT` 的动因**(§7 #3)。
备选"零点存码值 + 32768 偏置的 uint16"已否决:绕开引擎却要每个读点记住减偏置,属于给未来埋坑。
### 4.5 遥测快照:让 104 与 UI 共用一份上游
104 的 `s_src_yc_read()` 自己遍历相量、UI 将来也要一份 → 两处各自决定"什么时候算新值""品质怎么判",
迟早打架。本波引入 `App/algo/meas.c`:每 **200 ms** 从相量使用区取一次,产出
```c
typedef struct {
uint32_t seq; /* 只增;消费者据此判断是否换帧 */
uint32_t tick_ms;
uint8_t valid; /* 整帧有效 */
uint8_t rsv[3];
float yc[9]; /* 工程量(二次值或 ADC 引脚电压,由 flags 决定) */
uint16_t qds[9]; /* 每点品质:IV / NT / OV / CLIPPED */
uint8_t freq_valid;
float freq_hz;
} meas_snap_t; /* 72 B,双区共 ≈144 B;改字段 = 改协议,须同步 104 与 UI */
```
- **发布者 = `adc_task`**,在 `phasor_run()` / `freq_run()` 之后按 200 ms 分频发布;生产者在自己上下文里
发布,消费者不组装、不判断新旧。全仓 `meas_tick()` **调用点数 = 1** 是评审判据(§8"快照双写")。
- **跨任务读沿用 `phasor` 的双区原子交换**(写侧填非使用区、末尾翻单字节索引;读侧先取索引再整体拷),
**不是新机制**、不引入锁。
- 104 与 UI 都读这份快照 → **同一份数据、两个消费者**;104 侧值与品质整体透传,不做本地判断。
- **200 ms 是上送节拍,不是平均窗**:相量本身已是 1 ms 刷新的基波有效值,再平均只会引入滞后。
⚠ 这条在动态验证里有个可读的后果:注入非整 50 Hz 的正弦时,快照轨会呈现拍频式跳动,**属预期**(§8)。
### 4.6 动态波形验证:用信号发生器把整条计算链跑一遍
图由 `tools/arch_diagram/gen_data_trust_dc_ac_svg.py` 生成(改图改脚本重跑,勿手改 SVG)。
![上排直流静态标定、下排交流正弦验证:同一个注入点、同一套前端,两种证法](../images/ADC直流标定与交流验证.svg)
#### 4.6.1 为什么这一跳既不用标准源、也不用烧高压
| 理由 | 依据 |
|---|---|
| 注入点已经验证过,且就在那儿 | `docs/测试说明/专项验证/ADC前端注入验证流程.md` §3 的注入点清单(串联电阻端子侧 = `U5` 排针);③ 段 1:1 已拿到台架证据(§2.6) |
| **不知道 ④ 变比也能验算法** | 注入点在 ④ **之前**,发生器给的电压就是引脚电压,算法链要证的正是"引脚域里算得对不对" |
| 幅度小两个数量级 | 只需 ±2 V 以内的正弦(TPAFE 侧判据上限);端子二次值验证要上 100 V / 220 V,风险与设备都在那一级 |
| 现有静态验证的读数出口可直接复用 | 串口心跳 + 104 YC,零固件改动(§4.6.3) |
**这一跳证的是功能性**(算得对不对、品质报得实不实、节拍稳不稳),**不是计量**(误差几级)——
发生器不当"标准"的界线见 §4.6.5 与 §7 #9。
#### 4.6.2 判据(六轮:幅值 / 波形 / 相位 / 测频 / 削顶 / 谐波)
> **分工**:本节定"验什么、过判据是多少";**期望值的算术、接法细节与执行步骤**在
> `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8(同一轮次的手册,两边于 2026-10-29 已对齐)。
>
> **轮次名一律用语义短语(用户裁定 2026-10-30:清退"字母+数字"判据号)**:D1 → 幅值轮、D2 → 波形轮、
> D3 → 相位轮、D4 → 测频轮、D5 → 削顶轮、D6 → 谐波轮;本族旧号作废不得再取走
> (与二极管位号、网络自愈决策记录、链路延迟缺陷编号只是同形,各不相干)。
| 轮次 | 验什么 | 接法 | 读哪 | 过判据 |
|---|---|---|---|---|
| **幅值轮** | 基波幅值计量 | UA(R31 / `AIN1`)注 1.000 Vrms、50.000 Hz 正弦 | `meas:` 的 `ua_mv`;或 104 `0x4011` | 读数 = 万用表 AC 档读数,偏差 ≤2 %(与静态同档)。⚠ 别用 `phasor(hb)` 行比幅值——那是 ×0.1 定点,注 1 V 只剩 10 格(§4.6.3) |
| **波形轮** | 读数是否只跟基波走 | 同幅值改方波、三角 | 同上 | 期望值 = **基波分量有效值**(同峰值下的基波 / 峰值比:方波 ≈ **0.90**,闭式 4/π ÷ √2 = 0.900、20 点整周期 DFT 实算 0.904;三角 ≈ **0.573**,闭式 8/π² ÷ √2 = 0.573、实算 0.578),**不是**真有效值(方波 = 1.000、三角 = 0.583 峰值);偏差 ≤2 %。算术与逐波形对照表见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的波形卡。顺带把"这台仪表读的是基波"这条口径钉进文档——用户拿真有效值表去对会以为差了 10 % |
| **相位轮** | 相位 | UA 与 UN 两路**同片**(都走 TPAFE)注同幅、同相 | **定量档**:录波段文件 `test/host/wave_read.py fft`(浮点重算基波相位;段内表序 `UA` = 0、`UN` = 3);**定性档**:`phasor(hb)` 各行 `Re=` / `Im=` | **定量档**:同段内两路相位差 ≤2°,把发生器相位改 90° 后差值跟到 ≈90°。**定性档只判"跟随"**(差值落进 80°~100°)——`phasor` 出口是 ×0.1 定点,1.000 Vrms 时每格 0.1 V,角度量化最坏 ≈ atan(0.1 / 0.707) ≈ 8°,判不动 2°(§4.6.3)。⚠ 段与发生器**无绝对相位锁定**(触发瞬间钉在段内点 159),只能比**同段内两路**的相对差,跨段比相位或拿发生器相位当绝对基准都不成立。**只许比同片内**——跨转换器无同刻性(§9),STM32 那五路还有 1 拍乒乓滞后 |
| **测频轮** | 测频 | 同幅值轮的 1 V/50 Hz | `freq(hb):` 与 104 `0x401D` | **预期就是"不出数"**(幅值门 50 V 在引脚域恒不过,§2.3 #1)→ 这条的判据是"如实报不可测"(`freq_valid=0`、UI `Hz` 显示 `--`、104 上送 IV),**不是**报出一个错误的 50.00。想真验 45~55 Hz 精度(PC 侧判据 0.02 Hz)须临时把 `FREQ_AMP_MIN` 降到引脚域量级(如 0.5 V)单跑一轮 → §7 #8 + §8 风险行 |
| **削顶轮** | 削顶与品质路由(**负向用例**) | 给 UB(R52 / `AIN2`)注 **DC −1.00 V 并保持 ≥5 s**;或 1.000 Vrms 而频率 **2.0 Hz** 的正弦——两档都能造出"连续贴同一侧轨带"。⚠ **注 50 Hz 同幅正弦造不出锁存,且这是预期而非故障**:1 kHz 下一个周波只 20 点、正半周必落中带,而 `adc_health_rail_watch()` 任何一拍回中带就把计数清零(`App/algo/adc_health.c`),连续贴底最长 ≈ 209/360 × 20 ≈ 11 拍 < 20。TPAFE 侧在 ±2 V 判据上限内造不出这条(轨带 ±32112 码 ≈ ±4.9 V),只有 STM32 那五路能做 | `cal:` 行的 `rail=` / `edge=`;`rail: edge=…` 的 `[ERR]` 行;104 `0x4012`;段文件档另加 `wave_read.py shape` 的三把尺子(`--strict` / 再加 `--clip-superset` / 不带),逐条配法见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的削顶卡 | 负半周钉下轨 → **连续 20 拍同侧后该路贴轨位锁存**(`ADC_RAIL_N_RUN = 20`,`App/algo/adc_health.h:174`)、`edge` 起沿、104 上该路 IV 且值清零。锁存另有**释放沿前提**:该通道此前须出现过中带样本 → **先上电见基线摆动、再开发生器输出**,开机就注会测出假不通过。撤掉注入后 `rail` 仍非 0 是 sticky 语义(只有 `adc_health_rail_init()` / 复位清)——**复位后仍不清才是 bug**。⚠ 这条会**故意造出 `[ERR]`**,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 人工判读、排在最后单独一轮(§8 第一行) |
| **谐波轮** | 谐波轨 | 基波 + 20 % 二次 + 20 % 五次(IA 上注)。⚠ 峰值预算:1.000 Vrms 基波 + 两个 20 % 分量的最坏对齐 ≈ 1.98 V 已顶 ±2 V 红线 → 基波用 **0.800 Vrms**、二次与五次各 0.160 Vrms | **定量档**:段文件 `test/host/wave_read.py fft --ch 4 --all`(`IA` = 段内表序 4,直接给基波与 2 / 5 次谐波 RMS,单位 mV);**旁证**:UI 交流量页 `Ia2` / `Ia5`(1 mV)与 `phasor(hb) C04-IA-F2` / `C05-IA-F5`(×0.1 定点,只证这根轨不是恒 0) | 谐波轨读数 = 注入分量(**±2 %,走定量档**;周期行档判不动:0.160 Vrms 在 ×0.1 出口只有 1~2 格)。⚠ 这两根轨**目前没有任何下游消费者**(`prot_elm.c` 无引用、`meas` 只算 `harm=1`),所以谐波轮只证"算得对",**不证"有人用"**——出口归 §9 的谐波轨立项 |
**先做幅值 / 波形 / 削顶三轮**(纯读数、无跨通道约定),相位 / 谐波次之,测频轮视 §7 #8 的裁定。每条的两档跑法(周期行标量档 /
录波段文件定量档)、触发动作、耗时排布与失败分诊在 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.6。
#### 4.6.3 读数出口(零固件改动)
| 出口 | 有什么 | 坑 |
|---|---|---|
| 串口每 10 s 心跳(`App/task/adc_task.c` 心跳块) | `adc:`(9 路码值)、`cal:`(三路 mV + `vl`/`cl`/`rail`/`edge` 位图)、`phasor(hb)`(逐实例 `Re` / `Im` / `rms`)、`freq(hb)`、`meas:`(快照轨) | MicroLIB 无 `%f`,全是定点:`phasor` ×0.1(**1 V 注入只剩 10 格**)、`freq` ×0.01 Hz、`cal:` / `meas:` ×1000(1 mV)。10 s 一行的单点瞬时值对 50 Hz 等价于随机相位抽样 |
| 104 YC(现成 PC 主站 `test/host/iec104_master.py`) | `0x4011`~`0x4018` 八个电气量 + `0x401D` 频率,**浮点无量化**,还带品质 | UB/UC/IB/IC/IN 恒 IV、值清零 → 那五路只能回读串口码值域 |
| UI 交流量页 | `Ua` / `U0` / `Ia` / `Ia2` / `Ia5` / `Hz` / 标定徽标 共 7 行 | 160×160 单色;`--` **同时**表示"没数"和"有数但不可信" → 不能当判据,只能当旁证 |
| **段文件样本出口(代码侧已落地,2026-10-29)** | 每次触发一段:`/wave/WAVE00.BIN` 起共 100 个号轮转(FTP 根下可见),8 路 × 320 点原始码值加封存瞬间的标定与品质快照;PC 侧 `test/host/wave_read.py` 提供 dump / fft / shape / plot 四个子命令(bench 工具,纯标准库,自带 `--selftest`) | 「比对派生标量」已可升级成「PC 独立重算 vs 板上读数」对表(判据与执行步骤见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §4,格式属主见 `docs/子系统设计/故障录波设计说明.md` §6.2 与 §6.3)。**但板级那一轮还没跑**(注 1 V / 50 Hz、与 `meas:` 与 104 YC 对表、CRC 不符必须拒收的实测,见 `docs/任务规划/故障录波.md` 卡片判据);示波器仍旧只作旁证、不当判据。段内点序:触发瞬间落在段内点 159(预触发 160 点的最后一点),段的绝对相位与发生器无锁定关系,可核对的是相对相位与极性 |
| **仍然没有的(2026-10-29 更新)** | 没有命令控制台、也没有「把窗里 20 / 40 个点导出来」的定点 dump 子命令——**但样本出口本身已成立**(上一行的段文件:一次 320 点 / 8 路,比原来规划的 20 / 40 点窗更宽) | 现场取回一律走现成 FTP(21 端口),形状就地看回放页单通道、或在 PC 侧用同一脚本出图;示波器只对照发生器、不当判据。**判据已升级为「PC 独立重算 vs 板上读数」对表**,对表的执行轮次待台架(见 `docs/子系统设计/故障录波设计说明.md` §11) |
#### 4.6.4 接法与红线(照抄既有红线,不新发明)
- 注入点:串联电阻的**端子侧**焊盘(`U5` 排针),逐路清单见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §3;
引脚侧没有串阻保护,必须外串 **10 k** 限流。
- 幅度按**峰值**算,别看 Vrms 数字:1.000 Vrms 正弦峰值已 1.414 V;TPAFE 侧按判据只到 **±2 V**(满量程 ±5 V),
STM32 那五路是 **0~3.3 V 单极性**——给它们注交流只能是削顶轮那种"故意削顶"的用例,峰值同样不得超 3.3 V。
- 发生器与板**必须共地**(否则量到的是两地之间的差),且不形成地环:优先单点共地、必要时发生器浮地。
- **不许**因为"反正发生器便宜"就往端子侧上额定电压——那是 §5 第二张卡(要变比)与 §9(要标准源)的范围。
#### 4.6.5 这台发生器证不到什么(别让读数长得像证据)
| 证不到 | 为什么 | 归属 |
|---|---|---|
| 端子二次值 | 注入点在 ④ 之前,算出来还是引脚域 | §5「端子/子板变比确认」 |
| 精度等级(0.5 级 / 1 级) | 发生器自己的幅值误差本身就是要被校的量,不能冒充标准源 | §5「两点标定与精度验收」+ §7 #1 |
| 跨转换器相位 / 功率 / 对称分量 | 两片转换器无共同采样触发(V0.1 硬件缺陷)+ STM32 侧 1 拍乒乓滞后;量纲链路口径见通道映射说明的链路分段一节 | §9(本波不做矢量类运算) |
| THD / 谐波方和根 | 固件里只有两根谐波轨,没有合成出口 | §9(挂谐波轨立项) |
| 温升、EMC、长时间漂移 | 单轮台架不覆盖 | 送检与型式试验 |
---
## 5. 任务卡(完成即销项删行;标识列用语义短语,不配编号)
> 资源图例:🔴 台架(COM3 / ST-LINK,`bench.lock` 独占)· 🟡 外部(标准源 / 子板原理图)· 🟢 纯软件。
> 状态:⬜ 未开始 · 🟦 进行中。**已闭环 = 直接删行**。
> 本表**只写判据**;执行步骤在 `docs/测试说明/专项验证/ADC前端注入验证流程.md`,实测结论在
> `docs/硬件平台/ADC通道映射说明.md` §8.1(动态实测结论开在其后)。
| 标识(任务名)| DoD(可验证验收判据) | 硬依赖 | 资源 | 写范围 | 状态 |
|---|---|---|---|---|---|
| **信号发生器动态波形验证** | 按 §4.6.2 跑完六轮(测频轮允许以"如实报不可测"通过),逐条记实测 / 判据 / 结论;执行步骤与判据表**新增到** `docs/测试说明/专项验证/ADC前端注入验证流程.md`(直流节之后开一节"交流"),实测结论在 `docs/硬件平台/ADC通道映射说明.md` §8.1 之后新开一节;证据(串口日志 + 104 落库)归档 `docs/测试说明/测试数据/boot_log_data/` | 静态注入闭环(✅ 2026-10-27)+ 一台能出 50 Hz 正弦、幅度可调到 1 Vrms 的交流信号发生器(**不需要标准源、不需要端子加压**) | 🔴 台架 + 手边发生器 | `docs/测试说明/`、`docs/硬件平台/` | ⬜ |
| **端子/子板变比确认** | 给出"端子电压 → ADC 引脚电压"的比值(万用表同时量端子与引脚,或查子板原理图后实测核对),写入 `docs/硬件平台/ADC通道映射说明.md`;据此判定 `eng` 能否置 1;数据缺失则本波只交付引脚电压并登记缺口 | 已知电压注入验证(✅);**与动态验证无依赖关系**,可并行 | 🟡 子板实物或原理图 | `docs/硬件平台/` | ⬜ |
| **两点标定与精度验收** | 电压 4 路(UA/UB/UC/UN)+ 电流 4 路(IA/IB/IC/IN)各做两点标定(零点 + 满度,温度不纳入),写入 `[adc_cal]` 并置 `VALID`;误差 ≤ 目标精度(待定:0.5 级 / 1 级 → §7 #1);证据归档 | 端子/子板变比确认;削顶五路的处置结论(削顶轮) | 🟡 标准源 / 继保测试仪 | `docs/算法/`、`docs/测试说明/测试数据/boot_log_data/` | ⬜ |
**为什么把动态验证排在第一**(不是因为它最重要,而是因为它把后面两张卡踩实):
1. 它**不依赖任何外部资源**,而另两张卡都在等东西;等待期正好做它。
2. 它复用刚闭环的注入点与读数出口,**边际成本几乎为零**。
3. 它会先把削顶轮那类"预期内的 `[ERR]`"暴露在台架规程里并写清判读,避免第二、三张卡跑到一半
才发现"自动化测试把这轮读成 FAIL"。
4. 它顺手把"发生器能证 / 不能证"的界线钉住,两点标定开跑时判据不会串档。
---
## 6. 并行与顺序
主干一条道,两处等外部资源(自环 = 等待),动态那一步不阻塞后面的卡:
```mermaid
flowchart TD
S([静态注入 2026-10-27 已闭环]) --> Q1{发生器在手?}
Q1 -- 否 --> W1[等待:发生器到位<br/>不动端子、不烧高压]
W1 --> Q1
Q1 -- 是 --> DYN[信号发生器动态波形验证<br/>幅值 · 波形 · 削顶 三轮先做]
DYN --> WB[回写:测试说明加「交流」一节<br/>通道映射补动态实测节]
WB --> Q2{变比到手?}
Q2 -- 否 --> W2[等待:子板实物或原理图]
W2 --> Q2
Q2 -- 是 --> CAL[两点标定与精度验收<br/>标准源 / 继保测试仪]
CAL --> V[电气 8 路 VALID 全置位]
V --> R[保护自动解卡<br/>闭锁 → 解锁台架验证]
R --> E([标准源送检 + 第三方 104 主站验收])
W1 -. 并行不阻塞 .-> ENG[eng 保持 0<br/>本波只承诺「ADC 引脚电压」]
ENG -.-> E
```
- **实测斜率偏差规则**:实测斜率与理论 LSB 偏差 >2 % 时**先查前端(分压 / 变比 / 焊接)再改系数**——
用系数凑斜率会把硬件的错固化成"标定值"。这条对动态同样成立(幅值轮偏差 >2 % 先查接线与共地)。
- 并行度规则见 `docs/环境与部署/并行任务工作树方案.md` §7.3。
---
## 7. 前置决策
> 一张表带状态列:🟡 是还没拍的(拍板前相应任务卡无法判定 DoD),✅ 是**口径锚点,勿删**——
> **第 3 行是 `CFG_VAL_INT`,`App/cfg/cfg_file.c:31` 引用的"§7 决策 3"就指它,勿改序。**
| # | 问题 / 决策 | 备选 | 现状 / 建议 | 状态 |
|---|---|---|---|---|
| 1 | **精度目标** | 0.5 级 / 1 级 | 决定两点标定的判据。**两点标定开跑前必须定**,否则"误差 ≤ 目标精度"这条 DoD 无法判定。保护判据本身只需 3~5 %,0.5 级是计量口径 | 🟡 开放 |
| 2 | **端子 / 子板变比从哪来** | ① 有子板原理图(直接算)② 只有子板实物(万用表同时量端子与引脚)③ 都没有 | 决定 `eng` 能否置 1。② 同样可行且够用;③ 则本波只交付"ADC 引脚电压",二次值登记为缺口 | 🟡 开放 |
| 3 | **`CFG_VAL_INT`(有符号零点)** | 补引擎值类型 / 零点改 uint16 + 32768 偏置 | 已定案:补值类型(`strtol` + `ERANGE` + 宽度上下界,`s_encode()` 带负号)。偏置方案否决理由见 §4.4 尾注 | ✅ 已定案 |
| 4 | 未标定即闭锁 | 保持闭锁 / 用万用表走捷径提前解锁 | 已定案:用户裁定 2026-10-25 **保持闭锁到标准源到位**,不缩短解锁路径 | ✅ 已定案 |
| 5 | 遥测快照发布权 | `adc_task` 分频发布 / 消费者各自计时组装 | 已定案:`adc_task` 唯一发布者(§4.5),调用点数 = 1 由评审守 | ✅ 已定案 |
| 6 | 温度是否纳入线性标定 | 纳入 / 不纳入 | 已定案:不纳入,`adc_cal_flags(TEMP)` 恒 0,页面 `--` | ✅ 已定案 |
| 7 | 注入层级与上限 | 引脚侧 / `U5` 排针端子侧 | 已定案:端子侧(③ 段的"端子侧"),≤2 V 直流——`U5` 排针是可安全接触的最低一级,引脚侧要拆子板 | ✅ 已定案 |
| 8 | **`eng = 0` 期间的测频幅值门怎么处置** | A 保持恒失效(现状,UI 恒 `--`)/ B 台架临时把 `FREQ_AMP_MIN` 降到引脚域量级跑一轮测频轮再还原 / C 换成"相对量"门限(如帧内最大值的一定时比例) | 建议 **A 为常态 + B 为一次性台架**,C 需要重新论证别在过渡期改。**跑之前先定**,还原由 §8 风险行盯 | 🟡 开放 |
| 9 | **动态验证的基准与发生器要求** | 万用表 AC 档 / 发生器自报刻度 / 借标准源 | 建议:以**万用表 AC 档为基准**,发生器只要求"波形干净、幅度稳定、频率能锁 50.000 Hz",**不拿它的刻度当精度**;判据档沿用静态 ±2 % | 🟡 开放 |
---
## 8. 风险
> 引用本表某一行时**写行名**(例:「削顶通道被当成可测」行),别写「末行 / 第 N 行」——本表会插行。
| 风险 | 触发条件 | 缓解 |
|---|---|---|
| **削顶负向用例被当成固件 bug** | 做削顶轮时 STM32 那五路必然钉下轨 → `rail: edge=…` 是 `[ERR]` 行,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 整轮被判 FAIL | 判读规则写进流程文档:"做削顶轮的这一轮 `[ERR] rail:` 属预期,只人工判读、不计入 `/serial-boot-test` 结论",或把这五路排在最后单独一轮并事先声明。同时别忘 `cl=0xE6` 是**来源派生**(§2.6),不是本轮新削出来的 |
| **拿发生器的精度当标准用** | 用发生器自报 Vrms 当基准值去比 | 基准 = 万用表 AC 档实测(§7 #9);发生器只当"波形干净、频率可锁"的信号源,它自己的幅值误差正是要被校的量 |
| **临时改了 `FREQ_AMP_MIN` 忘了还原** | 走 §7 #8 的 B 方案 | 改动落在产品头文件里、会编进固件。单列一条收尾判据:还原后 `/keil-build` 0 错误 0 警告 + `git diff` 里 `App/algo/freq.h` 必须为空;并在 §7 #8 那行留一句"本轮台架已还原" |
| **峰值当成有效值,顶到量程外** | 只看 Vrms 数字:1.000 Vrms 峰值已 1.414 V | 接线前按**峰值**核一遍:TPAFE 侧 ≤±2 V、STM32 侧峰值必须 <3.3 V(且负半周本就钉轨,只作削顶轮用) |
| **发生器与板不共地 / 地环** | 两台设备各自接电网地 | 单点共地,必要时发生器浮地;读数漂或出现与幅度无关的偏置先查这里 |
| **非整 50 Hz 注入被当成 `meas` 抖动 bug** | 注 49.5 / 50.5 Hz | `meas` 是**瞬时基波有效值透传、200 ms 是上送节拍不是平均窗**(§4.5)→ 快照轨会有拍频式周期间跳动,属预期。测频腿要扫频时读 `freq(hb)`,别读 `meas:` |
| **`cfg` 键数顶格** | 后续给 `[adc_cal]` 加键 | 已按 8+1 / 8 拆段;加键前先看 `CFG_FILE_MAX_KEYS`,必要时再拆 |
| **标定值把保护"调坏"** | 两点标定写入错误系数 | `adc_cal_set()` 校验范围(`k` 必须在板级系数 ×[0.5, 2.0] 内)+ 写入后回读校验;越界拒绝并留 `[ERR]` |
| **削顶通道被当成可测** | 消费者只看 `k` 不看 `flags` | `adc_cal_flags()` 是唯一查询入口,`adc_cal_apply()` 不返回可用性;单测覆盖"CLIPPED 通道 104 恒 IV" |
| **快照双写** | 104 或 UI 侧也加一个 200 ms 计时器 | 设计约定"唯一发布者 = `adc_task`";评审时数 `meas_tick()` 调用点 = 1 |
| **加压烧板** | 变比未确认就往端子加额定电压 | **端子级上额定值必须在变比确认之后**,且先量"端子对地通断"确认无直流通路。动态验证只在 `U5` 排针侧 ≤±2 V 做,正就是为了绕开这条风险 |
---
## 9. 范围边界(本波不做)
| 不做 | 理由 / 归属 |
|---|---|
| THD / 谐波方和根真有效值、快照 4 点平均 | 挂 `docs/算法/继电保护功能复现规划.md` 的「遥测谐波轨(可选)」一起做;快照保持"基波有效值 + 直取相量"口径(§4.5) |
| **谐波轨的消费出口**(C04 / C05 目前无人消费) | 谐波轮只证"算得对";接线到判据或上送属谐波轨立项范围,本波不动 |
| 端子级额定电压、绝缘耐压、温升 | 要标准源 / 型式试验条件;本波所有注入都在 `U5` 排针侧 ±2 V 以内 |
| 录波(原始码值段文件) | **已交付代码面**(2026-10-29 立项并当日落地):`docs/任务规划/故障录波.md`;本卡「动态波形验证」的样本出口**已**由录波段文件承担(§4.6.3 出口表已改),排序也随之调整(`docs/子系统设计/故障录波设计说明.md` §11);**没跑的是板级那一轮**(§10) |
| 104 文件传输(规约侧读文件) | 仍独立待排;现场与台架取回一律走现成 FTP(21 端口),规约侧文件服务等送检或第三方交接需求再议 |
| 等周波调频 | 与标定正交、无标准源时判据不可达,见 `docs/算法/继电保护功能复现规划.md` §3.1 |
| 功率 / 相位跨相比较 / 功率因数 / 对称分量 | **V0.1 硬件禁止**:跨转换器无同一时刻性,`docs/硬件平台/ADC通道映射说明.md` §7 通道归属行 |
| PT 断线判据 | 需要 `flags` 与遥信配合,而 V0.1 **无开入硬件** → 归开入波次 |
| 开入 / 开出固件 | 固件里**完全没有**这两类代码(`docs/问题记录/采集与数据处理短板评测.md` 登记),是另一个波次的量级 |
| 温度非线性折算 | §7 已定案行"温度不纳入线性标定" |
| 端子二次值(一次/二次变比换算) | **条件项**:变比确认拿到变比才做;拿不到则本波只到"ADC 引脚电压",`eng` 保持 0,缺口登记进 `docs/任务规划/登记簿.md` |
| UI 页面(含交流量回炉) | 归「UI 补齐」;本波只保证 `meas_snap_t` 与 `adc_cal_flags()` 可被其消费 |
---
## 10. 与其它工作的关系
| 工作 / 文档 | 关系 |
|---|---|
| **`docs/测试说明/专项验证/ADC前端注入验证流程.md`** | **执行步骤的属主**。本文只写"证到哪、判据是什么、为什么这么排";怎么接表笔、读哪一行、填哪张表一律在那篇里。动态验证的**步骤**同样落那篇(新开"交流"节),本文 §4.6 只留判据 |
| **通道映射说明** | `docs/硬件平台/ADC通道映射说明.md` §7.1(①②③④ 链路分段)与 §8.1(静态六项实测)是**量纲与实测记录的属主**;本文 §2.1 / §2.6 是它的**消费者**,不另立口径,动态实测结论也回写该文件 |
| **`docs/子系统设计/故障录波设计说明.md`** | 录波段文件是本卡「动态波形验证」的**样本出口**,数据面代码侧已落地(2026-10-29:环与段格式在 `App/algo/wave_ring.c` / `App/algo/wave_store.c`,PC 侧 `test/host/wave_read.py`);判据从「比对派生标量」升级为「PC 独立重算 vs 板上读数」对表的**执行轮次待台架**,动态验证的排序已因此让位给录波数据面(用户裁定 2026-10-29,理由与三处口径变更见 docs/子系统设计/故障录波设计说明.md §11) |
| **`docs/算法/采集与算法层设计说明.md`** | 算法与判据正文(全周傅氏、测频、保护元件);本文只规定"这些算法的信度到什么程度" |
| **`docs/子系统设计/IEC104上行设计说明.md`** | 动态验证的**读数出口**(`0x4011`~`0x4018` + `0x401D`);送检验收索引在 `docs/任务规划/登记簿.md` §7 |
| **送检验收** | 标准源送检依赖本文「两点标定与精度验收」;顺序不可倒(先变比 → 再标定 → 才解卡 → 才送检,§6) |
| **UI 补齐** | 已交付的 `meas_snap_t` + `adc_cal_flags()` 供 `ui_data_rt_t` 填 `eng`:现为 0 = 引脚电压,变比确认拿到变比后才升 1 = 二次值。**UI 不必等本文任何一张卡** |
| **双转换器无共同采样触发(V0.2 硬件改版)** | 本波的 `CLIPPED` 位就是这条硬件缺陷在软件里的可见形态;V0.2 改版后该位恒 0,页面与 104 绑定零改动 |