From b26f01f5ec2e49f5e2491583f577b107fc0101e8 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Thu, 29 Oct 2026 19:02:52 +0800 Subject: [PATCH] =?UTF-8?q?docs(=E6=B3=A8=E5=85=A5=E9=AA=8C=E8=AF=81):=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=A4=E6=B5=81=E6=AD=A3=E5=BC=A6=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E9=AA=8C=E8=AF=81=E8=BD=AE=E6=AC=A1=E7=9A=84=E5=8F=B0?= =?UTF-8?q?=E6=9E=B6=E6=89=A7=E8=A1=8C=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按 docs/任务规划/数据可信.md §5 任务卡 DoD:D1~D6 的执行步骤新增到 本篇,直流轮次之后开新节 §8;§1~§7 编号未动(外部只引用它的 §3)。 判据属主仍是数据可信 §4.6.2,新节只写怎么跑:设备与共地、开机前置 门、逐条执行卡(接法 / 设定 / 读数 / 期望 / 坑 / 记录表)、顺序与耗 时、[ERR] 判读、失败分诊、收尾判据、归档与回写、证不到的边界。 新节按代码实况记下三处与判据文档的分歧,本轮没有改数据可信.md (它正被在飞工作树 task/wave-record 修改,docs/任务规划/ 又是单写 者目录),更正待其合入后一次性回写: 1) D2 三角期望值「峰值/√6」应为 0.573(闭式)~0.578(20 点整周期 DFT,与固件同一个窗);照原数判会把好板子判成失败。 2) D5 的「注 50 Hz 正弦 → 连续 20 拍锁存」按 adc_health_rail_watch 的中带清零逻辑做不到(一周波仅 20 点、贴底最长约 11 拍), 给出 DC −1.00 V 与 2 Hz 两种零固件改动改法。 3) D3 / D6 在 phasor 心跳 ×0.1 定点出口下分辨率不足(1 V 只剩 10 格),给出 UI 目检档(1 mV)与等录波段文件两条路。 校验:check_doc_links.py --sections-strict 本篇 rc 0(88 处引用 / 91 % 可判定);check_ids_new.py 通过;无 BOM / CR / U+FFFD、表格列 数一致、单一 LF 结尾;文件 275 → 577 行。 --- docs/测试说明/ADC前端注入验证流程.md | 313 ++++++++++++++++++++++++++- 1 file changed, 307 insertions(+), 6 deletions(-) diff --git a/docs/测试说明/ADC前端注入验证流程.md b/docs/测试说明/ADC前端注入验证流程.md index e57088ea..e82f3ca9 100644 --- a/docs/测试说明/ADC前端注入验证流程.md +++ b/docs/测试说明/ADC前端注入验证流程.md @@ -3,13 +3,15 @@ > **这篇是什么**:已知电压注入验证的**执行侧**——判据与实测记录在 `docs/硬件平台/ADC通道映射说明.md` §8.1, > 这边写怎么接表笔、读哪一行日志、填哪张表、结果往哪回写。 > -> **本文只验直流**:零点 / 线性 / 通道映射 / 极性——它证的是"一条水平线的高度"。 -> **交流(正弦)动态验证不用等标准源**:一台信号发生器接在本文 §3 的同一批注入点上就能跑, -> 判据与接法见 `docs/任务规划/数据可信.md` §4.6;等标准源的只是**精度等级**那一步 -> (`docs/任务规划/数据可信.md` §5 的「两点标定与精度验收」)。V0.1 有五路单极性削顶 -> (`UB/UC/IB/IC/IN`),它们在交流轮次里只能作"预期削顶"的负向用例。 +> **本文分两个轮次**:§1~§7 = **直流轮次**(零点 / 线性 / 通道映射 / 极性,2026-10-27 六项 PASS, +> 证的是"一条水平线的高度";**不需要**示波器、信号源、标准源,**只需要**一块万用表 + 一个电位器 + 串口日志)。 +> §8 = **交流(正弦)动态验证轮次**(D1~D6,证的是"给定电压算得对不对、品质报得实不实、节拍稳不稳")—— +> 一台信号发生器接在本文 §3 的同一批注入点上就能跑,**同样不用等标准源**; +> 等标准源的只是**精度等级**那一步(`docs/任务规划/数据可信.md` §5 的「两点标定与精度验收」)。 +> V0.1 有五路单极性削顶(`UB/UC/IB/IC/IN`),它们在交流轮次里只能作"预期削顶"的负向用例。 > -> **不需要**示波器、信号源、标准源。**只需要**一块万用表 + 一个电位器 + 串口日志。 +> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(D1~D6 验什么、过判据是多少),本文 §8 只写**怎么跑**; +> 两处不一致以 §4.6.2 为准(§8.10 记了本轮要回给它三处更正)。 --- @@ -273,3 +275,302 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性, 与"加压试保护"是两件事,后者要等端子/子板变比确认(`docs/硬件平台/ADC通道映射说明.md` §7.1 链路分段表 ④ 行)之后单独排。 4. **引脚侧注入必须外串 10 k**,且先接线后上电、先断电后拆线。 5. 注入源与板子**共地**;电位器一端接 3.3 V、一端接 AGND、中间抽头串 10 k 到注入点。 + +--- + +## 8. 交流(正弦)动态验证轮次(D1~D6) + +> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(D1~D6 验什么、过判据是多少),本节只写**怎么跑**: +> 接哪个点、发生器怎么设、读哪一行的哪个字段、期望值怎么算、结果往哪回写。两处不一致以 §4.6.2 为准。 +> 为什么这一跳不用等标准源、以及它证不到什么,看 `docs/任务规划/数据可信.md` §4.6.1 与 §4.6.5,本节不重抄。 +> +> **引用写法**:本节凡引用判据文档的小节,一律写成「文件名 + 小节号」的紧邻形式;只写 §8.x 的是本文自己的节。 + +### 8.1 动手前先把出口分辨率算清楚(决定今天能判到哪一档) + +这一轮和直流轮次一样**没有样本出口**:板上没有任何"把窗里的点导出来"的通道(§4 那张表就是全部可读的东西), +所有判据都得从**已经算好的标量**读。各出口的实际分辨率如下——这张表决定哪几条今天能判到位: + +| 出口 | 打印处 | 分辨率 | 能判 | 判不动 | +|---|---|---|---|---| +| `meas: seq=.. v=.. ua_mv=.. un_mv=.. ia_mv=.. f=.. fv=..` | `App/task/adc_task.c:605` | **1 mV**(整数毫伏,只发 UA/UN/IA) | D1、D2 的幅值 ≤2 % | 相位、谐波、其余五路 | +| 104 YC `0x4011`~`0x4018` + `0x401D`(短浮点 + 品质) | `App/protocol/iec104/iec104_pts.c:70` | 3 位有效数字 ≈ 0.01 V | 单个静态工作点的幅值交叉读数、品质 IV | **小步进**(每点 0.5 V / 0.005 A 变化死区)、相位、谐波 | +| `phasor(hb) C0x-…-F1: Re=.. Im=.. rms=.. (x0.1)` | `App/task/adc_task.c:209` | **0.1 V,且向下截断** | 有数没数、量级、象限 | ⚠ **D3 的 ≤2° 与 D6 的 ±2 %**:注 1.000 Vrms 时 `rms` 只有 10 格,20 % 的谐波只有 2 格 | +| `freq(hb): f=.. valid=.. (x0.01)` | `App/task/adc_task.c:224` | 0.01 Hz | D4 的读数与新鲜度 | — | +| UI 交流量页 `Ua/U0/Ia/Ia2/Ia5`(3 位小数)、`Hz`(2 位) | `Drivers/BSP/UI/ui_page_ac.c:47` | **1 mV**(人工目检 + 拍照留证) | D6 谐波幅值、D1 交叉旁证、D4 的 `Hz` 显 `--` | 相位(页面上没有角度) | +| 录波段文件 `/wave/WAVE00.BIN` + [计划] `test/host/wave_read.py` | **主干尚无**(在飞工作树 `task/wave-record` 已做到代码侧) | 原始码值全样本 | 合入后 D3、D6 升级为「PC 独立重算 vs 板上读数」对表 | — | + +**所以这一轮分三档跑**(排序理由见 `docs/任务规划/故障录波.md` §2 末:动态验证真正缺的不是信号源,是**样本出口**; +判据升级口径见 `docs/子系统设计/故障录波设计说明.md` §11): + +| 档 | 条目 | 说明 | +|---|---|---| +| **今天判得动** | D1、D2、D4、D5(D5 的接法要按 §8.5 改,原因写在那张卡里) | 判据在 `meas:` / 104 / `freq(hb)` / `rail:` 上分辨率都够 | +| **判得动但要换出口** | D6 | 走 UI 目检档(1 mV),`phasor` 行只作旁证;没有谐波叠加功能就用同一张卡里的分次注入档 | +| **建议等段文件** | D3 | ×0.1 的定点出口判不了 2°:要么接受"90° 跟随"的定性档,要么等 `task/wave-record` 合入后一次判到位。硬要今天判只剩第三条路——临时把 `log_phasors()` 的 `* 10.0f` 改成 `* 1000.0f` 并同处改掉行尾 `(x0.1)`(不改标记会把读数误读 10 倍),跑完按 §8.9 还原。**这条路要不要走,先问用户。** | + +### 8.2 设备清单与开机前置门 + +| 项 | 要求 | 为什么 / 怎么核 | +|---|---|---| +| 信号发生器 | 正弦 / 方波 / 三角,**并有 DC 档**;频率可锁 50.000 Hz、也能设到 2 Hz;幅度 0~3 Vpp | **只要求"波形干净、幅度稳、频率锁得住"**,它的刻度不当基准(`docs/任务规划/数据可信.md` §7 #9)。DC 档是给 D5 改法 A 用的 | +| ⚠ 发生器输出端接设置 | 接板子时设成**高阻负载**,不要按 50 Ω 端接 | 按 50 Ω 端接而实际接的是高阻板输入 → 面板值与真实电压差 2 倍;这是台架"差一倍"最常见来源 | +| 万用表 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 归档归档的就是它 | +| 网口(可选) | 要读 104 那一路就插网线、PC 与板同网段(出厂 192.168.1.100),跑现成主站 `test/host/iec104_master.py`(`--ip` / `--port` / `--addr`) | 104 是浮点无量化 + 带品质,是 `meas:` 之外的第二条腿 | +| 共地 | 发生器 LO/GND 与板 AGND **单点**相连 | 不共地量到的是两地之差;现象见 §8.8 | + +**开机前置门**——接发生器**之前**日志就该长这样,不满足先回 §5 步骤 5.5 查节奏,别往下做: + +- `adc:` 行 10 s 一行,同一心跳里 `frames` 在涨("9 路全 0"要读成"没数据",§4 尾注);`idle=0`、`adc1_err=0`; +- `meas:` 的 `v=1`、`seq` 每 10 s 约 +500(200 ms 一帧;不涨 = 发布闸门停); +- `cal:` 的 `cl=0xE6` —— **这是来源派生**(V0.1 那五路本就触底,见 `docs/任务规划/数据可信.md` §2.6),既不是本轮战果也不是本轮故障; +- 四个位图 `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 的锁存**装不上**,测出假不通过。 + +### 8.3 接线的四条(与直流轮次比,差别只在第 2、3 条) + +1. **注入点与直流轮次完全相同**:§3 清单的**端子侧**焊盘(`U5` 排针,串阻的 1 脚侧)。③ 段 1:1 已由直流轮次实测 + (斜率偏差 −0.14 %,§6),所以端子侧电压就是引脚电压,不用再算变比。引脚侧仍须外串 10 k(§7 第 4 条)。 +2. **幅度按峰值核,别看面板上的 Vrms**:1.000 Vrms 正弦峰值已 1.414 V。 + +| 侧 | 判据上限(§7 红线 2) | 允许的最大正弦 Vrms | 本节用量 | +|---|---|---|---| +| TPAFE(`UA` / `UN` / `IA`) | ±2 V 峰值 | 1.414 Vrms | **1.000 Vrms**(峰值 1.414 V) | +| 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**,在绝对额定内, + 但**别往上加幅度**——这种注入只允许出现在 D5 这类"故意削顶"的用例里。 +4. **电流通道也是注电压**:`IA` 的注入点同样是电压进 R19 端子侧。这一轮证的是"给定引脚电压算得对不对", + 不是"一次侧 1 A 怎么办"——后者要变比,属 `docs/任务规划/数据可信.md` §5 的端子 / 子板变比确认。 + +### 8.4 记录表抬头(每条用例一份,与日志一起归档) + +```text +日期 ____ / 操作人 ____ / 板子序列号 ____ +固件 commit ________(@build 0 错误 0 警告:是 / 否) +发生器:型号 ______ 输出端接 = 高阻 / 50 Ω 波形 ____ 频率设定 ____ +万用表:型号 ______ AC 响应类型 = 真 RMS / 均值 共地方式 = 单点 / 发生器浮地 +注入点:路名 ____(端子侧 U5 / 引脚侧外串 ____ Ω) +[adc_cal] = 未标定(eng=0)—— 必须是这个状态 +基线(未注时):meas: ua_mv=____ un_mv=____ ia_mv=____ rail=0x____ cl=0x____ +``` +### 8.5 逐条执行卡 + +**每条卡的通用动作**:接好 → 开输出 → 等 ≥30 s(相量窗 + `meas` 200 ms 轨稳定)→ 取**连续 ≥10 行**心跳 → +先确认 `frames` 还在涨、`adc1_err=0`,再核数 → 关输出 → 填表。"连续 ≥10 行"不是保守:`meas:` 是 +**瞬时基波有效值透传**、200 ms 是上送节拍不是平均窗(`docs/任务规划/数据可信.md` §4.5), +单行读数带拍频式跳动,必须看一片才能定中枢。 + +#### D1 基波幅值(主用例,先做) + +| 项 | 内容 | +|---|---| +| 接法 | 发生器 → `UA`(R31 / `AIN1` / U5.A3)端子侧;万用表 AC 档**并同一注入点**——量真实加到板上的电压,不是面板值 | +| 设定 | 正弦、50.000 Hz、**1.000 Vrms**(峰值 1.414 V) | +| 主读数 | `meas: ua_mv=`(1 mV) | +| 期望与判据 | `ua_mv` ≈ 万用表读数 × 1000,偏差 **≤2 %**(与静态同档) | +| 交叉读数 | 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:` | + +记录表(每条 10 行取中枢): + +| 序号 | 万用表 AC (V) | `meas: ua_mv` | 期望 = 万用表 × 1000 | 偏差 % | 结论 | +|---|---|---|---|---|---| +| 1 | | | | | | +| 2 | | | | | | +| 3 | | | | | | + +**加做(3 min,非判据)**:0.500 / 0.200 Vrms 两点看是否**等比**——不是验精度,是看有没有隐藏的触底或死区。 +0.2 Vrms 那点 104 必然被死区吞掉,只读 `meas:`。 + +#### D2 读数是否只跟基波走(同峰值改波形) + +按**峰值对齐**(不是按 Vrms 对齐):三者峰值都取 1.414 V,发生器面板 Vrms 分别约 正弦 1.000 V、方波 1.414 V、 +三角 0.816 V。期望的**基波有效值**(全周傅氏基波口径:`App/algo/phasor.c:3` 的系数已预乘 √2/N、`fAmSQ` 直接就是 +有效值;下表的 20 点整周期 DFT 值就是按固件同一个窗算的): + +| 波形 | 基波有效值 / 峰值 | 峰值 1.414 V 时的期望 `ua_mv` | 真有效值 / 峰值(对照) | +|---|---|---|---| +| 正弦 | 0.707 | 1000 | 0.707 | +| 方波 | 0.904(闭式 4/π/√2 = 0.900) | ≈1278 | 1.000 | +| 三角 | 0.578(闭式 8/π²/√2 = 0.573) | ≈817 | 0.583 | + +- 判据:读数 = **基波**期望 ±2 %,**不是**真有效值。方波那栏最直观——真 RMS 表会读 ≈1414 mV、 + 均值响应表读 ≈1570 mV,而板上读 ≈1278 mV,**这正是"这台仪表读的是基波"的证据,不是 bug**; + 所以抬头里必须写清万用表响应类型(§4.6.2 D2 原话:拿真有效值表去对会以为差了 10 %)。 +- ⚠ **`docs/任务规划/数据可信.md` §4.6.2 的 D2 行把三角写成「峰值 / √6」(= 0.408)是错的**:按基波口径应为 + 0.573(闭式)~ 0.578(20 点整周期 DFT)。照那个数判会把好板子判成失败。本轮按本节数值跑, + 更正回写见 §8.10 第 4 条。 + +记录表: + +| 波形 | 峰值设定 (V) | 面板 Vrms | 万用表 AC 实测 | `ua_mv` | 期望 | 偏差 % | 结论 | +|---|---|---|---|---|---|---|---| +| 方波 | 1.414 | | | | ≈1278 | | | +| 三角 | 1.414 | | | | ≈817 | | | + +#### D3 相位(只许比同片内) + +| 项 | 内容 | +|---|---| +| 接法 | `UA`(R31)与 `UN`(R28)**都走 TPAFE**,同幅 1.000 Vrms、同相——发生器单路输出分两路即天然同相;双通道机型则两通道都设 0° | +| 读数 | `phasor(hb) C02-UA-F1: Re=.. Im=..` 与 `C03-UN-F1: Re=.. Im=..`,各取 `atan2(Im, Re)` 再比差值 | +| 判据(§4.6.2) | 同相时差值 ≤2°;把发生器(或 B 通道)改 90°,差值跟着走到 ≈90° | +| ⚠ 分辨率 | 出口只有 ×0.1 且向下截断:1.000 Vrms 时 Re/Im 各只有 ±10 格,**一格就是 0.1 V** → 角度量化误差最坏 ≈ atan(0.1 / 0.707) ≈ 8°,**≤2° 今天用串口判不出来** | +| 三个选择 | ① 今天只判**定性档**:同相 ≈0°、改 90° 后差值落进 80°~100° 即算跟随,容差写进记录表;② 等录波段文件合入后 PC 独立重算一次判到位(首选,§8.1);③ 临时改 `log_phasors()` 倍数为 ×1000 并改掉行尾 `(x0.1)`,跑完按 §8.9 还原——**先问用户** | +| 红线 | **只许比同片内**:跨转换器无同刻性(V0.1 硬件缺陷)+ STM32 那五路另有 1 拍乒乓滞后 → `docs/硬件平台/ADC通道映射说明.md` §7 | + +记录表(定性档): + +| 发生器相位设定 | C02-UA `Re` / `Im` | C03-UN `Re` / `Im` | 两路 `atan2` 之差 | 结论 | +|---|---|---|---|---| +| 0° / 0° | | | | | +| 0° / 90° | | | | | + +#### D4 测频(默认 A 档 = 判"如实报不可测") + +| 项 | 内容 | +|---|---| +| 接法与设定 | 同 D1(`UA`,1.000 Vrms / 50.000 Hz) | +| 读数 | `freq(hb): f=.. valid=..`;UI 交流量页 `Hz`;104 `0x401D` | +| 期望(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 风险表同一条) | + +记录表(A 档): + +| 频率设定 (Hz) | `freq(hb)` f | valid | UI `Hz` | 104 `0x401D` 品质 | 结论 | +|---|---|---|---|---|---| +| 50.000 | | | | | | + +#### D5 触底与品质路由(负向用例)——**接法必须按本卡改** + +- **`docs/任务规划/数据可信.md` §4.6.2 原文**:给 `UB`(R52 / `AIN2` / U5.B7)注同幅正弦 → 负半周钉下轨 + → 连续 20 拍后该路贴轨位锁存、`edge` 起沿、104 该路 IV 且值清零。 +- ⚠ **50 Hz 正弦造不出这个锁存**:锁存条件是"连续 `ADC_RAIL_N_RUN = 20` 拍贴同一侧轨带"(`App/algo/adc_health.h:174`), + 而 `adc_health_rail_watch()` 里**任何一拍回到中带就把两侧计数清零**;1 kHz 下一个 50 Hz 周波只有 20 个点、 + 正半周必然落在中带 → 连续贴底最长 ≈ 209°/360° × 20 ≈ **11 拍 < 20** → 永不锁存。 + **这是判据文档与代码的分歧,不是固件缺功能**(更正回写见 §8.10 第 4 条)。 +- **轨带数值**(`App/algo/adc_cal.c:452` 的 `adc_cal_rail_ths()`,TEMP 不监视):STM32 侧贴底 = 码 ≤ **81**(2 % FS ≈ 65 mV)、 + 贴顶 = 码 ≥ 4013;TPAFE 侧 = ±32112 码(≈ ±4.9 V)→ **TPAFE 侧这一条在 ±2 V 判据上限内根本造不出来**, + 只有 STM32 那五路能做。 +- **改法 A(首选,零固件改动)**:发生器切 **DC 输出 −1.00 V** 注 `UB` 端子侧,保持 ≥5 s。期望:`cal:` 的 `rail=0x002`、 + `edge=0x002`、一条 `[ERR] rail: edge=0x2 sticky=0x2 (code-domain, 20-run+release)`(`App/task/adc_task.c:428`)、 + 104 `0x4012` 该路 IV 且值清零、`adc: UB` 码值贴 0。撤掉注入后 **sticky 位不随输入恢复而清**(锁存语义, + 只有 `adc_health_rail_init()` / 复位清)→ 复位一次并把"是否随复位清"记进表:这条实测行为是本轮的产出之一。 +- **改法 B**:发生器 1.000 Vrms 但**频率设 2.0 Hz** → 负半周 250 ms = 250 拍贴底 ≥ 20 → 锁存; + 顺带证"贴轨检测与工频无关"这条口径。 +- **原接法照跑,但判据反过来**:注 50 Hz 正弦这一档仍做,判据是**不锁存属预期**——记录 `adc: UB` 负半周钉 0、 + `rail` 仍 `0x000`,作为 §8.10 第 4 条更正的证据。别把它记成失败。 +- **反向假阳性**:反过来注一个峰值 <65 mV(<46 mVrms)的 50 Hz 小信号,会让 `UB` 一路贴底而**锁存**—— + 那是"信号小到进不了中带",不是削顶。读 `rail` 时要把这条一起排除。 +- **与 `cl` 区分**:`cl=0xE6` 是**来源派生**的静态触底掩码(`docs/任务规划/数据可信.md` §2.6),D5 要的是动态 + `rail=` / `edge=`;别拿 `cl` 当本轮战果。 + +记录表: + +| 步 | 设定 | `rail` | `edge` | `[ERR] rail:` 行数 | 104 `0x4012` | 复位后 `rail` | 结论 | +|---|---|---|---|---|---|---|---| +| 1 | 50.000 Hz / 1.000 Vrms 正弦 | | | | | 不适用 | | +| 2 | DC −1.00 V(改法 A) | | | | | | | +| 3 | 2.0 Hz / 1.000 Vrms(改法 B) | | | | | | | + +#### D6 谐波轨(**用 UI 目检档**) + +| 项 | 内容 | +|---|---| +| 接法 | 发生器 → `IA`(R19 / `AIN8` / U5.B5)端子侧 | +| 设定 | 基波 + 20 % 二次 + 20 % 五次(发生器有谐波叠加 / ARB 模式就用它) | +| ⚠ 峰值预算 | 1.000 Vrms 基波 + 两个 20 % 分量的最坏对齐峰值 ≈ 1.414 + 0.283 + 0.283 = **1.98 V,已顶到 ±2 V 判据上限**。所以基波改 **0.800 Vrms**、二次与五次各 0.160 Vrms,最坏峰值 ≈ 1.58 V 留余量;期望值随之换算 | +| 主读数 | UI 交流量页 `Ia2` / `Ia5` 两行——**3 位小数 = 1 mV**(`Drivers/BSP/UI/ui_page_ac.c:47`),目检 + 拍照;远端可走 7003 看图截屏 | +| 期望与判据 | 期望 ≈ 各分量注入值(0.160 Vrms)±2 % | +| 旁证 | `phasor(hb) C04-IA-F2` / `C05-IA-F5` 的 `rms=`:×0.1 只有 1~2 格,**只能证明这根轨不是恒 0**,判不了 ±2 %(§8.1) | +| 没有谐波叠加功能时 | 分三次单注:只注 0.160 Vrms / 100 Hz → `Ia2` 有数、`Ia5` 应 ≈0;只注 0.160 Vrms / 250 Hz → `Ia5` 有数、`Ia2` 应 ≈0;再注纯基波 → 两行都 ≈0。这一档证的是"两根轨各认各的次",**不证叠加工况**,结论里要写明 | +| 口径 | 这两根轨**目前没有任何下游消费者**(`App/algo/prot_elm.c` 无引用、`meas` 只算基波)→ D6 只证"算得对",不证"有人用";出口归属 `docs/任务规划/数据可信.md` §9 的谐波轨立项 | + +记录表: + +| 注入分量 | 发生器设定 | UI 读数 (V) | 期望 (V) | 偏差 % | `phasor` 旁证 | 结论 | +|---|---|---|---|---|---|---| +| 基波 0.800 Vrms + 二次 0.160 + 五次 0.160 | | `Ia2=` / `Ia5=` | 0.160 / 0.160 | | | | + +### 8.6 顺序与耗时(一次台架 session 跑完) + +| 序 | 做什么 | 预计 | 备注 | +|---|---|---|---| +| 0 | 前置门 + 基线 30 s | 10 min | §8.2,不满足就停 | +| 1 | D1(含 0.5 / 0.2 Vrms 加做) | 15 min | 主用例 | +| 2 | D2(方波 / 三角,峰值对齐) | 15 min | 抬头里记万用表响应类型 | +| 3 | D6(含无谐波叠加功能时的三段退路) | 20 min | UI 目检 + 拍照 | +| 4 | D3 定性档(或整条等段文件) | 10 min | 三个选择见 §8.5 | +| 5 | D4 A 档 | 5 min | 判"如实报不可测" | +| 6 | D5:50 Hz 档 + 改法 A + 改法 B + 复位复观 | 25 min | **单独一份日志**,判读规则见 §8.7 | +| 7 | 同一份接线下把 104 交叉读数复跑一遍 | 15 min | `test/host/iec104_master.py` | +| — | (需用户点头)D4 B 档 / D3 改倍数档 | +40 min | 各含一次重编、烧录与还原 | + +### 8.7 `[ERR]` 的判读规则(D5 单独跑、单独归档) + +- D5 会**故意造出** `[ERR] rail: edge=… sticky=… (code-domain, 20-run+release)`,而 `@test` 的 forbidden 标记含 + `[ERR]`(AGENTS.md「构建与验证」)→ **这一轮不要把 `@test` 的标记校验当结论**:改人工判读,并在归档文件名与 + 抬头里写明「预期 [ERR]:贴轨锁存负向用例」;§8.6 已把它排在最后单独一轮(`docs/任务规划/数据可信.md` §8 风险表第一行同一条)。 +- 除这一条 `[ERR] rail:` 之外,**任何 `[ERR]` 都是不通过**;四个 Fault 的崩溃日志也以 `[ERR]` 开头 → + 出现 Fault 立即停线取现场(`docs/子系统设计/看门狗设计说明.md` §10),别再继续注。 +- 每次开机 `rail:` 边沿只打一条、`SYSLOG` 也只留痕一次("adc code rail fault" 进 `selftest.log`)——这是设计不是漏报; + 要看第二次边沿就复位一次。 + +### 8.8 失败分诊(先查这一列,别急着改固件) + +| 现象 | 先查 | 依据 | +|---|---|---| +| 与万用表差约 2 倍 | 发生器输出端接设成了 50 Ω | §8.2 表第 2 行 | +| 差约 5.3 倍,或数字带 6553.6 / 1241.2 的痕迹 | 拿错刻度,或把 `adc:` 的码值当 mV 读 | §2 两把尺子、§4「码是什么」 | +| `phasor` 行 `rms` 只有 10 格量级 | 正常(×0.1),不是 bug | §4 尾注、§8.1 | +| 非整 50 Hz 时 `meas:` 来回跳 | 预期:瞬时透传、200 ms 不是平均窗 → 改读 `freq(hb)` | `docs/任务规划/数据可信.md` §8 风险表 | +| 104 读数不动 | 每点 0.5 V / 0.005 A 变化死区(生效值 `App/algo/run_par.c`) | §8.5 的 D1 坑 ② | +| 50 Hz 正弦注 `UB` 但 `rail` 不锁存 | **预期**(连续贴底不足 20 拍)→ 改法 A / B | §8.5 的 D5 卡 | +| 改 DC 也不锁存 | 释放沿前提没满足:开机后该通道没出现过中带样本 → 先建基线再注入 | `App/algo/adc_health.c`、§8.2 前置门末条 | +| 撤掉注入后 `rail` 仍非 0 | 锁存语义(sticky),只 `adc_health_rail_init()` / 复位清 → 复位后仍不清**才是** bug | §8.5 的 D5 改法 A | +| 读数带与幅度无关的偏置或漂移 | 共地 / 地环 | §8.2 末行 | +| `meas: seq` 不涨 | 发布闸门停 → 先查采集链,别判交流 | §8.2 前置门 | +| 9 路全 0 | 读作"没数据",不是"输入为零" | §4 尾注 | + +### 8.9 收尾判据(走过临时改动的一条都不许留) + +| 临时改动 | 收尾判据 | +|---|---| +| D4 B 档:`FREQ_AMP_MIN` 50.0f → 0.5f(`App/algo/freq.h:62`) | 还原 + `@build` 0 错误 0 警告 + **`git diff` 里 `App/algo/freq.h` 必须为空** + 在 `docs/任务规划/数据可信.md` §7 #8 那行留一句"本轮台架已还原" | +| D3 改倍数:`log_phasors()` 的 `* 10.0f` → `* 1000.0f`(`App/task/adc_task.c:209`) | 同上,`git diff` 里 `App/task/adc_task.c` 必须为空 | +| 只动接线与发生器、没动代码 | `git status` 除归档目录外干净 | +| 全程 | `test/board/test_config.h` 四个套件宏保持全注释(产品构建);烧录仍须 `-Rst -Run` + 回读校验 | + +### 8.10 归档与回写(跑完必做,缺一算没收尾) + +1. **证据归档** → `docs/测试说明/boot_log_data/`,沿用现有命名惯例(日期_主题_类型.txt): + `20261104_ac_d1_meas_log.txt`、`20261104_ac_d5_rail_log.txt`、`20261104_ac_iec104_log.txt`;UI 目检照片同目录 + (该目录若不收图,就在抬头里写清照片存放位置)。 +2. **实测结论回写** → `docs/硬件平台/ADC通道映射说明.md`,在 §8.1(直流轮次)之后**新开一节**—— + 任务卡 `docs/任务规划/数据可信.md` §5 的 DoD 就是这么分的。本文只留"怎么跑",**不抄实测数**。 +3. **本文回写** → 只在 §8.1 那张表下加一行指针级别的句子("YYYY-MM-DD 已按本节跑通,实测见 …"); + 不在本文建第二份结论表,否则两份必然漂移(`docs/文档规范.md` 同一事实只在一处详述)。 +4. **三处要更正 `docs/任务规划/数据可信.md`**(本轮**没动**那个文件:它正被在飞工作树 `task/wave-record` 修改, + 而 `docs/任务规划/` 是单写者目录;等它合入后一次性改): + - §4.6.2 D2 的三角期望值「峰值 / √6」→ 0.573 ~ 0.578(§8.5 的 D2 卡); + - §4.6.2 D5 的"注 50 Hz 正弦 → 连续 20 拍锁存"按代码做不到,改法 A / B 见 §8.5; + - §4.6.2 D3 / D6 的判据在 ×0.1 定点出口下分辨率不足 → 要么挂到录波段文件,要么在判据里明写"定性档"。 +5. **销项** → `docs/任务规划/数据可信.md` §2.7 与 §6 卡片表里这一条按登记簿「完成即销项」处理,属 Ask first, + 须用户明确指示后再做。 + +### 8.11 这一轮证不到(别让读数长得像证据) + +`docs/任务规划/数据可信.md` §4.6.5 那张五行表整条适用(端子二次值 / 精度等级 / 跨转换器相位与功率与对称分量 / +THD 与谐波方和根 / 温升 EMC 长时间漂移),本节只补一句现状:**样本出口未落地**(录波在飞)→ 本轮所有"波形" +结论都是**标量级**的、不是形状级;要看形状现在只能拿示波器直接看注入点,那只用于确认发生器输出干净与否, +**不进判据**。