Files
STM32F4-Base/docs/测试说明/ADC前端注入验证流程.md
T
wandering1 d64bbdc57f feat(wave): 故障录波数据面、接线与单通道回放页(软件闭环交付)
数据面(App/algo,纯逻辑,双端编译)
- wave_ring:8 路 × 320 点列优先环(1 kHz,预触发 160 + 后触发 160),adcTask
  唯一写者;触发/冻结/封存/冷却四态,冻结持续到落盘回执才解冻,滞留 2 s 自弃
  兜底——下一次真故障无波可录比丢一段更贵
- wave_store:段头编解码 + 拉模式打包游标 + 自带无表位运算 CRC-16/MODBUS(带
  锚点自检)+ 段名与整段长度等式;格式不依赖平台类型宽度
- 段头只存原始码值与封存瞬间生效系数,工程量只当单位标签、不进任何算式
- 三套主机单测(环 113 / 编解码 170 / 触发状态机 110),全部无桩、生产源原样
  纳入;新文件补 stddef 是 ARMCC 与主机差异,主机侧照不出这条分叉
- test/host/wave_read.py 是按 §6.2 的独立第二实现(dump/fft/shape/plot),92 条
  自洽断言;三份合成段互读双校验全过、哈希钉死,格式面双向闭合
- 三套新单测不加专属钩子,由覆盖率总闸全量真跑(沿用既有裁定)

接线(任务层)
- adc_cal:新增生效系数的 32 位定点原值入口(与既有浮点入口共用生效视图),
  段头按最低有效位精确记账,不经浮点回算
- adcTask:每拍压 8 路语义原始码值并推进状态机,封存那一拍同拍交棒封存瞬间事实;
  台架定周期自抓走双层编译门,产品镜像里零存在;串口新增一条 wave: 周期行
- defaultTask:卷空闲后一次心跳整段搬完(try 锁 + 256 字节分片 + 一次完整开档到
  关档),成败都回执;失败先删半成品再计错,段号只在成功时推进;持锁超 50 ms
  补一条告警并记历史峰值(喂狗余量可核)
- Lead 复核补第四道并发陷阱:采集任务优先级高于落盘道,搬段中途它可能正好把滞留
  超时的本段自弃、甚至封出下一段——数据区校验和是对「实际读到的字节」算的,
  半新半旧的段照样自洽,故关档后复检环侧身份判废:删文件、不补账、段号不推进
- Lead 复核抓到触发挂号不是原子操作(旧实现分三个字节写,消费者可在窗口里读到
  上一段的触发源与元件号):已把载荷压进一个字节,越界当场拒且不记任何计数;
  段文件字节布局零改动,三份合成段哈希逐字节不变
- protectTask:保护启动上升沿同点请求录波,一拍一次、元件号取最低位;判据本体
  零改动

人机(160×160 单色屏)
- 菜单树节点 26「手动录波」绑页面 + 记录查询组末新增「录波回放」叶,重跑生成器
  得 43 节点 / 34 叶 / 30 已绑,页面映射 28 → 30
- 回放页一屏一路、触发点前后各一周波共 40 点、每点 3 像素阶梯线(只用水平与
  垂直两种线段——单色屏斜线会被阈值裁掉);零点虚线、触发光标、窗口峰值、
  单位徽标与形状受限徽标;空态与坏段各一句显式文案,绝不用半截波形冒充数据
- ui_data 新增录波注入通道(六件操作表、三态返回);执行侧胶水带段头缓存、
  手动请求后连缓存一起作废、逐点走全仓唯一的码值换算入口
- 模拟器接真实环与编解码合成两段(含坏段与空态旗标),6 张新黄金参考,既有
  60 张逐字节零漂移未用更新模式;字库 218 → 224 字 / 319 字形
- 两份图形配置里图表组件仍为关;零堆分配;页面池水位不变
- 回放读路径的 uiTask 阻塞上界按实码写清:一次渲染 = 段表刷新 + 未缓存段头最坏
  22 次小读;已验段只剩一次开窗读 + 40 点解码;无实测数不编,实测归台架、
  仪器用已在跑的单轮工作耗时探针,不新加埋点

