Files
vd-analysis/docs/measurement-window-quantization.md
T
wangfq fc243c010c docs(measurement): 测量节拍是区间 —— 周期累积法的窗口量化(用户提出)+ 全仓回灌
- 新文件 docs/measurement-window-quantization.md:窗长 = ⌊BASE/Xn₀⌋·Xn₁ tick(LPCNT 整数除法 + 学习后冻结)
  · 标称 BASE/f_cap(10.92/21.85ms)是【上限】,实际 = 标称 ×(BASE−r₀)/BASE × f₀/f_now
  · 站点偏差:100kHz −0.39%(PD132T 10.88ms / PD136HA 21.76ms)、60kHz −2.34%、带内最差 −6.20%(Xn₀=2049)
  · 深占压(频偏 −5%)窗再 +5.3%;"检测阈值"量级(≤0.46%)可忽略
  ·  Δf/f 口径不受影响:Value/Origin = Xn₁/Xn₀ 精确(余数完全约掉)—— 灵敏度/交付结论全部保持
  · ⚠ 新发现:loop1_LPCNT 为 INT8U(≤255),同族靠 406<Xn<2050 保证 ≤80;
    PD136HA 该窗口已注释 ⇒ Xn<129 时 8 位截断 ⇒ 异常线圈可能报"堵车"而非"故障"(建议恢复或加钳位)
- 新增 tools/window_calc.py(内置六型号参数,实跑验证文档全部数字)
- 回灌:cross-model 总表(新增脚注 + 测频路线说明 + 待补证1条)、PD132T↔PD136HA 对比报告(§0/§3.1/§3.2/§4.3)、
  两份交付对齐报告("测量窗列 = 标称上限" + 区间脚注)、filter-coefficient 专题(M1H 8.19ms 勘误 + τ 复算 + 脚注)、
  README(新增"专题文档"段 + 目录树)
- 表格校验 0 异常
2026-09-11 09:25:49 +08:00

