Files
STM32F4-Base/docs/硬件平台/ADC通道映射说明.md
T
wandering1 4c74cfa825 refactor(编号·批次二): 文档侧 194 处保护功能号改成功能名,定义表 7 张首格改语义标识
批次二文档半(道 gate-docs 执行)。先纠三个数的口径账,别再拿任何旧数当准:**234 处是准数** —— 卡片写
52(Lead 用了门禁 Checker 的引用集合,它**刻意排除属主文档内部的定义位**)、道里先报 265(裸正则把
`SDL2-2.32.10` 里的 `L2-2` 当成功能号,误报 10 处)。最终边界口径 = 带左边界 + 跳过反引号代码段。

· 19 只文件 HEAD 共 234 处 → 现 40 处,**40 处 100% 落在变更记录行**(冻结历史,按 Q3 一条没动),
  非变更记录残留 **0**;改写 163 行 / 16 只文档。站点最多:规划文档 110→37、相量层单测说明 25→1、
  采集与数据处理短板评测 21→0、App/algo/README 26→0。
  (`App/algo/README.md` 由上一笔代码提交带上车,路径归属已在该笔正文注明,内容是本批改写)
· **定义表首列由编号改成语义标识**(编号规范 §3.3「表首格就是短语」的完全形态):首列原为编号的表
  共 **7 张**(不是 5 张),删掉与之重复的「语义名」列;表头标签按域词区分——三张 L3 保护**元件**表
  保留 `| 元件 |`,四张 L1/L2 表用 `| 功能名 |`(把「元件」统一洗成功能名会丢掉领域信息)。
  七张表逐张核:表头竖线数 == 分隔行 == 首条数据行 == 列数+1;与 HEAD 逐块对拍**净新增不一致块 0**,
  并且正是这个对拍抓到第一版「三张表数据行已删列、表头没删」的破表。
· 7 处删号留下的残词/重复解释括号人工收口(如「L1-5(通道标定)」→「通道标定(一次系数 + 零漂)」),
  复扫待收口站点 0;措辞逐字取自映射表,无第二种说法。
· tools/arch_diagram 三只生成器 4 处(3 处 docstring + 1 处图形文案)与产物同批:重跑后**只有位图那张
  变 2 个 text 节点的换行位置**,画布 1580x740 与总行数不变,另两张逐字节未变;改前先干跑对照证明三张
  svg 原本与生成器一致(不在 stale 基线里)——`check_generated_fresh --only docs-svg` PASS。

本笔另含 **F-* 半批的文档面**(同一轮 `git add docs tools/arch_diagram AGENTS.md` 一并收进
,非误伤):BSD
函数调用关系里 9 处反引号紧邻指针、属主文档 §7 的停发句与导读行(**12 条定义行原样保留、不删登记族**)、
以及 `gen_net_instability_svg.py` 与它的产物 `网络不稳根因总览.svg`(「唯一读者红线」那条的框宽自适应
526 → 551,右缘 1411 未越界,画布 1560x1468 不变)——该半批的**代码注释面**在下一笔。

⚠ 因 `docs/任务规划/登记簿.md` 与 `docs/任务规划/UI补齐.md` 正被另一张卡(UI 叶数复核)改动,本笔**不含
那两只文件**,批次二的 §9 存量收尾与它们同批提交。
2026-10-27 09:05:24 +08:00