台账与文档
- 内存台账:录波环与落盘/回放静态逐条入册,三档对照 81,536 → 88,296 → 89,936
  字节(62.2% → 68.6%),累计 +8,400;预估 5.9 KB 与实测 +6,760 的差额点名;
  散列文件头注释同步;任务栈表核对后无需抬栈;体积趋势行与同码凭证由权威构建
  重打(0 错误 0 警告,四项体积与上一轮相同——本轮改动只有注释与声明位置)
- 设计说明:§5 补第四条并发陷阱;§6.3 定字段口径(两份独立实现的共同依据);
  §7 回填实测;§9 周期行写实;§10 台架判据改两段式且不比绝对相位;§12 补读路径
  风险行;抬头状态改成「代码面已交付、未做完的只有板级那一轮」
- 卡片:软件闭环一栏列证据;台架三条按用户裁定保持未完成,不做虚假销项
- 口径同步:数据可信、UI 补齐、页面补齐规划、产品需求、采集短板评测、任务规划
  索引与两份 README;陈旧现状句清扫 16 处(带日期戳的历史取数行一律不动)
- 门禁说明:nested-comment 记仓库根探测必须兼容 linked worktree 的 gitdir 文件
  形态(修前该钩子在任务树里恒报环境错、静默不可用);coding-standard 记
  「函数头注释超过 24 行就把函数功能挤出回看窗口」这条机制与本次现场
- 覆盖率基线登记两个新覆盖模块(套件 41 → 44 套);环单测重打后该文件有效行
  227 → 226、覆盖行 226 → 225,比率仍 99.6%,是分母变小不是覆盖率回退

为什么是单一提交:文档链接、双端注册、生成器幂等(菜单与字库)、内存数字与
体积事实源、编号门禁这五道整仓门禁要求代码、页面、菜单树、字库、文档与台账
同处一个提交才自洽,按数据面/接线/人机/台账拆成四笔必然红其中至少四道

编号门禁新增行 14 处命中已按语义改写:魔数常量按字符命名、段名样例改由格式串
生成、频谱表头改 f / 2x / 5x 并加一行图例;改写后自洽断言 92 条仍全过
2026-10-29 19:23:15 +08:00

21 KiB
Raw Blame History

ADC 前端注入验证流程(台架)

这篇是什么:已知电压注入验证的执行侧——判据与实测记录在 docs/硬件平台/ADC通道映射说明.md §8.1, 这边写怎么接表笔、读哪一行日志、填哪张表、结果往哪回写。

本文只验直流:零点 / 线性 / 通道映射 / 极性——它证的是"一条水平线的高度"。 交流(正弦)动态验证不用等标准源:一台信号发生器接在本文 §3 的同一批注入点上就能跑, 判据与接法见 docs/任务规划/数据可信.md §4.6;等标准源的只是精度等级那一步 (docs/任务规划/数据可信.md §5 的「两点标定与精度验收」)。V0.1 有五路单极性削顶 (UB/UC/IB/IC/IN),它们在交流轮次里只能作"预期削顶"的负向用例。

不需要示波器、信号源、标准源。只需要一块万用表 + 一个电位器 + 串口日志。


1. 为什么非做不可

下游已经全部按"工程量"消费:保护判据、104 遥测、UI 交流量页读的都是 adc_cal_apply() 的输出。系数错 一倍,三处一起错,且没有任何一处会报错。"通路活"(9 通道转换成功、零超时、互异非饱和、跨次开机 读数不同)不证明读数对。所以这一步的性质是给整条链路的量纲盖章,不是"补充测试"。

2. 前置事实:这个前端不是分压器

2026-10-27 按 docs/硬件平台/V0.1.tel 逐通道追线,以 UA 为例(图由 tools/arch_diagram/gen_adc_frontend_svg.py 生成,改图请改脚本重跑,勿手改 SVG):

UA 通道前端:端子 → R31 → ADC7 → TPAFE AIN_7P;C44 / R32 在差分负端,不在信号通路上

