docs(注入验证): 按代码实况补交流轮次的裁定口径与判读陷阱

只读复核回报后逐条回代码核对,补八处;判据文档未动(在飞单写者目录)。

- 拆开「判据属主」的说法:验什么、算不算过从数据可信文档 §4.6.2,
  期望值的算术从本文——原文两处写「不一致以 §4.6.2 为准」,与 D2 / D5
  卡里的更正自相矛盾(照 §4.6.2 的三角系数与 50 Hz 接法跑会把好板判死)
- §8.2 前置门补三条:开机 first 行与 10 s hb 行是两拨;phasor 行不带任何
  valid 位(条件只有 phasor_get() == 0),有数不等于标定可用或没削顶;
  adc_health 的位只吃序号差与错误增量,注入正弦不会点亮 health 那几行
- §8.2 串口行补长跑口径:110 min 的 session 不能用 @test(静默 8 s /
  总超时 30 s、max_boot_count = 1、forbidden 含 [ERR] 而 D5 故意造 [ERR])
- §8.3 第 3 条改定性:负半周走片内钳位 / ESD 路径(网表 V0.1.tel :228-241
  实证这些节点无外置钳位二极管、无隔直电容),1.1 mA 标注为估算
- D1 加坑 ③:cal: ua_mv 是当拍瞬时码折算、meas: ua_mv 是 200 ms 快照的
  基波有效值,同名不同物,adc_task.c:595-599 原注勿互为判据
- D4 补测频取源顺序:先 UA(C02)再退 IA(C01),App/algo/freq.c:47
- §8.8 加一行分诊(health 位亮 = 查节拍丢帧,别查发生器);§8.11 补一条
  边界:算法精度已由主机侧单测在纯数字域钉住(且其幅值绕过 adc_cal),
  本轮只证信号进 sample_ring 之前那一段,别写成功能性重复验证

