- 三级降采样链:捕获级(Xn,6.25kHz)→ 窗级(Value/CAPVD,92Hz)→ 基线级(Origin,0.92Hz) - PD132T @100kHz:Xn=480tick=**160µs**(÷32 后信号的半周期 = 16 个线圈周期)/ Value = 68×160µs = **10.880ms** / Origin = 100 窗 = **1.088s** - PD136HA @100kHz:Xn = **320µs**(整周期 = 32 个线圈周期)/ Value = **21.760ms** / Origin = 256 窗 = **5.571s** - τ 换算成"窗"后与型号无关:τ/T = 256/α ⇒ α79 = 3.24 窗、α64 = 4.0 窗 - Origin 是**块平均**(`ORG_SUM/100`;PD136HA `>>8`),非滑动平均 ⇒ 基线跟踪粒度 = 1 个块; 有车期间 ORG_SUM 清零 + ORG_CNT 停止 ⇒ 冻结 + 重新累计 - 上电首个 Origin 只有**单窗样本**(92Hz 单点),需 1.09s / 5.57s 才变块平均 ⇒ 学习/静默期长度的根本依据 - 响应链三段:①窗内平均 ≤1 窗 ②IIR ≈ τ·ln(Δ/(Δ−阈值)) ③输出级 50ms tick(PD132T 进入确认 = 0) - 精化跨型号表 PD132T「进入确认」表述(无 IN_DELAY 判定,而非"已注释");表格校验 0 异常
16 KiB
测量节拍不是常数:周期累积法的窗口量化(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 逐行同构)
/* 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;
}
关键性质(两条都容易被忽略):
LPCNT是"一次冻结":只在LPCNT == 0且CapCnt > 100时计算一次,此后不再重算;只有INIT_VD()(学习/复位)才LPCNT = 0重新标定。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:150,V3.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 时间常数 τ、进入/离开响应时间、最小可检占压、积分深度 | 表中数值标注"标称(上限)",实际 = 标称 × (BASE−r₀)/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 | 480(PD132T/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. 验证与复算方法
- 纯计算(现场 5 分钟):量出线圈频率
f_coil⇒Xn₀ = C/f_coil(C = 4.8×10⁷,PD132T/PD136HA 通用)⇒LPCNT = ⌊32768/Xn₀⌋⇒ 窗长 =LPCNT·Xn₀tick ⇒ 窗时长 = 窗长/f_cap。可算到 0.1% 以内。 - 固件侧:把
loop1_LPCNT/loop1_Value引到可用观测(PD132T 无 UART ⇒ 需临时改 LED 或 ISP 读 RAM;PD136HA 有 SWD ⇒ 直接在线看变量最省事)。 - 回归验证:若实测"基线更新时间"与
窗长×100(256)不符,说明LPCNT被二次重算过 —— 检查是否存在第二处LPCNT = 0(PD132TINIT_VD()、PD136HA main.c:411;其 430 行为注释状态)。 - 台架:信号发生器替代 CD4060 输出已知 f_in ⇒ 交替改频率 0.1%/0.5%/2%,观察继电器翻转窗口数与理论
dlt是否一致(验证 §2 的"口径精确"结论)。
9. 时序链详解:六个量的更新时间(2026-09-11 补,用户提出)
整条链是三级降采样:捕获级(每 Xn 一次)→ 窗级(每 LPCNT 次捕获一次)→ 基线级(每 100/256 窗一次)。
捕获中断(PCA/ADTIM4) 窗结账(ISR 内) 主循环(紧随其后) 块平均
│ │ │ │
每 t_Xn 一次 每 LPCNT 次捕获 每次 Value 更新 每 100/256 窗
├── Xn = 相邻捕获差 ────► ├── Value = Σ Xn ────────► ├── CAPVD = IIR(Value) ──► ├── Origin = ΣCAPVD/N
│ (6.25 kHz) │ (92 Hz) │ (92 Hz) │ (0.92 Hz)
└── 频率窗口检查(若启用) └── CAP_OK = 1 └── 判据 dlt = Origin×表>>16
9.1 六个量逐一(PD132T @ 100kHz 站点,Xn₀=480、LPCNT=68)
| 量 | 更新触发 | 更新周期 | 物理含义 |
|---|---|---|---|
loop1_Xn |
每次捕获中断(相邻两次捕获之差) | t_Xn = Xn/f_cap = **160 µs**(6 250 次/s) |
÷32 后信号的半周期 = 16 个线圈周期(双沿捕获) |
loop1_Value |
ISR 内 CapCnt >= LPCNT 时 |
LPCNT·t_Xn = **10.880 ms**(92 次/s) |
LPCNT 个 Xn 之和(= 窗)⇒ 同步置 CAP_OK=1 |
loop1_CAPVD |
紧随其后调用 VD1_TASK()(主循环) |
10.880 ms(与 Value 同拍) | IIR 平滑值:CAPVD += (Value−CAPVD)·Flt_Reg>>8 |
loop1_Origin |
VD1_TASK() 内 ORG_CNT == 99 且无车 |
100 窗 = 1.088 s(0.92 次/s) | Origin = ORG_SUM/100(块平均,非滑动) |
| 测量节拍 | = Value/CAPVD/判据的共同节拍 |
10.880 ms(标称上限 10.923) | 见 §1-§3(区间值,按站点 −0.4%~−6.2%) |
| 基线更新周期 | = Origin 的更新间隔 |
1.088 s(标称上限 1.092 s) | 块粒度 ⇒ 基线跟踪"阶梯式" |
| IIR 时间常数 τ | — | α79: 35.3 ms(= 3.24 窗)/ α64: 43.5 ms(= 4.0 窗) | τ = T·256/α |
9.2 同表:PD136HA @ 100kHz(Xn₀=480、LPCNT=68,f_cap 减半)
| 量 | 更新周期 | 与 PD132T 的比 |
|---|---|---|
loop1_Xn |
480/1.5MHz = **320 µs**(3 125 次/s) |
×2(单沿 ⇒ 整周期 = 32 个线圈周期) |
loop1_Value |
68 × 320µs = **21.760 ms**(46 次/s) |
×2 |
loop1_CAPVD |
21.760 ms | ×2 |
loop1_Origin |
256 窗 = **5.571 s** |
×5.1(256/100 × 2) |
| τ(α64) | 87.0 ms = 4.0 窗 | 窗数相同、绝对 ×2 |
9.3 四条容易搞混的关系(重点)
t_Xn = 前端分频比 /(边沿系数 · f_coil)—— PD132T =16/f_coil、PD136HA =32/f_coil、M1H =32/f_coil(双沿 ⇒ 16,单沿 ⇒ 32)。Xn是"测量结果"而不是"时间源":它本身随线圈频率变化(Xn ∝ 1/f),所以"更新周期"必须写成Xn/f_cap(随站点变),而不是常数。Value是"计数域降采样",不是抽点:Value = Σ(LPCNT 个 Xn)是箱式积分(boxcar),因此Xn的 6.25kHz 信息在 92Hz 处被平均而不是被丢弃(无混叠问题);这也是Δf/f口径精确的来源(§2)。- τ 换算成"窗"后与型号无关:
τ/T = 256/α⇒ α79 = 3.24 窗、α64 = 4.0 窗(与 BASE、f_cap、分频比全无关)⇒ 讨论"滤波快慢"时用"窗"最直观。 Origin是块平均:每 100(PD136HA 256)个CAPVD才整体替换一次 ⇒ 基线跟踪的时间分辨率 = 1 个块(1.09 s / 5.57 s),块内一直用"上一个块的均值"。有车期间ORG_SUM被清零且ORG_CNT停止 ⇒ 有车冻结 + 重新累计(不是"有车也跟踪")。
9.4 响应链:三段叠加
| 段 | 延迟 | 说明 |
|---|---|---|
| ① 窗内平均 | ≤ 1 窗(≤10.9 / 21.8 ms) | 变化要"填满"当前窗才在 Value 中完整体现 |
| ② IIR 上升到阈值 | ≈ τ·ln(Δ/(Δ−阈值)) |
大信号快(Δ=1% vs 阈值 0.09% ⇒ ≈0.09τ ≈ 3ms);小信号慢(Δ≈阈值 ⇒ 多个 τ) |
| ③ 输出级 | 50 ms 节拍(PD132T/M1H;PD136HA tick ⚠待实测) | FLAG_IN 在 T1 ISR 里被消费;进入确认 PD132T = 0(立即,无 IN_DELAY 判定)、M1H = IN_DELAY=10≈0.6 s |
⇒ 例:PD132T 大车(Δ≈1%)⇒ ≈10.9 + 3 + ≤50 ≈ ≤65 ms;PD136HA 同条件 ⇒ ≈21.8 + 6 + ≤50 ≈ ≤80 ms(IIR 更慢但窗长翻倍是主因)。
9.5 上电初期的一个易忽略点
INI_LOOP 结束时(CapCnt>100 后第一个满窗)执行的是:
loop1_CAPVD = loop1_CapSum; loop1_Origin = loop1_CAPVD; loop1_INI_LOOP = 0;
⇒ 上电时 Origin 只有一个窗的样本(92Hz 单点、噪声最大),要等第一个块(100/256 窗 = 1.09 s / 5.57 s) 完成才变成块平均 ⇒ 这就是"上电静默期/学习期"必须留足时间的根本原因(PD136HA 侧更长,5.6 s)。
相关文档
- 双型号对比:
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