ADC7 这个节点上只有 R31、C44、U3.61 三样东西,没有对地电阻。所谓"1k 到地"是 R32, 它接在 TPAFE 的负输入脚 AIN_7GND(芯片手册 pin62)上,是把差分负端经 1k 拴到 AGND, 属于差分滤波,不是信号分压。STM32 侧更直接(图 B):AIN2 —[R52 1k]— ADC17 —[C111]— AGND, 同样没有分流电阻,连 R32 那个接地电阻都没有。

由此得到两条可直接用的结论:

  1. 不存在 2:1 分压。旧口径"板级系数 305.18 / 1611.3 µV/码"(按 2:1 折算到 AINn 侧的条件值) 在本板上不成立;docs/任务规划/数据可信.md §2.1 已于 2026-10-27 改为引脚侧系数(152.59 / 805.66)。 所以已知电压注入验证只需确认转换器 LSB 与逐通道映射,不必再判别两种读法。
  2. 端子侧斜率 = 引脚侧斜率。所以在端子侧注入既安全(有 1k 串阻护着芯片)又能直接验 LSB, 不必去碰 LQFP 引脚。

期望斜率(由转换器满量程事实推出,与前端无关):

转换器 满量程 LSB 期望斜率
TPAFE5160 ±5 V(10 V 跨度 / 65536 码) 152.587890625 µV 6553.6 码/V
STM32 ADC1 0~3.3 V(3.3 V / 4096 码) 805.6640625 µV 1241.2 码/V

3. 注入点清单

串联电阻的两只焊盘就是两个注入层级:1 脚 = 端子侧(靠 U5),2 脚 = 引脚侧(靠转换器)。

语义 串阻 端子侧节点 引脚侧节点 转换器脚 期望斜率
UA R31 AIN1(U5.A3) ADC7 U3.61 6553.6
UN R28 AIN4(U5.A4) ADC6 U3.59 6553.6
IA R19 AIN8(U5.B5) ADC3 U3.53 6553.6
UB R52 AIN2(U5.B7) ADC17 U17.44(PC4) 1241.2
UC R20 AIN3(U5.C14) ADC12 U17.37(PA3) 1241.2
IB R49 AIN9(U5.A8) ADC15 U17.42(PA6) 1241.2
IC R46 AIN10(U5.C9) ADC10 U17.35(PA1) 1241.2
IN R48 AIN11(U5.C10) ADC11 U17.36(PA2) 1241.2
温度 R47 V_ZL2(U5.C11) ADC14 U17.41(PA5) 不验(非线性,不参与标定)

引脚侧没有串阻保护,注入前必须外串 10 k 限流。除非端子侧结果对不上、需要分离 "转换器的错"和"前端的错",否则不要用引脚侧。

4. 读数出口(固件只有下面这些周期行,没有命令控制台)

样本出口已落地(代码侧,2026-10-29):故障录波的数据面已进仓(立项与卡片见 docs/任务规划/故障录波.md,格式与判据属主见 docs/子系统设计/故障录波设计说明.md §6.2 与 §6.3、口径变更见该文 §11)——每次触发一段,段文件直接给出 8 路 × 320 点原始码值,动态验证的判据因此可以从「比对下表这些派生标量」升级为「PC 独立重算 vs 板上读数」对表。下表仍是固件唯一的周期行出口(段文件不是周期行,只在触发时产生),两种出口对表用。