门禁:check_doc_links --sections-strict rc 0(92 处引用 / 93 % 可判定);
check_ids_new rc 0;表格列数 0 处不一致;无 BOM / CR 0 / U+FFFD 0 /
行尾空格 0 / 单一 LF 结尾。
This commit is contained in:
2026-10-29 19:29:21 +08:00
parent efda416f42
commit b367d16f3c
@@ -10,8 +10,11 @@
> 等标准源的只是**精度等级**那一步(`docs/任务规划/数据可信.md` §5 的「两点标定与精度验收」)。
> V0.1 有五路单极性削顶(`UB/UC/IB/IC/IN`),它们在交流轮次里只能作"预期削顶"的负向用例。
>
> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(D1~D6 验什么、过判据是多少),本文 §8 只写**怎么跑**;
> 两处不一致以 §4.6.2 为准(§8.10 记了本轮要回给它三处更正)。
> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(D1~D6 验什么、过判据是多少),本文 §8 只写**怎么跑**。
> 两处不一致时分两类裁定:**「验什么、算不算过」从 `docs/任务规划/数据可信.md` §4.6.2**;**「期望值怎么算」从本文**。
> 后者不是抬杠:那边有三处与代码算不拢(D2 的三角系数、D5 的「注 50 Hz 正弦就能造出锁存」、D3 与 D6 在 ×0.1 定点
> 出口下的分辨率),照它的数字跑会把好板子判成失败。本轮按本文数值跑,更正清单与回写路径见 §8.10 第 4 条;那个
> 文件正被在飞工作树改(`docs/任务规划/` 是单写者目录),**要不要现在一并改它,等用户裁定**。
---
@@ -281,7 +284,9 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
## 8. 交流(正弦)动态验证轮次(D1~D6)
> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(D1~D6 验什么、过判据是多少),本节只写**怎么跑**:
> 接哪个点、发生器怎么设、读哪一行的哪个字段、期望值怎么算、结果往哪回写。两处不一致以 §4.6.2 为准。
> 接哪个点、发生器怎么设、读哪一行的哪个字段、期望值怎么算、结果往哪回写。裁定口径同开头引导块:
> **判据语义从 `docs/任务规划/数据可信.md` §4.6.2,期望值的算术从本节**——它与代码算不拢的那三处,
> 回写清单见本文 §8.10 第 4 条;本节按更正后的数值跑。
> 为什么这一跳不用等标准源、以及它证不到什么,看 `docs/任务规划/数据可信.md` §4.6.1 与 §4.6.5,本节不重抄。
>
> **引用写法**:本节凡引用判据文档的小节,一律写成「文件名 + 小节号」的紧邻形式;只写 §8.x 的是本文自己的节。
@@ -318,7 +323,7 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| 万用表 AC 档 | 能读到 mV;**记明型号与响应类型**(真 RMS / 均值响应) | 基准就是它;D2 那一步两种表的读数都与基波期望差很多,不记响应类型就说不清是谁错 |
| 板子 | 产品构建(`test/board/test_config.h` 四个 `TEST_SUITE_*` 全注释)+ `@build` 0 错误 0 警告 + 烧录 `-Rst -Run` 与回读校验 | → `stlink-flash` skill 与 AGENTS.md「构建与验证」 |
| `[adc_cal]` 状态 | **保持未标定**(`eng=0`),别为"读数好看"先写标定值 | 现在 `meas:` / `phasor` 的量纲是 **ADC 引脚电压 V**(`App/algo/meas.h` 文件头的 A-lite 口径);标定一生效就换成二次值,本节全部期望值作废 |
| 串口 | 全程抓 RX 落盘:用 `serial-assistant` skill(`open` → `clear` → 跑 → 读日志文件或 `log --tail`) | 日志文件就是证据本体,§8.10 归档归档的就是它 |
| 串口 | 全程抓 RX 落盘:用 `serial-assistant` skill(`open` → `clear` → 跑 → 读日志文件或 `log --tail`) | 日志文件就是证据本体,§8.10 归档归档的就是它;**长跑别用 `@test`**——它绑定一轮启动语义(静默 8 s、总超时 30 s、`max_boot_count` = 1,且 forbidden 含 `[ERR]`,而 D5 故意造 `[ERR]`),110 min 的 session 必然超时或误判;daemon 全量写 `state/serial.log`(20 MB 上限自动截头保尾 10 MB)→ `docs/测试说明/自动化测试流程.md` 长时间采集一节 |
| 网口(可选) | 要读 104 那一路就插网线、PC 与板同网段(出厂 192.168.1.100),跑现成主站 `test/host/iec104_master.py`(`--ip` / `--port` / `--addr`) | 104 是浮点无量化 + 带品质,是 `meas:` 之外的第二条腿 |
| 共地 | 发生器 LO/GND 与板 AGND **单点**相连 | 不共地量到的是两地之差;现象见 §8.8 |
@@ -330,7 +335,13 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
- 四个位图 `vl` / `cl` / `rail` / `edge` 同一个位序(语义通道枚举 `App/algo/adc_input.h:38`):bit0 `UA`、bit1 `UB`、
bit2 `UC`、bit3 `UN`、bit4 `IA`、bit5 `IB`、bit6 `IC`、bit7 `IN`、bit8 `TEMP` → `0xE6` = bit1/2/5/6/7 = `UB/UC/IB/IC/IN`;
- **先上电、在基线里看到 `adc: UB` 有正常摆动,再开发生器输出**:贴轨锁存要求该通道"此前出现过中带样本"(释放沿前提,
`App/algo/adc_health.c` 的 `adc_health_rail_watch()`),开机就注大信号会让 D5 的锁存**装不上**,测出假不通过。
`App/algo/adc_health.c` 的 `adc_health_rail_watch()`),开机就注大信号会让 D5 的锁存**装不上**,测出假不通过。
- 开机各有一条 `first:` 与 `phasor(first)` / `freq(first)` 单发行(`App/task/adc_task.c:478` 与 `App/task/adc_task.c:201`
的 `tag` 参数),与 10 s 一轮的 `hb` 行是两拨——数心跳时别把 `first` 计进去;
- `phasor` 行**只要有数就打**:打印条件只有 `phasor_get() == 0`,不带任何 valid 位(`App/task/adc_task.c:209`)→
「phasor 有数」既不说明标定可用、也不说明这一路没在削顶,判读必须配 `vl` / `cl` / `rail` 三个位图一起看;
- 注入正弦**不会**点亮 `health:` 或 `sampling fault:` 那几行:`adc_health` 的位只吃序号差、错误计数增量与 tick 差
(`App/algo/adc_health.c:91-189`),与波形幅值无关;它们若亮是节拍 / 丢帧问题,别归因给发生器(§8.8 同一条)。
### 8.3 接线的四条(与直流轮次比,差别只在第 2、3 条)
@@ -344,7 +355,9 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| STM32(`UB` / `UC` / `IB` / `IC` / `IN`) | 0~3.3 V 单极性 | 无正向意义 | 只在 D5 用:注交流 = **故意触底**,负半周本就钉 0 |
3. **一次只注一路**(D3 除外,它要 `UA` 与 `UN` 两路同源),换表笔前先关输出。端子侧串阻是 **1 k**(R31 / R28 / R19 / R52 …),
STM32 那五路负半周经引脚钳位二极管灌向 VDDA:1.000 Vrms 时峰值电流约 (1.414 − 0.3) / 1 k ≈ **1.1 mA**,在绝对额定内,
STM32 那五路负半周经**片内**钳位 / ESD 路径灌向 VDDA——网表 `docs/硬件平台/V0.1.tel` :228-241 逐条实证这些节点只有
「电容 .2 + 串阻 .2 + MCU 脚」三件,**无外置钳位二极管、无隔直电容**,所以这条电流走的是芯片内部路径;
1.000 Vrms 时峰值电流约 (1.414 − 0.3) / 1 k ≈ **1.1 mA**(按片内钳位压降 0.3 V 估、仓内无实测,只用来论证量级),
但**别往上加幅度**——这种注入只允许出现在 D5 这类"故意削顶"的用例里。
4. **电流通道也是注电压**:`IA` 的注入点同样是电压进 R19 端子侧。这一轮证的是"给定引脚电压算得对不对",
不是"一次侧 1 A 怎么办"——后者要变比,属 `docs/任务规划/数据可信.md` §5 的端子 / 子板变比确认。
@@ -378,6 +391,7 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| 交叉读数 | 104 `0x4011`(短浮点)应 ≈ 万用表读数,单位是**引脚电压域**(`eng=0`,不是二次值) |
| 坑 ① | **别用 `phasor(hb)` 比幅值**——×0.1 定点,1 V 只剩 10 格(§4 尾注同一条) |
| 坑 ② | 104 每点 0.5 V(电流 0.005 A)变化死区,生效值在 `App/algo/run_par.c` 的 `[run_par]` 副本:1.000 → 1.100 V **不会**上报变化,那是死区不是坏了;连续扫幅度只看 `meas:` |
| 坑 ③ | **`cal: ua_mv` 与 `meas: ua_mv` 同名不同物**:前者是当拍瞬时码折算(`App/task/adc_task.c:587`),后者是 200 ms 快照里那一周波的基波有效值(`App/task/adc_task.c:605`),50 Hz 下二者可以差很多——`App/task/adc_task.c:595-599` 的原注就是**勿互为判据**,D1 只认 `meas:` |
记录表(每条 10 行取中枢):
@@ -443,7 +457,7 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| 期望(A 档 = 现状) | **就是不出数**:幅值门 `FREQ_AMP_MIN 50.0f`(`App/algo/freq.h:62`,`App/algo/freq.c:231` 拿它与基波有效值比)在引脚电压域恒不过 → `valid=0`、`f=0`、UI `Hz` 显 `--`、104 `0x401D` 上送 IV |
| 判据 | **如实报不可测**,而不是报一个看起来对的 50.00。若门限没改却报出 50.00 → 反而是 bug,停下查 `App/algo/freq.c` |
| B 档(要用户先点头) | 临时把 `FREQ_AMP_MIN` 由 `50.0f` 降到 `0.5f` → 重编(`@build`,要 build 锁)+ 重烧 → 扫 45.000 / 50.000 / 55.000 Hz 三点,PC 侧判据 0.02 Hz → 跑完**必须还原**,收尾判据见 §8.9 |
| 坑 | 非整 50 Hz 时 `meas:` 会拍频式跳动,属预期 → **扫频读 `freq(hb)`,别读 `meas:`**(`docs/任务规划/数据可信.md` §8 风险表同一条) |
| 坑 | 非整 50 Hz 时 `meas:` 会拍频式跳动,属预期 → **扫频读 `freq(hb)`,别读 `meas:`**(`docs/任务规划/数据可信.md` §8 风险表同一条);测频的取源顺序是先 `UA`(相量实例 C02)再退 `IA`(C01)(`App/algo/freq.c:47`)——本卡注 `UA` 走的就是 UA 源;若哪天只注 `IA`,测频会跟着 IA 走,别以为它锁在 UA |
记录表(A 档):
@@ -540,6 +554,7 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| 撤掉注入后 `rail` 仍非 0 | 锁存语义(sticky),只 `adc_health_rail_init()` / 复位清 → 复位后仍不清**才是** bug | §8.5 的 D5 改法 A |
| 读数带与幅度无关的偏置或漂移 | 共地 / 地环 | §8.2 末行 |
| `meas: seq` 不涨 | 发布闸门停 → 先查采集链,别判交流 | §8.2 前置门 |
| `health:` 或 `sampling fault:` 亮 | 与注入的波形无关:`adc_health` 的位只吃序号差、错误计数增量与 tick 差(`App/algo/adc_health.c:91-189`)→ 查节拍 / 丢帧,别查发生器 | §8.2 前置门 |
| 9 路全 0 | 读作"没数据",不是"输入为零" | §4 尾注 |
### 8.9 收尾判据(走过临时改动的一条都不许留)
@@ -574,3 +589,10 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
THD 与谐波方和根 / 温升 EMC 长时间漂移),本节只补一句现状:**样本出口未落地**(录波在飞)→ 本轮所有"波形"
结论都是**标量级**的、不是形状级;要看形状现在只能拿示波器直接看注入点,那只用于确认发生器输出干净与否,
**不进判据**。
再补一条「别把台架做成功能性重复」的边界:**算法本体的精度已经在纯数字域钉住了**——`test/host/phasor/phasor_test.c`
的 TC-PHASOR-003 与 TC-PHASOR-004(基波 = 峰值 / √2 容差 1 %、注入相角容差 0.5°)和 TC-PHASOR-006(2 / 3 / 5 次
谐波 1 %),以及 `test/host/freq/freq_test.c` 的扫频判据 J1(45~55 Hz 内 ≤0.02 Hz),都是把已知正弦**直接喂进
`sample_ring`**,绕过了 `adc_cal` 的折算(那里的幅值是工程量口径,不是引脚 µV)。所以 §8 这一轮真正要证的只有
「信号走到 `sample_ring` 之前」那一段:发生器刻度与输出端接、前端串阻与滤波电容的幅频、两片转换器的同刻性、
码到 mV 的折算、出口的量化。这一轮过了**不等于**「算法精度已实测验证」,结论里别那么写。