181 lines
11 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.
# 测量节拍不是常数:周期累积法的窗口量化(`floor(BASE/Xn)·Xn`
> **2026-09-11** · 起因:指出 `void CAP1_isr()` 里 `loop1_Value = loop1_CapSum`(累加 LPCNT 个 `Xn`)与 `loop1_LPCNT = 32768/loop1_Xn` 的**整数除法** ⇒ **测量节拍是区间,不是定值**。
> 适用:**PD132T / PD136HA / M1H**BASE=32768 同族,代码逐行同构);**DLD154V4B / 154Pro 同理**BASE 不同,误差更小,见 §7)。
## 0. 结论
| # | 结论 | 说明 |
|---|---|---|
| 1 | **测量窗 = `floor(BASE/Xn₀) · Xn₁ / f_cap`** | `Xn₀` = 学习时算得并**冻结**的周期计数;`Xn₁` = 当前周期计数 |
| 2 | **标称值 `BASE/f_cap`10.92 / 21.85ms)是上限,不是真值** | 实际窗 = `BASE (BASE mod Xn₀)` 个 tick ⇒ **只短不长** |
| 3 | 站点偏差 = `(BASE mod Xn₀)/BASE` ⇒ 带内 **0 ~ 6.2%** | Xn₀ 越接近带低端(2050)越短;典型 100kHz 线圈(Xn₀=480)为 **0.39%** |
| 4 | 另有**频率跟踪分量**:窗时长 ∝ `1/f_now` | 阈值量级(≤0.46%)可忽略;**深占压**(线圈频偏 −5%)时窗变长 +5.3% |
| 5 | ⭐ **Δf/f 口径完全不受影响** | `Value/Origin = Xn₁/Xn₀` **精确成立**(整除余数 r 在分子分母**完全约掉**)⇒ 既有灵敏度/交付结论全部保持 |
| 6 | ⚠ **`loop1_LPCNT` 声明为 `INT8U`(≤255** | 同族靠 `406 < Xn < 2050` 保证 `LPCNT ≤ 80`**PD136HA 已把该窗口注释掉** ⇒ `Xn < 129`(线圈 >372kHz)会 8 位溢出(§5 |
---
## 1. 代码机理(PD132T / PD136HA 逐行同构)
```c
/* PD132T main.c:96-105 / PD136HA main.c:163-172 —— 学习期:LPCNT 算一次后冻结 */
if (loop1_INI_LOOP) {
if (loop1_LPCNT == 0) {
if (loop1_CapCnt > 100) {
loop1_LPCNT = 32768 / loop1_Xn; // ← 整数除法,截断
if (loop1_LPCNT == 0) loop1_LPCNT = 1; // Xn>32768 时兜底
loop1_CAPVD = 0; loop1_CapSum = 0; loop1_CapCnt = 0;
}
}
}
/* 测量期:累加 LPCNT 个 Xn */
loop1_CapSum += loop1_Xn;
if (loop1_CapCnt >= loop1_LPCNT) {
loop1_Value = loop1_CapSum; // = Σ(LPCNT 个 Xn)
loop1_CapSum = 0; loop1_CapCnt = 0;
}
```
关键性质(两条都容易被忽略):
1. **`LPCNT` 是"一次冻结"**:只在 `LPCNT == 0``CapCnt > 100` 时计算一次,此后不再重算;只有 `INIT_VD()`(学习/复位)才 `LPCNT = 0` 重新标定。
2. **`CapCnt++` 发生在累加之前**PD132T:83 / PD136HA:148)⇒ 判据触发时 `CapSum` 恰好含 **LPCNT** 项 ⇒ `Value = LPCNT × Xn`Xn 恒定时)✓
⇒ 因此:**窗长(tick= `LPCNT × Xn₁` = `floor(BASE/Xn₀) × Xn₁`**,而**不是**恒定 `BASE`
---
## 2. 代数:窗为什么"只短不长",而口径为什么不受影响
`BASE = 32768``r₀ = BASE mod Xn₀`,则
```
LPCNT = (BASE r₀) / Xn₀ (整数除法)
窗长(tick) = LPCNT · Xn₁ = (BASE r₀) · (Xn₁ / Xn₀) Xn₁ = 当前值)
窗时长 = 窗长(tick) / f_cap
```
**两条分量**
| 分量 | 表达式 | 量级 | 性质 |
|---|---|---|---|
| ① 整除余数量化 | `(BASE r₀)/BASE` | 带内 **0 ~ 6.2%** | **站点确定值**(不抖动;随该站点线圈频率而定) |
| ② 频率跟踪 | `Xn₁/Xn₀ = f₀/f_now` | 阈值内 ≤ +0.46%;深占压 +5% 量级 | 与频偏**同向**(频率跌 ⇒ 窗变长) |
**口径为什么不受影响**(最重要):
```
Origin = LPCNT · Xn₀ = BASE r₀ (学习值)
Value = LPCNT · Xn₁ (当前值)
Value / Origin = Xn₁ / Xn₀ ← 精确,r₀ 完全约掉 ✓
```
⇒ 相对量 `Δf/f = 1 Value/Origin` **与 r₀、与 BASE、与 f_cap 全部无关** ✓(数值验证:Xn₀ = 406/480/800/2050 四种站点,频偏 0.5% 时 `Value/Origin` 均精确等于 `Xn₁/Xn₀`)。
唯一残留误差是判据阈值的**截断**`dlt = Origin × 表值 >> 16` ⇒ 有效阈值 = `表值/65536 ± 1/Origin`,即 **±0.003%**1/32768)—— 可忽略。
## 3. 数值表(按站点线圈频率)
`Xn₀ = C / f_coil`(族内 `C = 32·f_cap/边沿系数 = 4.8×10⁷`PD132T/PD136HA 通用):
| 线圈频率 | Xn₀ | LPCNT | 窗长(tick) | PD132T 窗@3MHz | 偏差 | PD136HA 窗@1.5MHz | 偏差 | M1H 窗@4MHz |
|---|---|---|---|---|---|---|---|---|
| 240 kHz | 200 | 163 | 32 600 | 10.867 ms | 0.51% | 21.733 ms | 0.51% | 8.150 ms |
| **100 kHz(标称)** | 480 | 68 | 32 640 | **10.880 ms** | **0.39%** | **21.760 ms** | **0.39%** | 8.160 ms |
| 60 kHz | 800 | 40 | 32 000 | 10.667 ms | 2.34% | 21.333 ms | 2.34% | 8.000 ms |
| 40 kHz | 1200 | 27 | 32 400 | 10.800 ms | 1.12% | 21.600 ms | 1.12% | 8.100 ms |
| 23.4 kHz(带低端) | 2050 | 15 | 30 750 | 10.250 ms | **6.16%** | 20.500 ms | 6.16% | 7.688 ms |
| (带内最差) | 2049 | 15 | 30 735 | 10.245 ms | **6.20%** | 20.490 ms | 6.20% | 7.684 ms |
**读法**`10.92 ms` / `21.85 ms` 是**标称上限**;具体站点按上表由**线圈频率**决定(偏差随 `LPCNT` 变小而变大 —— 低频线圈的窗更短、量化更粗)。
**积分深度**(每窗平均的有效线圈周期数)同样按此缩放:PD132T ≈ `16·LPCNT`、PD136HA ≈ `32·LPCNT`100kHz 站点:1088 / 2176 个线圈周期)。
---
## 4. 频率跟踪分量(窗随时间"伸缩")
因为 `LPCNT` 冻结、而窗累加的是**当前**周期,所以:
```
窗时长(t) = 窗长(tick)/f_cap = (BASE r₀)/f_cap × (f₀ / f_now)
```
| 线圈频偏 | 窗时长变化 | 现场含义 |
|---|---|---|
| 0.032%PD132T 档 3 阈值) | +0.032% | 可忽略 |
| 0.458%PD132T 档 0 阈值) | +0.460% | 可忽略 |
| 1% | +1.01% | 温度漂移量级 |
| **5%** | **+5.26%** | **大车/拖车深占压**:窗变长 ⇒ 恢复更慢 |
⇒ 结论:**在"检测阈值"量级上可忽略(≤0.5%),在"深占压"场景下会把响应/恢复时间再拉长百分之几**。这也解释了为什么"深占压后基线跟踪慢"的代码设计(冻结 + `LC_HOLD` 重学)是必要的。
---
## 5. ⚠ 位宽与窗口检查(本轮新发现)
| 变量 | 类型 | 上限 | 约束 | 风险 |
|---|---|---|---|---|
| `loop1_LPCNT` | `INT8U`PD132T main.h:37 / PD136HA main.h:64 | **255** | `LPCNT = 32768/Xn ≤ 255` ⇒ 需 `Xn ≥ 129` | ⚠ 见下 |
| `loop1_CapCnt` | `INT8U` | 255 | 需 `LPCNT ≤ 255`(同上) | 同上 |
| `loop1_CapSum` / `Value` / `CAPVD` | `INT16U` | 65 535 | 标称 32 768**余量 2×** | 频率下漂 >100%(Xn 翻倍)才溢出 ⇒ 现实不可达 |
**同族靠频率窗口保护 8 位 LPCNT**`406 < Xn < 2050``LPCNT ≤ 80` ✓(PD132T main.c:85、M1H 同构)。
**PD136HA 已把该窗口注释掉**`// if(loop1_Xn>400 && loop1_Xn<2030)`main.c:150V3.14 去环路 LED 时一并屏蔽)⇒ **保护消失**
-`Xn < 129`(等效线圈 > 372 kHz,例如线圈断线/短路的异常振荡、或强干扰产生的窄脉冲)⇒ `LPCNT` 真值 >255 ⇒ **8 位截断**(如 327 → 71)⇒ 窗长骤降(71×Xn)而 `Origin ≈ 32768``Value ≪ Origin dlt`**判为"持续有车"** ⇒ 继电器吸合 → HOLD 300s 超时 → 整机复位。
- 对比 **PD132T**:同样的异常会走 `LOOP_OK = 0` + LED 快闪(**故障指示**,不产生有车输出)。
-**行为差异**:同一种线圈异常,PD132T 报"故障"PD136HA 可能报"堵车"。
- **建议**(固件侧,待评估):PD136HA 恢复窗口检查,或至少加 `if (loop1_LPCNT > 80) → 判故障` 的兜底钳制。
> 同类检查也适用于 M1H(同 8 位 `LPCNT` + 无窗口检查 ⇒ 同风险)。**注意**:PD132T 的窗口检查同时承担"线圈异常 → 故障"的职责,恢复/删除前要确认异常语义有替代路径。
---
## 6. 受影响 / 不受影响(既有数值的正确读法)
| 类别 | 项目 | 处置 |
|---|---|---|
| ✅ **不受影响** | `Δf/f = 表值/65536` 口径、灵敏度表换算、跨型号档位对比、进入/离开判据、滞回语义 | 保持不动(§2 代数保证) |
| ⚠️ **同一因子缩放** | 测量节拍、基线更新周期、IIR 时间常数 τ、进入/离开响应时间、最小可检占压、积分深度 | 表中数值标注"**标称(上限)**",实际 = 标称 × `(BASEr₀)/BASE` × `f₀/f_now` |
**修正后的表述模板**(建议全仓沿用):
> 测量节拍 **≈10.88 ms**(标称上限 10.923 ms = 32768/3MHz;实际 = `floor(32768/Xn₀)·Xn₀/f_cap`100kHz 站点 0.39%,带内最差 6.2%)
例:PD132T 基线更新周期 = 100 × 10.88ms = **1.088 s**(标称上限 1.092s);PD136HA = 256 × 21.76ms = **5.571 s**(标称上限 5.593s)。
---
## 7. 跨型号意义:BASE 越大量化误差越小
站点量化误差上限 = `Xn₀/BASE`= `1/LPCNT`):
| 型号 | BASE | 100kHz 站点 Xn₀ | LPCNT | 窗量化误差上限 |
|---|---|---|---|---|
| M1H / PD132L / PD132T / PD136HA | 32 768 | 480PD132T/136HA | 68 | **≤1.46%**(带低端 ≤6.25% |
| DLD154V4B | 131 072 | 1200 | 109 | ≤0.92% |
| DLD154Pro | 524 288 | 600 | 873 | ≤0.11% |
**大基数的第二个好处**(除既有"绝对分辨率高 4×"之外):**同比降低窗量化误差** —— 因为 `LPCNT` 更大,"`floor` 截断"的相对损失更小。V4B 的 1.09ms 窗实际为 ≈1.09ms(−0.9% 上限),154Pro 的 8.74ms 窗几乎无量化损失。
---
## 8. 验证与复算方法
1. **纯计算**(现场 5 分钟):量出线圈频率 `f_coil``Xn₀ = C/f_coil``C = 4.8×10⁷`PD132T/PD136HA 通用)⇒ `LPCNT = ⌊32768/Xn₀⌋` ⇒ 窗长 = `LPCNT·Xn₀` tick ⇒ 窗时长 = 窗长/`f_cap`。可算到 0.1% 以内。
2. **固件侧**:把 `loop1_LPCNT` / `loop1_Value` 引到可用观测(PD132T 无 UART ⇒ 需临时改 LED 或 ISP 读 RAMPD136HA 有 SWD ⇒ 直接在线看变量最省事)。
3. **回归验证**:若实测"基线更新时间"与 `窗长×100(256)` 不符,说明 `LPCNT` 被二次重算过 —— 检查是否存在第二处 `LPCNT = 0`PD132T `INIT_VD()`、PD136HA main.c:411;其 430 行为注释状态)。
4. **台架**:信号发生器替代 CD4060 输出已知 f_in ⇒ 交替改频率 0.1%/0.5%/2%,观察继电器翻转窗口数与理论 `dlt` 是否一致(验证 §2 的"口径精确"结论)。
---
## 相关文档
- 双型号对比:`docs/pd132t-vs-pd136ha-comparison.md`(§3 测量与归一化)
- 跨型号总表:`docs/cross-model-comparison.md`(测量节拍/基线周期行)
- 滤波系数专题:`docs/filter-coefficient-79-vs-64.md`(τ 口径)
- 交付对齐:`docs/pd136ha-to-dld154v4b-delivery-alignment.md``docs/pd132t-to-v4b-delivery-alignment.md`