日志行 频率 内容 用途
adc: UA=.. UB=.. UC=.. UN=.. IA=.. IB=.. IC=.. IN=.. T=.. 每 10 s 9 路原始码值 本次验证的主读数
cal: ua_mv=.. un_mv=.. ia_mv=.. vl=.. cl=.. 每 10 s UA/UN/IA 折算后毫伏 + 标定/削顶位图 旁证:码值 → 电压是否自洽
first: UA=.. … T=.. 每次开机一次 9 路原始码值 与 adc: 行互校(同序同格式)
frames=.. idle=.. adc1_err=.. tgap=.. 每 10 s 采集健康计数 步骤 4 的节奏判据
phasor(hb) C0x-…: Re=.. Im=.. rms=..(逐实例)、freq(hb): f=.. valid=.. 每 10 s 基波相量分量与测频读数(×0.1 / ×0.01 定点) 交流轮次的主读数(直流轮次只作旁证)
meas: seq=.. v=.. ua_mv=.. un_mv=.. ia_mv=.. f=.. fv=.. 每 10 s 200 ms 遥测快照轨(基波有效值 mV) 交流轮次的幅值比对(1 mV 分辨率,比 phasor 行细)
段文件 /wave/WAVE00.BIN 起共 100 个号轮转(FTP 根下可见,与 /log 平级) 每次触发一段(手动 / 保护启动 / bench 定时) 8 路 × 320 点原始码值 + 封存瞬间的标定与品质快照(布局见 docs/子系统设计/故障录波设计说明.md §6.2) 样本出口:交流轮次的主对表源——预触发 160 点 + 后触发 160 点,触发瞬间落在段内点 159
PC 侧脚本 test/host/wave_read.py(不是固件日志,bench 工具,纯标准库) 手动跑;--selftest 是它的自带回归 四个子命令:dump(逐字段与双 CRC)/ fft(全周傅氏重算基波有效值与相位)/ shape(削顶与形态判定,可 --strict)/ plot(出 SVG 或 PNG,PNG 用 -o 落文件) 把段文件还原成周波数、幅值、相位、削顶判定与图 = 「PC 独立重算」这条判据的执行体;CRC 不符或零长度它必须拒绝而不是画出东西

⚠ 直流轮次用不到后两行,但它们一直都在。交流轮次(判据见 docs/任务规划/数据可信.md §4.6) 必须用 meas: 或 104 YC 比幅值,别用 phasor(hb) 行——那行是 ×0.1 定点,注 1 V 只剩 10 格。

adc: 行是 2026-10-27 新增的(App/task/adc_task.c 心跳块),此前只有 cal: 的三路, 验 8 个通道要复位二十余次。现在全程不必复位。

「码」是什么:ADC 输出的原始整数,中文常写「码值」/「AD 码」,英文对应 raw code / counts。 它表示"多少个最小刻度(LSB)",本身不是物理量——电压 = 码 × LSB,而两片转换器的 LSB 不同:

转换器 位数与极性 码的范围 1 码 = 换算示例
TPAFE5160 16 位双极性 −32768 ~ +32767(共 65536 码 = 10 V 跨度) 152.59 µV 11430 码 × 152.59 µV ≈ 1.744 V
STM32 ADC1 12 位单极性 0 ~ 4095(共 4096 码 = 3.3 V 跨度) 805.66 µV 1000 码 × 805.66 µV ≈ 0.806 V

同一个整数落在两把刻度尺上代表不同电压(图由 tools/arch_diagram/gen_adc_code_scale_svg.py 生成,改图请改脚本重跑,勿手改 SVG):

两把刻度尺:TPAFE5160 16 位双极性 −32768~+32767、1 码 152.59 µV、11430 码≈1.744 V;STM32 ADC1 12 位单极性 0~4095、1 码 805.66 µV、1000 码≈0.806 V

两把尺子不能混用:同样是"1000",在 TPAFE 上是 0.153 V,在 STM32 上是 0.806 V,差 5.3 倍。 所以 §5 各步的记录表里每一格都必须写明是哪一路(UA/UB/… 属 TPAFE,T 属 STM32), 抄错一行全盘结论作废。

本文一律用"码"而不是"伏",有两个理由:① 固件 adc: 行打印的就是码,抄数不用心算; ② 标定还没做,把码换成伏正是本次要验证的事——先换算再用,等于默认了尚未验证的系数。 判据按转换器分两档:TPAFE 侧 ≤ 30 码、STM32 侧 ≤ 5 码——即短接后读数离 0 不超过 30 / 5 个刻度,折算 ≈4.6 mV / ≈4.0 mV。两档数值差 6 倍是因为两种刻度差 5.3 倍 (TPAFE 152.59 µV/码、STM32 805.66 µV/码),统一到物理量后都在 4~5 mV 量级。

