Files
DLD154V4B/docs/devlog.md

6.1 KiB
Raw Blame History

DLD154V4B 开发日志

MCU: AT32F421F8P7 (Cortex-M4, 120MHz) | 线圈通道: 1路 | 通信: RS485


2026-06-23 — 跳出框框:去掉 >>6 精度浪费

背景

DLD154V4B 的检测算法继承自 M1HSTC12C5202, 2008和 TLD-110P87LPC762, 2003但有几个关键硬件差异

特性 M1H / TLD-110 DLD154V4B
主频 ~12MHz (8051) 120MHz (Cortex-M4)
分频芯片 CD4060 (Pin5, ÷32) ,直连 PA7
MCU 内分频 TIM3 DIV_4 → DIV_2
有效分频比 ÷32 ÷2
捕获方式 PCA 周期捕获 / 门控计数 TIM3_CH2 硬件输入捕获

问题:<<6 和 >>6 的精度浪费

原始代码的数据流存在一个"膨胀再压缩"的精度陷阱:

TMR3 ISR:
  Xn = 周期差值 (4800 ticks @ DIV_4)
  LPCNT = (32768 << 6) / Xn = 437     ← 窗口开大 64×降噪
  Value = Σ 437次 Xn ≈ 2,097,600      ← 437 样本精密累加

vd1_task:
  tmp = Value >> 6 = 32,775            ← 6bit 精度全部丢弃!
  CAPVD = IIR(tmp...)                  ← IIR 只看到 ~6 样本有效信息

<<6>>6 在数学上互相抵消——437 个样本累加,然后右移 6 位,等效仅用 ~7 个样本437/64 ≈ 6.8)。窗口开大降噪了,但精度被自己扔掉了。

方案:去掉 <<6/>>6用 MEASUREMENT_BASE

TMR3 ISR:
  LPCNT = 131072 / Xn = 27~54        ← 自适应窗口,不丢精度
  Value = Σ Xn ≈ 131072              ← 直接作为检测输入

vd1_task:
  CAPVD = IIR(Value)                 ← 全精度参与滤波
参数 旧方案 新方案
LPCNT (100kHz, DIV_2) 54
测量窗口 17.5ms (DIV_4) ~1ms
有效精度/窗口 ~6 样本 (>>6 后) 54 样本 (全保留)
Origin 范围 ~32K ~131K
灵敏度阈值 百分比公式,自动按比例缩放 ✓ 同 ✓
进入响应 ~50ms ~3ms

同步改进

# 改动 原因
1 TIM3 分频 DIV_4 → DIV_2 提高采样率,中断率 2× 仍安全 (CPU<3%)
2 MEASUREMENT_BASE = 131072 (2^17) 平衡精度和 Origin 范围
3 去除所有 >>6 保留全采样精度
4 离开增加 cnt_release >= 3 防抖 防瞬间噪声导致误落杆
5 基线冻结 + 100 窗口慢跟踪 仿 TLD-110有车不更新基线

为什么不需要 CD4060 外部分频

AT32F421 的 TIM3 有内置输入分频器,配合 120MHz 主频:

线圈频率 DIV_2 中断率 CPU 占用 (50周期/ISR)
100 kHz 50k/s 2.1%
150 kHz 75k/s 3.1%
200 kHz 100k/s 4.2%

均在安全范围内,无需外部分频芯片。

对比 M1H/TLD-110

指标 M1H (CD4060÷32) DLD154V4B (新)
测量间隔 ~50ms (固定) ~1ms (自适应)
进入防抖 500ms IN_DELAY 500ms IN_DELAY
离开防抖 1.9s OUT_DELAY 3次连续确认 + 1.9s OUT_DELAY
基线跟踪 100次 (有车也跟) 100次 (有车冻结)

2026-06-23 — 精简重构,对齐参考实现

  • 删除二阶差分滤波(计算但从未参与判决)
  • 删除 FltHistoryManager 死代码20+ 未用字段)
  • 删除 StageRangeConfig区间约束未引用
  • 删除动态窗口切换LOOP_WINDOW_SIZE_LOW→FAST
  • 时序状态机简化:去掉 PLUSE_IN_F/PLUSE_IN 中间层
  • 拨码去抖 10→5对齐 M1H
  • 代码量1177→706 行(-40%

2026-06-22 — 参考分析

reference_analysis.mdM1H + TLD-110 完整算法分析。


2026-06-23 — 指示灯行为规范化

LED 硬件对应

硬件 引脚 行为
红灯 PB1 (无宏, TMR14 PWM) 始终呼吸,不干预
绿灯 (LEDA) PA9 LEDA_ON/LEDA_OFF 自检慢闪 / 有车亮 / 无车灭
黄灯 (LEDC) PA10 LED_YELLOW_ON/OFF 故障快闪 / 断开次数编码

注: LEDA 宏在 BSP 遗留代码中指向 PB1红灯已修正为 PA9绿灯LEDB 宏无实际 IO已删除。

绿灯行为

状态 绿灯
上电自检 (Origin 未确立) 慢闪 200ms
数值稳定期 (128 样本 ≈ 128ms) 慢闪 200ms
正常工作,无车
正常工作,有车
线圈断开中 (黄灯快闪负责故障指示)

黄灯行为

条件 黄灯
上电后从未接线圈 快闪 200ms
线圈当前断开中 快闪 200ms
重连后,断开过 1 次 1 短闪 (80ms 亮) + 1.2s 间隔
重连后,断开过 2 次 2 短闪 + 1.2s 间隔
重连后,断开过 3+ 次 3 短闪 + 1.2s 间隔
正常,无断开记录

"不接线圈上电,上电后再接线圈"不计入断开次数。


2026-06-23 — 上电稳定期 & 线圈重连

上电稳定期

Origin 首次确立后,线圈振荡需要时间稳定。新增 g_loop_stable 标志:

  • INIT_VD()g_loop_stable = 0
  • vd1_task(): 稳定期内只做 IIR + 基线跟踪,跳过进入检测
  • 128 样本 (~128ms) 后 g_loop_stable = 1,正式启用检测
  • 安全复位时重置 g_loop_stable = 0

线圈重连状态保持

断开时不丢 VD_FLAG,重连后快速收敛 IIR

断开: 保留 loop1_VD_FLAG仅关断继电器
重连: loop1_CAPVD = 0 → 首个样本直锁 Value → IIR 后续正常跟踪
断开前 断开期间 重连后 检测结果
有车 车还在,绿灯灭 车还在 CAPVD < Origin-dlt → VD_FLAG=1 → 绿灯亮
有车 车离开 车离开 CAPVD ≈ Origin → cnt_release→3 → VD_FLAG=0
无车 车进入 车进入 CAPVD < Origin-dlt → VD_FLAG=1 → 绿灯亮

修订记录

版本 时间 说明
V1.3 2026-06-23 指示灯行为、稳定期、重连状态保持
V1.2 2026-06-23 <<6/>>6 精度浪费分析与改进
V1.1 2026-06-23 精简重构,对齐 M1H/TLD-110
V1.0 2026-06-22 参考分析文档