194 lines
28 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.
# V0.1 ADC 通道映射表(权威口径)
> **一句话结论**:V0.1 共 **17 路**模拟采样——**8 路进 TPAFE5160**(16 位、8 通道同步、**±5 V 满量程 = 10 V 跨度**、LSB ≈ 152.59 µV,板上 RANGE 接 GND,口径见 §7.1)、**9 路进 STM32 内部 ADC**(12 位、顺序采样、0~3.3 V 单极性)。网名 `AINn`、板级网名 `ADCn`、转换器通道号**三套编号互不等价**(V0.1 有 13/17 路被置换),任何代码 / UI 显示 / 自检注入**必须以本表为准,不得假设 `AINn = ADCn`**。
>
> 语义分配由硬件于 **2026-10-09** 确认;网名与电阻对应关系取自 [`V0.1.tel`](V0.1.tel)(第 227~262 行),引脚号取自数据手册 LQFP144 引脚表([`../芯片手册/stm32f405rg.md`](../芯片手册/stm32f405rg.md))。
---
## 1. 语义分配(2026-10-09 硬件确认)
| 语义 | 网名 | 类别 | 说明 |
|---|---|---|---|
| **UA** | AIN1 | 电压 | A 相电压 |
| **UB** | AIN2 | 电压 | B 相电压 |
| **UC** | AIN3 | 电压 | C 相电压 |
| **UN** | AIN4 | 电压 | 零线(中性线)电压 |
| **IA** | AIN8 | 电流 | A 相电流 |
| **IB** | AIN9 | 电流 | B 相电流 |
| **IC** | AIN10 | 电流 | C 相电流 |
| **IN** | AIN11 | 电流 | 零线电流 |
| **温度** | V_ZL2 | 温度 | 温度检测模拟采样 |
| 备用 | AIN5 / AIN6 / AIN7 / AIN12 / AIN13 / AIN14 / AIN15 / V_ZL1 | — | **未使用**(悬空或不用),软件侧一律标 `RESERVED`,不参与采集与上报 |
**设计口径(重要,2026-10-10 更正)**:本产品的**电能计量在子板(计量模块)完成**,主板 ADC 只做**监视 / 辅助测量**。但**"8 路电气量被分到两片转换器上"(UA/UN/IA 走 TPAFE5160,UB/UC/IB/IC/IN 走 STM32 12 位 ADC)是 V0.1 的硬件缺陷**——建档时(2026-10-09)写的"有意分配、不要按'8 路电气量应全部走 TPAFE'去修正"**说法作废**:该分配**就是需要修正的对象**,已列入下一版硬件(V0.2)改版项(登记簿 **N-18**)。
**缺陷实质(为什么必须改)**:
1. **跨转换器通道没有同一时刻性**:TPAFE5160 是 8 通道**同步**采样,STM32 ADC 是**顺序**扫描(9 通道一轮 ≈ 67 µs),且两片转换器**没有共同采样触发**(CONVST 只打 TPAFE,ADC1 为软件触发)。于是 UA↔UB、IA↔IB 这类同族量之间**相位关系不确定**,主板侧任何功率 / 功率因数 / 相角 / 对称分量类运算都不成立。
2. **精度与量程不一致**:TPAFE 16 位 ±5 V **双极性**(LSB ≈ 152.6 µV,满量程 = 10 V 跨度,口径见 §7.1)vs STM32 12 位 0~3.3 V **单极性**(前端无中点偏置,交流量负半周削顶;LSB ≈ 806 µV)。同为相电压,UA 与 UB/UC 满量程码值差 16 倍、可用象限也不同——同一套算法无法统一处理 8 路电气量。
3. **语义与硬件归属交叉**:UA 在 TPAFE、UB 在 STM32,固件映射表 / UI 通道序 / 自检注入都必须逐通道查表绕开这个交叉(本文件 §4、§5 两张表的存在本身就是代价)。
**下一版硬件(V0.2)改版要求**:**8 路电气量 UA/UB/UC/UN/IA/IB/IC/IN 全部接到 TPAFE5160 的 8 个通道**,备用路与温度(V_ZL2)留给 STM32 ADC。TPAFE 现被 5 条备用路占着(`AIN5`/`AIN13`/`AIN7`/`AIN15`/`AIN12` → ADC1/ADC2/ADC4/ADC5/ADC8),与要迁过来的 5 路(UB/UC/IB/IC/IN)**正好 5 换 5**:只需把这 5 路串联电阻在转换器一侧的目的地对调,**元件数量与料号不变,属走线级改动**。改版后本表 §3 的"转换器 / 代码通道"两列须按 V0.2 网表重出——这也是消费侧**必须按语义取数、不得写死下标**的原因。
**V0.1 现板的软件口径**:主板侧只做**逐通道独立监视**(有效值 / 越限 / 温度),**禁止**做跨转换器的同周期相位、功率、功率因数、矢量类运算;确需此类量,取子板计量模块的结果。
---
## 2. 三套编号,别混
| 编号族 | 含义 | 出现位置 |
|---|---|---|
| `AINn`(n=1~15)、`V_ZL1/2` | **子板侧网名**:语义挂在这一层(UA/UB/…/温度) | 连接器 U5 各脚 → 串联电阻 |
| `ADCn`(n=1~17) | **主板 ADC 输入网名**:电阻另一侧、滤波电容、转换器输入脚 | 电阻 → 滤波器 → U3 / U17 |
| 转换器通道号 | 软件真正要用的编号:TPAFE `ch1~ch8`(= 驱动 `buf[0..7]`)/ STM32 `ADC_CHANNEL_x` | 固件、UI、自检 |
V0.1 相对 V0.0 把 `AINn ↔ ADCn` 的电阻对应关系置换了 13 路(见 [`V0.1_网表详细分析报告.md`](V0.1_网表详细分析报告.md) §6),所以**网名编号完全不能当通道号用**(例:`AIN1`(UA) 实际落在 TPAFE 第 7 通道)。
---
## 3. 完整映射表(17 路)
TPAFE5160(U3)通道脚:`AIN_1P`=49 / `AIN_2P`=51 / `AIN_3P`=53 / `AIN_4P`=55 / `AIN_5P`=57 / `AIN_6P`=59 / `AIN_7P`=61 / `AIN_8P`=63。
STM32(U17)为 LQFP144 脚号。
| 语义 | 网名 | U5 脚 | 串联电阻 | 板级网名 | 转换器 | 转换器脚 / MCU 脚 | **代码通道** | 状态 |
|---|---|---|---|---|---|---|---|---|
| **UA** | AIN1 | A3 | R31 | ADC7 | TPAFE5160 | U3.61 = `AIN_7P` | `buf[6]`(ch7) | 在用 |
| **UB** | AIN2 | B7 | R52 | ADC17 | STM32 ADC123 | U17.44 = **PC4** | `ADC_CHANNEL_14` | 在用 |
| **UC** | AIN3 | C14 | R20 | ADC12 | STM32 ADC123 | U17.37 = PA3 | `ADC_CHANNEL_3` | 在用 |
| **UN** | AIN4 | A4 | R28 | ADC6 | TPAFE5160 | U3.59 = `AIN_6P` | `buf[5]`(ch6) | 在用 |
| 备用 | AIN5 | B6 | R12 | ADC1 | TPAFE5160 | U3.49 = `AIN_1P` | `buf[0]`(ch1) | RESERVED |
| 备用 | AIN6 | C13 | R5 | ADC9 | STM32 ADC123 | U17.34 = PA0 | `ADC_CHANNEL_0` | RESERVED |
| 备用 | AIN7 | A5 | R23 | ADC4 | TPAFE5160 | U3.55 = `AIN_4P` | `buf[3]`(ch4) | RESERVED |
| **IA** | AIN8 | B5 | R19 | ADC3 | TPAFE5160 | U3.53 = `AIN_3P` | `buf[2]`(ch3) | 在用 |
| **IB** | AIN9 | A8 | R49 | ADC15 | STM32 ADC123 | U17.42 = PA6 | `ADC_CHANNEL_6` | 在用 |
| **IC** | AIN10 | C9 | R46 | ADC10 | STM32 ADC123 | U17.35 = PA1 | `ADC_CHANNEL_1` | 在用 |
| **IN** | AIN11 | C10 | R48 | ADC11 | STM32 ADC123 | U17.36 = PA2 | `ADC_CHANNEL_2` | 在用 |
| 备用 | AIN12 | B3 | R13 | ADC8 | TPAFE5160 | U3.63 = `AIN_8P` | `buf[7]`(ch8) | RESERVED |
| 备用 | AIN13 | A6 | R17 | ADC2 | TPAFE5160 | U3.51 = `AIN_2P` | `buf[1]`(ch2) | RESERVED |
| 备用 | AIN14 | C12 | R45 | ADC13 | STM32 ADC123 | U17.40 = PA4 | `ADC_CHANNEL_4` | RESERVED |
| 备用 | AIN15 | B4 | R26 | ADC5 | TPAFE5160 | U3.57 = `AIN_5P` | `buf[4]`(ch5) | RESERVED |
| 备用 | V_ZL1 | A7 | R51 | ADC16 | STM32 ADC123 | U17.43 = PA7 | `ADC_CHANNEL_7` | RESERVED |
| **温度** | V_ZL2 | C11 | R47 | ADC14 | STM32 ADC123 | U17.41 = PA5 | `ADC_CHANNEL_5` | 在用 |
**汇总**:TPAFE 8 路 = AIN5/13/**8**/7/15/**4**/**1**/12;STM32 9 路 = AIN6/**10**/**11**/3/14/**9**/**2**/V_ZL1/**V_ZL2**(粗体为在用通道)。
---
## 4. TPAFE 侧:读出顺序 → 驱动缓冲区下标
`tpafe5160_read_all()` / EXTI 自动读取按 RD 时序连续读 8 次,`FRSTDATA` 标记第一通道,故 **`buf[0..7]` = `ADC1..ADC8` 网名 = TPAFE `ch1..ch8`**:
| `buf[i]` | 板级网名 | TPAFE 通道 | 语义 |
|---|---|---|---|
| 0 | ADC1 | ch1 | RESERVED(AIN5) |
| 1 | ADC2 | ch2 | RESERVED(AIN13) |
| **2** | ADC3 | ch3 | **IA** |
| 3 | ADC4 | ch4 | RESERVED(AIN7) |
| 4 | ADC5 | ch5 | RESERVED(AIN15) |
| **5** | ADC6 | ch6 | **UN** |
| **6** | ADC7 | ch7 | **UA** |
| 7 | ADC8 | ch8 | RESERVED(AIN12) |
> 消费侧**必须经语义映射表取数**(`UA → buf[6]`),不要按"buf[0]=UA"这类直觉下标写代码。
---
## 5. STM32 侧:网名 → 引脚 → 代码通道宏
| 板级网名 | U17 脚 | 引脚 | **代码宏** | 语义 |
|---|---|---|---|---|
| ADC9 | 34 | PA0 | `ADC_CHANNEL_0` | RESERVED(AIN6) |
| ADC10 | 35 | PA1 | `ADC_CHANNEL_1` | **IC** |
| ADC11 | 36 | PA2 | `ADC_CHANNEL_2` | **IN** |
| ADC12 | 37 | PA3 | `ADC_CHANNEL_3` | **UC** |
| ADC13 | 40 | PA4 | `ADC_CHANNEL_4` | RESERVED(AIN14) |
| ADC14 | 41 | PA5 | `ADC_CHANNEL_5` | **温度(V_ZL2)** |
| ADC15 | 42 | PA6 | `ADC_CHANNEL_6` | **IB** |
| ADC16 | 43 | PA7 | `ADC_CHANNEL_7` | RESERVED(V_ZL1) |
| **ADC17** | **44** | **PC4** | **`ADC_CHANNEL_14`** | **UB** |
> ⚠️ **`ADC17` 网名 ≠ `ADC_CHANNEL_17`**。PC4 在 F407 上是 `ADC123_IN14`,代码必须写 `ADC_CHANNEL_14`;`ADC_CHANNEL_12` 是 **PC2(pin 30)**,写错就读到另一只脚。
**CubeMX 侧标签(2026-10-09 已写入 `STM32F407-Demo.ioc` 并生成代码,格式 `板级网名_语义`)**:`ADC9_RES` / `ADC10_IC` / `ADC11_IN` / `ADC12_UC` / `ADC13_RES` / `ADC14_TEMP` / `ADC15_IB` / `ADC16_RES` / `ADC17_UB`(9 脚已配到 ADC1 的 IN0..IN7 + IN14,生成代码里对应 `main.h` 的 `ADC9_RES_Pin`…`ADC17_UB_Pin`)。⚠ PA0 标签首次配置时误写成 `AD9_RES`(少个 C),已改回 `ADC9_RES`(`.ioc` + `Inc/main.h` + `Src/adc.c` 三处同步)。
**引脚可用性核查(2026-10-09)**:`STM32F407-Demo.ioc` 中 PA0~PA7、PC4 **此前均未分配**(PC5 = LED1,与 ADC 无关)→ 这 9 路做模拟输入无冲突,现已配给 ADC1。PA4/PA5 兼 `DAC_OUT1/2`,作模拟输入期间须保持 DAC 关闭(当前固件未启用 DAC ✓);PA4/PA5/PA6/PA7 的 SPI1 复用未使用(SPI1 走 PB3/PB4/PB5)✓。
---
## 6. 对既有文档的勘误(2026-10-09,依据 DS8626 引脚表)
1. **PC4 的通道号**:`docs/硬件平台/V0.1_网表详细分析报告.md` §4.6 / §9-3 / §11 与 `docs/硬件平台/V0.0_网表详细分析报告.md` B5 处写的 "PC4 = `ADC12_IN12`、代码用 `ADC_CHANNEL_12`" **有误**——DS8626 引脚表:PC4 = LQFP144 pin 44,附加功能 **`ADC12_IN14`**;`ADC_CHANNEL_12` 对应 **PC2(pin 30)**。正确写法:**`ADC_CHANNEL_14`**。
2. **"PB0 非 ADC 输入脚" 不成立**:PB0 = LQFP144 pin 46 = **`ADC12_IN8`**(PB1 = pin 47 = `ADC12_IN9`)。所以 V0.0 把 `ADC17` 接 pin 46(PB0)**电气上是有效通道**,并非"死通道"。V0.1 改到 pin 44(PC4)的**实际收益是解除与 LED2(PB0)的复用**,不是"救活无效通道"——V0.0 报告 B5 的定性需按此理解。
---
## 7. 实现注意事项(当前固件现状,2026-10-10)
| 项 | 现状 | 影响 |
|---|---|---|
| **通道归属(硬件缺陷)** | 8 路电气量分属两片转换器:UA/UN/IA → TPAFE,UB/UC/IB/IC/IN → STM32 ADC | **V0.1 硬件缺陷**(非有意分配,理由见 §1)→ V0.1 上禁止跨转换器做相位/功率/功率因数/矢量类运算;**V0.2 改版要求 8 路电气量全部走 TPAFE**(登记簿 N-18) |
| STM32 ADC 外设 | **已生成(2026-10-09,CubeMX 6.17 + FW_F4)**:`Src/adc.c`/`Inc/adc.h` 已入库并挂进 `MDK-ARM/*.uvprojx`;`Inc/stm32f4xx_hal_conf.h` 的 `HAL_ADC_MODULE_ENABLED` 已生效;HAL `stm32f4xx_hal_adc.c/_ex.c` + `stm32f4xx_ll_adc.h` 已补入仓库(HAL 原本是裁剪子集);`Src/main.c` 里 `MX_ADC1_Init()` 排在 `MX_IWDG_Init()` 之后。生成配置核对无误:9 通道 / Rank 1~9 / 全部 144 cycles / `ScanConvMode=ENABLE` / `ContinuousConvMode=DISABLE` / `ExternalTrigConv=ADC_SOFTWARE_START` + `EDGE_NONE` / `EOCSelection=ADC_EOC_SINGLE_CONV` / `DataAlign=RIGHT` / 12 位;`HAL_ADC_MspInit()` 已把 PA0~PA7+PC4 配成 `GPIO_MODE_ANALOG` | 硬件通路已打通(`hadc1` 可用);**消费者已落地**——`App/algo/adc_input.c` 的 `stm32_take()`(「STM32 ADC1 启动与扫描」,v2.0,2026-10-10):ADC1 由 **TIM3 TRGO 硬件触发**一轮 9 通道 + **DMA2_Stream4 循环搬运**进乒乓双缓冲,任务侧只消费刚完成的半区(零忙等),9 通道一轮 ≈ 67 µs |
| ADC1 上电自校准 | **已补(2026-10-10)**:`Src/adc.c` 的 `USER CODE BEGIN ADC1_Init 2` 调用 `adc1_calibrate()`(实现同文件 `USER CODE BEGIN 1`,按 RM0090 §13.3.6:清 ADON→等生效→置 ADON→置 CAL→等 CAL 由硬件清零)。⚠ **CubeMX 不生成这一步**,且本仓库裁剪版 HAL **没有** `HAL_ADCEx_Calibration_Start`、裁剪版 CMSIS 头**没有** `ADC_CR2_CAL`(bit3,代码里按 RM 自建 `ADC1_CAL_BIT`)→ 属 L2 手工定制,审计项 `adc1-calibration-call` / `adc1-calibration-impl` 兜底 | 实测有效:校准前后同一拍 STM32 侧 6 路**同向**变化 `UB 898→961`、`UC 978→1038`、`IB 906→922`、`IC 1061→1071`、`IN 1017→1055`、`T 790→846`(+10~+63 LSB ≈ 0.2~1.5 % FS);TPAFE 侧 `UA/UN/IA` 一字不变 → 变化确来自 ADC1 校准。缺这一步不报错,只是**读数带失调** |
| ADC 时钟 | CubeMX 的 F4 ADC 面板**有** Clock Prescaler 一项(此前"面板没有该项、固定 DIV2"的判断有误),已选 **PCLK2/4 → ADCCLK = 21 MHz** ✓。面板里 **DIV2 是灰的、选不到**:DB 里 `FadcConstraint Max=36000000`,APB2 = 84 MHz → DIV2 = 42 MHz 超限,该候选值被 `Action="DISABLE"` 禁掉,超规值进不来 | **不设额外防护(2026-10-09 决定)**:约束已由 CubeMX 把关;`.ioc` 虽不保存 `ADC1.ClockPrescaler` 键,重生成也只会回落到约束允许的值。按 144+12 cycles 算 ≈ 7.4 µs/通道、9 通道一轮 ≈ 67 µs |
| `adc_task` | **已实现(B1,2026-10-10;L1 层 v2.3;P1-5 事件驱动消费,2026-10-10)**:`App/task/adc_task.c` 每拍调 `adc_input_poll()`(`App/algo/adc_input.c`)= TPAFE `tpafe5160_snapshot()` 原子快照(8 通道)+ 消费一帧 STM32 ADC1 DMA 乒乓缓冲,**经 `adc_input_raw()` 按语义取数**(不再直接索引驱动缓冲);**消费唤醒由 TIM3 ISR 置位 `ADC_WAKE_FLAG`**(不再 1 ms 轮询);任务在 `Src/freertos.c` 的 `USER CODE` 区创建为 `adcTask`(512 words / **AboveNormal**) | 数据路径已通(台架 `@test`:`frames` 严格 1000 Hz 递增、**`idle=0`**、`adc1_rc=0` / `adc1_err=0`) |
| TPAFE 采样触发 | **周期 CONVST 已实现(2026-10-10)**:`Src/main.c` 的 `HAL_TIM_PeriodElapsedCallback` 在 **TIM3 更新事件(1 kHz)** 内调 `tpafe5160_start_conv_irq()`;`app_main_init()` 用 `HAL_TIM_Base_Start_IT(&htim3)` 启动节拍(在 `tpafe5160_init()` 之后)。同一 TIM3 更新事件还经 **TRGO** 硬件触发 ADC1 一轮 9 通道(DMA 搬运),并调 `adc_tick_irq_notify()` **唤醒消费者**(P1-5 方案 a,2026-10-10;内含"消费者就绪"门)→ 两片转换器由同一硬件事件同源对齐 | 连续波形(1 kHz);详见 `docs/子系统设计/ADC采样节拍设计说明.md` §4(DMA 乒乓搬运)与 §6(事件驱动唤醒) |
| 前端偏置 | 每路 1k 串联 + 1k 到 `*_GND` + 滤波 C,**无中点偏置** | STM32 侧只能测 **0~3.3 V 单极性**,交流量负半周被削顶;主板侧只做监视可接受,若要算 RMS/功率需硬件补偏置或明确算法口径 |
| TPAFE 量程(**2026-10-25 卡 1 定死**) | 板上 RANGE 接 GND → **±5 V 双极性量程**(芯片手册输入量程表:RANGE = 0 → −5 ~ +5 V),16 位二进制补码,**±5 V 满量程 = 10 V 跨度**,LSB = 10 V / 65536 ≈ **152.59 µV/码(@ 转换器引脚)**。“±10 V” 是芯片的另一可选档(RANGE = HIGH,跨度 20 V、LSB ≈ 305.18 µV),**本板未用**——历史版本曾把本板误标为“±10 V 双极性”,与 §7 本行矛盾、且会让 TPAFE 侧系数差一倍,更正记录见 §9 | 用 `tpafe5160_to_voltage()` 换算;端到端口径见 §7.1 |
| 取数契约(**2026-10-10 已修**,E-44 / E-45 / E-58 闭环) | 旧的 `get_buf` / `data_ready` / `clear_ready` **已删除**(删除前确认全仓库零调用者):`get_buf` 只给指针、任务再拷 → 被 BUSY EXTI 抢占就是**两帧混合**;`s_ready` 电平标志被 `start_conv_irq` 触发前清 0 → **重触发即丢未消费帧**;`read_all` 从不看 FRSTDATA(宏有定义、代码零引用)→ 芯片死亡时返回 OK + 常量垃圾。现口径:**`tpafe5160_snapshot(dst, count)`**(临界区原子拷贝,返回 1/0/-1,**仅任务上下文**)+ **`tpafe5160_frame_seq()`**(帧序号只增不清)+ **`tpafe5160_frstdata_err()`**(无跳变帧计数);`tpafe5160_init()` 增**首帧自检**——一帧读下来 FRSTDATA 无跳变(芯片不驱动并行总线;板上 R24 4.7k 上拉会把它钉死为高)→ 返回 `-3` + `[ERR]` | 消费者**只能**用 `snapshot()` 取数(`AGENTS.md` 已立为铁律);真机实测开机 `[ADC] Init OK` 现只在自检帧通过后才打印 → 判据在本板成立、非空转 |
### 7.1 端到端量纲链路口径(网名 AINn → 端子 → 变比 → 码值 → 满量程,2026-10-25 卡 1 定死)
> 出处:`docs/任务规划/数据可信.md` 卡 1。本节把 **语义端子(二次侧)→ 子板/端子板 → 网名 `AINn` → 主板电阻网络 → 板级网名 `ADCn` → 转换器引脚 → 码值 → 满量程** 的链路**逐段**定口径;
> 待实测段只给**口径与判据**,不填任何实测数值(本轮按用户指示跳过台架,标注“待台架实测”)。
**芯片级口径(定死,与前端网络无关)**:
| 项 | 口径 | 依据 |
|---|---|---|
| TPAFE5160 量程档 | 板上 RANGE(U3 pin8)接 GND → **±5 V 双极性**(−5 ~ +5 V);RANGE = HIGH 的 ±10 V 档本板未用 | [`V0.0_网表详细分析报告.md`](V0.0_网表详细分析报告.md) §4.5“模式配置全对:RANGE(pin8)=GND → ±5V” + [`../芯片手册/TPAFE5160.md`](../芯片手册/TPAFE5160.md) 输入量程表(RANGE = 0 → −5 ~ +5;RANGE = 1 → −10 ~ +10) |
| TPAFE 码值格式 | 16 位二进制补码(−32768 ~ +32767,全量程 65536 码 = 10 V 跨度) | 芯片手册 DC Accuracy(16 bit / NO missing code);`Drivers/BSP/TPAFE5160/tpafe5160.c` 的 `tpafe5160_to_voltage()` 注释 |
| TPAFE LSB(@ 引脚) | 10 V / 65536 ≈ **152.59 µV/码**(≈6553 码/V) | 由上两行推得;与 §7“TPAFE 量程”行、驱动注释一致 |
| STM32 ADC1 LSB(@ 引脚) | 12 位单极性 0 ~ 3.3 V:3.3 V / 4096 ≈ **805.66 µV/码**(≈1241 码/V) | §7 生成配置行;`docs/任务规划/数据可信.md` §2.1 同口径 |
“±10 V”只允许出现在“芯片可选档”语境。本文件 2026-10-09 建档时曾把文首摘要写成“TPAFE … ±10 V 双极性”,与 §7 的 ±5 V 档矛盾、**TPAFE 侧系数因此会差一倍**——2026-10-23 `docs/任务规划/数据可信.md` §2.1 挂账该冲突并要求卡 1 定死;现**定死为“±5 V 满量程 = 10 V 跨度、LSB 152.59 µV”**,文首摘要与 §7 已按此更正。全仓其余“±10 V”字样仅剩芯片手册转写与 `tpafe5160.h` 中 RANGE 枚举可选档注释(均为芯片能力描述,非本板配置口径),不构成歧义。
**链路分段口径**:
| 段 | 关系 | 状态 |
|---|---|---|
| ① 语义 ↔ 网名 ↔ 板级网名 ↔ 转换器代码通道 | §2/§3/§4/§5 的 17 路映射表 | **定死**(本文件为唯一权威) |
| ② 转换器引脚电压 ↔ 码值 | TPAFE `U_pin = code × 152.59 µV`(code 带符号);STM32 `U_pin = code × 805.66 µV` | **定死**(纯转换器事实,上表) |
| ③ `AINn`(串联电阻子板侧)↔ `ADCn`/转换器引脚 | 每路 1k 串联 + 1k 到 `*_GND` + 滤波 C(§7“前端偏置”行)。两种读法并存:**A** 按 2:1 电阻分压折算到 `AINn` 侧 → 系数 305.18(TPAFE)/ 1611.3(STM32)µV/码;**B** [`V0.0_网表详细分析报告.md`](V0.0_网表详细分析报告.md) §4.7 定性“源阻抗匹配(手册推荐做法,非分压)”→ 两侧系数相同 | **待台架实测**——`docs/任务规划/数据可信.md` 卡 0 注入斜率判别:引脚侧注入验 ②(期望 ≈6553 码/V),`AINn`/端子侧注入的斜率即 ③(或 ③+④)的合成变比。本卡不裁决 A/B |
| ④ 语义端子(二次端子)↔ `AINn` | 子板/端子板变比:仓库内**无任何文档**(`docs/硬件平台/` 只有 `.tel` 网表与分析报告,无子板原理图;§8 步骤 4) | **缺口**——卡 0b 实测确认;拿不到变比则“端子二次值”不成立、`eng` 保持 0 |
**可评审结论**:
1. **ROM 默认系数按 ② 引脚口径冻结**:TPAFE 通道 `k = 152.59 µV/码`、STM32 通道 `k = 805.66 µV/码`;标定折算的输出单位 = **ADC 引脚电压 V**(`eng = 0`)。该口径**不依赖** ③④ 两个未决项,自本卡定死即成立——这就是 M4 承诺边界止于“引脚电压”的依据(`docs/任务规划/数据可信.md` §2.6)。
2. `docs/任务规划/数据可信.md` §2.1 表中“板级系数(输入侧)305.18 / 1611.3 µV/码”是**按 ③ 读法 A(2:1 分压)折算到 `AINn` 侧**的条件值,而同一网络已被 V0.0 §4.7 定性为非分压(读法 B)。卡 0 判别 A/B 之前,305.18 / 1611.3 **不得**进任何代码或换算;引脚侧一律用 152.59 / 805.66。
3. **满量程必须写明参考点**:TPAFE 通道满量程 = ±5 V **@ 引脚**(跨度 10 V);③④ 定死前,端子侧满量程只允许写“引脚侧数值 × ③ 比 × ④ 比”,两个比值当前均未知,**严禁**把“端子电压 = 码 × 305.18 µV”写进代码/文档当作已成立结论。
4. **待台架实测占位(本轮按用户指示跳过)**:卡 0(三点注入:线性 R² ≥ 0.999、斜率、零点、逐通道映射确认)、卡 0b(端子→引脚变比)、卡 12(两点标定)完成后,回写本节 ③④ 两行与 §8。实测斜率与 ② 理论值偏差 >2 % 时**先查前端**(分压/变比/焊接),不得用系数凑错斜率(`docs/任务规划/数据可信.md` §8 风险表)。
---
## 8. 逐通道验证方法(上板自检口径)
1. **TPAFE 侧**:对目标 `AIN` 注入 1 V DC → 观察对应 `buf[i]` 变化(UA→`buf[6]`、UN→`buf[5]`、IA→`buf[2]`),同时 U3.14 `BUSY` 有脉冲;**语义与下标不符即映射错**。⚠ **本步无执行记录**(2026-10-23 核查;`V0.0_网表详细分析报告.md` §5.1 第 6 条的同一验证也从未执行)。已排入 `docs/任务规划/数据可信.md` 卡 0,并把两条判据降为**不需要示波器**的口径:① "`BUSY` 有脉冲"改用固件帧计数——注入前后 `tpafe5160_frame_seq()` 仍严格 1000 Hz 递增即等价;② 幅值判据改用万用表读注入点实际电压 + 同时读 `adc_input_raw()` 码值,三点线性拟合(R² ≥ 0.999)。
2. **STM32 侧**:对目标引脚(如 PC4=UB)注入 0.5 V → 读 `ADC_CHANNEL_14` 应变化;若不变而相邻通道变化 → 通道宏写错(见 §5 警告)。⚠ **本步尚未执行**(2026-10-10 「STM32 ADC1 启动与扫描」台架只验证了"9 通道全部转换成功 + 零超时 + 互异非饱和 + 跨次开机读数不同",台架无信号源);映射的**代码侧**一致性有两道保证:① `App/algo/adc_input.c` 的 `k_adc_map[]` 与 CubeMX 标签(`ADC17_UB`=PC4 等)逐条对齐;② 开机自检 `adc_input_init()` 校验每个 STM32 语义通道都落在 `k_stm32_rank_ch[]` 扫描序列内(挡"映射到不扫描的通道 → 恒读陈旧值")。
3. **备用通道**:RESERVED 路不接入任何语义,UI 与上报里不得出现;若实测有读数漂移,只记录不消费。
4. **端子侧变比(2026-10-23 补)**:上面 1/2 两条都只到 **ADC 引脚**。**"端子电压 → ADC 引脚电压"的变比在仓库里没有任何文档给出**(`docs/硬件平台/` 只有 `.tel` 网表与分析报告,无子板原理图),而 `V0.0_网表详细分析报告.md` §4.7 已把 `1k 串联 + 1k 到地` 这组网络定性为"**源阻抗匹配(手册推荐做法,非分压)**"。故**不得**用"2:1 分压"直接换算出二次值;该变比由 `docs/任务规划/数据可信.md` 卡 0b 实测确认。
---
## 9. 变更记录
| 日期 | 内容 |
|---|---|
| 2026-10-09 | 建档:固化 V0.1 语义分配(UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度、其余备用)与 17 路端到端映射;确立"主板只做监视/辅助测量、计量在子板"口径;勘误 PC4 通道号(IN12→IN14)与 PB0 定性(=IN8) |
| 2026-10-09 | **CubeMX 生成 ADC1(9 通道)落地**:新增 `Src/adc.c`/`Inc/adc.h` + HAL adc 三文件并挂进 uvprojx、`HAL_ADC_MODULE_ENABLED` 生效、`MX_ADC1_Init()` 入 `main.c`;分频 PCLK2/4 = 21 MHz——面板里 DIV2 已被 `FadcConstraint`(36 MHz)约束禁掉,**故不加 `.ioc` 键 / 代码守卫 / 审计项等额外防护**(曾加过,按决定撤除,理由见 §7"ADC 时钟"行);修正 PA0 标签笔误 `AD9_RES`→`ADC9_RES`。⚠ 本次重生成打回了 5 处定制(IWDG 延迟启动锚点、HardFault + 3 个 Fault 手工 Handler、`FreeRTOSConfig.h` 加固区、`freertos.c` 三处栈核算注释),已全部复原;存活审计新增 1 项 `adc1-hal-enabled`(共 19 项),现 19 通过 / 1 警告(timeSyncTask 手工定义)/ 0 失败,`@build` 0 错 0 警 |
| 2026-10-10 | **口径更正**:8 路电气量分属 TPAFE / STM32 两片转换器**定性为 V0.1 硬件缺陷**,撤销 2026-10-09 建档时"有意分配、不要修正"的说法;补记缺陷实质(跨转换器无同一时刻性、16 位双极性 vs 12 位单极性、语义与归属交叉)与 **V0.2 改版要求**(8 路电气量全部接 TPAFE,与 5 路备用路对调串联电阻目的地,BOM 不变);§7 新增"通道归属"行,明确 V0.1 上禁止跨转换器做相位/功率类运算。同步更正 `V0.1_网表详细分析报告.md` §1.4(新增 V10)/ §6-3,登记簿新增 **N-18** |
| 2026-10-10 | **STM32 ADC1 消费者落地(L1-3/L1-4)**:新增 `App/algo/adc_input.c/h`——语义映射表 `k_adc_map[]` 按本文件 §3/§5 逐条落地(`UA/UN/IA`→TPAFE `buf[6]/[5]/[2]`,`UB/UC/IB/IC/IN/TEMP`→`CH14/3/6/1/2/5`),并提供 `adc_input_raw()` **按语义取数**;`stm32_scan()` 实现 9 通道软件触发顺序扫描;`adc_input_init()` 增**映射自检**(STM32 映射通道必在扫描序列内)。§7 的"STM32 ADC 外设 / `adc_task` / TPAFE 采样触发"三行同步更新(后两者原为陈旧描述:TIM6 周期触发、L1 层取数)。§8 步骤 2 标注**引脚级注入验证尚未执行**。台架 `@test` PASS(`adc1_rc=0` / `adc1_err=0`、`ADC input layer init: OK`;首帧 `UA=11429 UN=11454 IA=11452`、`UB=1018 UC=1044 IB=943 IC=1069 IN=1052 T=850`——互异非饱和,且两次开机读数不同 → 实时转换而非常量),证据 `测试说明/boot_log_data/20261010_prod_adc_l1_boot_log.txt` |
| 2026-10-23 | **验证现状核查与排期**:确认 §8 步骤 1/2 与 `V0.0_网表详细分析报告.md` §5.1 第 6 条的"首次功能级 ADC 验证"**均无执行记录**——现有台架判据只证"通路活"(9 通道转换成功、零超时、互异非饱和、跨次开机不同),不证读数正确,连极性都未验。新增 §8 步骤 4:**"端子电压 → ADC 引脚电压"的变比在仓库内无任何文档**(无子板原理图),且 `1k 串联 + 1k 到地` 已被 §4.7 定性为"源阻抗匹配、非分压",故撤销"按 2:1 换算二次值"的用法。验证方法同步降为**不需要示波器 / 信号源**:`BUSY` 脉冲改用 `tpafe5160_frame_seq()` 帧计数,幅值改用万用表 + 三点线性拟合。排期见 `docs/任务规划/数据可信.md` 卡 0 / 0b |
| 2026-10-25 | **量程口径定死(本波卡 1)**:文首摘要行“TPAFE5160(16 位、8 通道同步、±10 V 双极性)”更正为“±5 V 满量程 = 10 V 跨度、LSB ≈ 152.59 µV(板上 RANGE 接 GND)”;§1“缺陷实质 2”补“满量程 = 10 V 跨度”;§7“TPAFE 量程”行重写并括注“±10 V 是芯片可选档(RANGE=HIGH)、本板未用”;新增 §7.1 固化“端子 → 子板变比 → 网名 AINn → 电阻网络 → 引脚 → 码值 → 满量程”链路分段口径——② 引脚侧 LSB 系数(TPAFE 152.59 / STM32 805.66 µV/码)**定死**,③ 1k+1k 网络“2:1 分压 vs 源阻抗匹配”两读法待卡 0 斜率判别,④ 端子变比为仓库缺口待卡 0b;“板级系数 305.18 / 1611.3 µV/码”定性为读法 A 条件值、判别前禁入代码;新增内容全部收进 §7.1 子节、本章编号刻意保持 §9 不动(`docs/算法/继电保护功能复现规划.md` §4 有指向本文件 §9 的既有跨文档引用,挪号会打断 doc-links 章节校验)。实测数值本轮按用户指示未采(台架未跑),相关段均标“待台架实测” |