⚠ TPAFE 档于 2026-10-27 由 ≤10 放宽到 ≤30:首次实测三路残差 UA −14 / UN −15 / IA −13 (≈2 mV),按 16 位 /10 V 跨度算只有 0.02% FS。原来的 ≤10(≈1.5 mV)定判据时没有实测依据, 比实测噪声还紧,必然误判失败。这不是"把判据改成能过"——若残差继续增大(>30 码 / ≈4.6 mV), 说明前端确有真实失调(R32 侧接地断、TPAFE 失调),那时必须回前端查,不得再放宽。

⚠ adc: 行某路取数失败时该槽打 0,所以"9 路全 0"要读作"没数据",判据是同一份心跳里 frames 是否还在涨。

5. 步骤

5.1 步骤 0:断电核阻(5 分钟)

断电,万用表电阻档量两处,期望值不一样:

量哪里 期望 验的是什么
串阻两端(1 脚 ↔ 2 脚,即端子侧焊盘 ↔ 引脚侧焊盘) ≈ 1 kΩ 串阻焊好、没虚焊
注入点 ↔ AGND(TPAFE 侧,UA/UN/IA) ≈ 1 MΩ 量级 无意外短路;不是 1 kΩ
注入点 ↔ AGND(STM32 侧,UB/UC/IB/IC/IN) 高阻,不定量 无设计直流通路,只作短路排查

5.2 步骤 1:零点(这一步是整套测试的分水岭)

做什么(8 路逐个重复,每路约 1 分钟):

  1. 断电,把该路注入点短接到 AGND(短接线之前先用 0 Ω 档确认该点与 AGND 直通);
  2. 上电,等 adc: 行出现(每 10 s 一行,9 路码值都在里面);
  3. 把该路码值抄进下面的零点记录表;
  4. 断电拆短接线,换下一路。

记录(现场填;判据只看"短接后"那一列,"空载"列是留证用):

⚠ 本表行序 = adc: 日志的列序(UA UB UC UN IA IB IC IN),照着日志从左往右抄, 不要按"TPAFE 三路 / STM32 五路"重新分组。2026-10-27 现场实测就栽在这里:按语义分组抄, 结果 UN/IA 填成了 STM32 的 ~1000、UB/UC 填成了 TPAFE 的 ~11450——而 UN/IA 属 TPAFE、 UB/UC 属 STM32,这两个量级在物理上不可能。"转换器"列就是给这一眼准备的。

通道 转换器 端子侧节点 空载码值(浮空) 短接 AGND 后码值 判据
UA TPAFE AIN1(U5.A3) 11428~11429 1~3 ≤ 30
UB STM32 AIN2(U5.B7) 993~1018 0~1 ≤ 5
UC STM32 AIN3(U5.C14) 975~1033 0 ≤ 5
UN TPAFE AIN4(U5.A4) 11452~11455 2~4 ≤ 30
IA TPAFE AIN8(U5.B5) 11449~11451 2~3 ≤ 30
IB STM32 AIN9(U5.A8) 937~960 2~5 ≤ 5
IC STM32 AIN10(U5.C9) 991~1092 0 ≤ 5
IN STM32 AIN11(U5.C10) 979~1065 1~2 ≤ 5

为什么这一步最关键:空载(输入浮空)读数比判据高两个数量级,最可能的解释是输入悬空后 漏电流在滤波电容上建立的平衡点——短接 AGND 后应塌回 0。但如果短接后仍读 11430,那就是 真实偏置,且超过零点补偿上限 ADC_CAL_B_MAX(8192 码)——adc_cal_set() 会直接拒掉、 回退 ROM 系数、永远置不了 VALID,保护也就永远解不了锁。那种情况必须回前端查 (R32 那侧接地是否断、TPAFE 是否失调),不能靠软件补偿。

2026-10-27 实测结论:8 路全部 PASS。 短接后落在 0~5 码(TPAFE ≤4.6 mV、STM32 ≤4.0 mV), 全部远小于零点补偿上限 ADC_CAL_B_MAX(8192 码),可以正常标定、不会触发回退。 空载 → 短接的塌陷幅度:TPAFE 约 11430 → 04(三个数量级),STM32 约 1000 → 05(两个数量级), 两者都证明短接真实到位、输入前端没有意外直流通路。

⚠ IB 最贴边:25 码,上限 5 码正好触到。折算 1.64.0 mV,物理上没问题,但它是八路里 余量最小的一路;若日后 IB 零点继续变大,第一个该查的是 R49 那侧(AIN9 / U5.A8)。

5.3 步骤 2:三点线性(用 UA 做,免复位)

3.3 V 轨经 10 k 电位器分压作源,逐点注入。每点同时记两个数:万用表读注入点实际电压、 adc: 行读对应码值。

记录(UA 一路,三点;"目标"列是调电位器的靶子,"实测"列填万用表读数):

目标注入 实测电压(万用表) 码值 反算 µV/码 TPAFE 期望码 STM32 期望码
≈ 0.3 V 0.300 1954 153.53 1966 372
≈ 1.0 V 1.001 6547 152.89 6554 1241
≈ 2.0 V 2.004 13106 152.91 13107 2482

拟合 R² = 0.9999997 斜率 = 6544.2 码/V 偏差 = −0.14 % 截距 = −7.2 码(≈ −1.1 mV)

反算 LSB = 152.81 µV/码,与 TPAFE 期望 152.59 差 0.14 %——与斜率偏差同源,是同一个数。

期望码两列并列,是因为同样的三个注入点也可能拿去复验 STM32 侧某一路(UA 对不上时换路交叉验证); 两列数值差 5.3 倍,一眼能确认手上这支表笔当前接的是哪一片转换器。

判据:三点线性拟合 R² ≥ 0.999,斜率与期望值偏差 ≤ 2 %。

偏差 > 2 % 时先查前端(焊点、串阻实际值、电位器负载效应),不要用系数去凑—— 把硬件的错固化成"标定值"是最坏的结果。

2026-10-27 实测结论:PASS。 R² = 0.9999997(判据 ≥0.999)、斜率偏差 −0.14 %(判据 ≤2 %)。 三条残差 −2.0 / +3.5 / −1.4 码,落在读数噪声内,无系统性弯曲——即前端在这三个点上确实是 线性的,不存在未识别的分压元件。这是"③ 段变比 = 1:1"在台架上的第一次直接证据。

5.4 步骤 3:极性(只 TPAFE 三路)

TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,负半周测不了。给 UA/UN/IA 各加一个 −1.0 V 点。

记录(三路各两个点):

通道 +1.0 V 码值 −1.0 V 码值 对称性偏差
UA 6544 −6566 0.34 %
UN 6549 −6568 0.29 %
IA 6548 −6566 0.27 %

判据:−1.0 V 点码值为负且落在 −6554 附近,幅值与 +1.0 V 点对称(差值 ≤ 2 %) → 符号位与补码解释正确。这一步专门补"连极性都没证过"这个缺口。

2026-10-27 实测结论:PASS。 三路 −1.0 V 点全部为负,落在 −6566~−6568(相对 −6554 偏 −0.18 %~−0.21 %);对称性偏差 0.27 %~0.34 %,远小于 2 % 判据。补码符号位解释正确。

5.5 步骤 4:节奏(注入期间顺带看)

注入期间 frames= 应仍严格 1000 Hz 递增(10 s 间隔 +10000 左右),idle=0, adc1_err=0。这一条替代了原方案里"用示波器看 U3.14 BUSY 有脉冲"的判据——不需要示波器。

2026-10-27 实测结论:PASS。 注入前(20:58 那次开机)与注入后(21:29)各取两行相隔 10 s 的心跳,两边都是 Δ9998 码 / ≈10.0 s ≈ 1000.1 Hz,idle=0、adc1_rc=0、adc1_err=0:

时点 frames= 两行 Δ 折算
注入前(20:58) 29997 → 39995 9998 1000.5 Hz
注入后(21:29) 1819639 → 1829637 9998 1000.1 Hz

⚠ 口径说明:这两次是"注入前后",不是"注入进行中"——已知电压注入验证判据 ⑤ 要的正是"注入前后 tpafe5160_frame_seq() 仍严格 1000 Hz 递增",故按此口径已达标。若日后要连"进行中"也钉住, 在任一注入过程里再抓两行即可(注入不改变 TIM3 硬件触发,理论上无影响,但没测过就不算证过)。

adc1_gap / tgap / skip 是本次开机以来的累计值(548 / 363 / 183),10 s 内只增 3 / 2 / 1, 占比约 0.03 %,属正常漏检量级,不是停摆。

5.6 步骤 5:回写

  1. 把实测斜率、零点、映射结果写进 docs/硬件平台/ADC通道映射说明.md §8,把"尚未执行"改成 实测值 + 日期;
  2. 若实测确认无分压,同步在 docs/硬件平台/ADC通道映射说明.md §7.1 的链路分段表把第 ③ 段 (AINn ↔ 转换器引脚)从"待台架实测"改为实测结论;
  3. docs/任务规划/数据可信.md 的已知电压注入验证行按"完成即删"销项;判据与实测证据的属主是 docs/硬件平台/ADC通道映射说明.md §8.1。

6. 判据汇总

项 判据 2026-10-27 实测 结论 不通过意味着
零点 TPAFE 码值绝对值 ≤ 30;STM32 码值绝对值 ≤ 5 8 路全部 0~5 码(≤4.0 mV) PASS 有真实偏置,需查前端;可能超出补偿上限
线性 R² ≥ 0.999 0.9999997(UA 三点) PASS 前端非线性或注入源带载失真
斜率 偏差 ≤ 2 % −0.14 %(6544.2 vs 6553.6 码/V) PASS 前端有未识别元件,或转换器档位/参考错
映射 注入哪路只动哪路 8 路短接各自塌到本路(步骤 1 代偿;串扰未单独证) PASS 语义表与物理通道不符(k_adc_map[] 错)
极性 −1.0 V → −6554 码 −6566 / −6568 / −6566,对称性 ≤0.34 % PASS 补码符号处理错
节奏 注入期间仍 1000 Hz 注入前/后各 Δ9998 / 10 s ≈ 1000 Hz,idle=0、adc1_err=0 PASS 注入改变了输入共模,触发转换异常

总体结论(2026-10-27):六项全部 PASS。合起来证明了三件事: ① ③ 段(AINn ↔ 转换器引脚)变比确为 1:1,无隐藏分压(斜率偏差 −0.14 %); ② 8 路语义 ↔ 物理端子一一对应(零点步骤逐路代偿); ③ TPAFE 补码符号位解释正确(对称性 ≤0.34 %)。 已知电压注入验证的判据 ①②③④⑤⑥ 至此全部闭环(判据与实测记录 → docs/硬件平台/ADC通道映射说明.md §8.1)。

⚠ 两项残留口径(不影响本轮 PASS,但别当成已验证):串扰未单独证(见上表"映射"行); 节奏只测了注入前后、没测注入进行中。两项若日后怀疑,各自的补做方法已写在对应小节。

7. 安全红线

  1. STM32 侧严禁超过 3.3 V(VDDA + 0.3 V 即击穿),电位器上限就接 3.3 V 轨,不要接 5 V。
  2. TPAFE 侧按判据只到 ±2 V,虽芯片容 ±5 V,但判据不需要更大。
  3. 端子侧不许直接上额定电压(220 V / 100 V 二次值)。本次是直流低压注入, 与"加压试保护"是两件事,后者要等端子/子板变比确认(docs/硬件平台/ADC通道映射说明.md §7.1 链路分段表 ④ 行)之后单独排。
  4. 引脚侧注入必须外串 10 k,且先接线后上电、先断电后拆线。
  5. 注入源与板子共地;电位器一端接 3.3 V、一端接 AGND、中间抽头串 10 k 到注入点。