From 7d15be9783ebbb7f67143c0f73a7e3e0408e090a Mon Sep 17 00:00:00 2001 From: wangfq Date: Wed, 24 Jun 2026 08:11:01 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=89=8B=E5=86=8C=E5=92=8C=E6=8A=80=E6=9C=AF=E8=A7=84=E6=A0=BC?= =?UTF-8?q?=E4=B9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 + docs/product-manual.md | 251 +++++++++++++++++ docs/technical-spec.md | 605 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 865 insertions(+) create mode 100644 docs/product-manual.md create mode 100644 docs/technical-spec.md diff --git a/README.md b/README.md index b1284b9..d8247c4 100644 --- a/README.md +++ b/README.md @@ -109,3 +109,12 @@ DLD154V4B/ - IDE: Keil MDK / AT32 IDE - 调试器: SWD (PA13/PA14) + +## 文档 + +| 文档 | 说明 | +|------|------| +| [产品手册](docs/product-manual.md) | 面向用户:功能说明、安装指南、故障排查 | +| [技术规格书](docs/technical-spec.md) | 面向工程:算法详解、IO 分配、电气参数、通信协议 | +| [开发日志](docs/devlog.md) | 版本历史和设计决策记录 | +| [参考分析](docs/reference_analysis.md) | M1H (STC12C5202) + TLD-110 (P87LPC762) 算法分析 diff --git a/docs/product-manual.md b/docs/product-manual.md new file mode 100644 index 0000000..a428126 --- /dev/null +++ b/docs/product-manual.md @@ -0,0 +1,251 @@ +# DLD154V4B 产品手册 + +> 单路线圈车辆检测器 | 型号: DLD154V4B | 版本: V1.5 +> 适用于停车场、收费站、交通卡口等场景的车辆到达/离开检测 + +--- + +## 1. 产品概述 + +DLD154V4B 是一款基于 ARM Cortex-M4 微控制器的**单通道环形线圈车辆检测器**。通过实时监测埋地线圈的 LC 振荡频率变化,精确检测车辆的存在与离开。产品采用专利级平坦性离开判定算法(CN200910309382),有效解决大车通行时频率多峰导致的误触发问题。 + +### 1.1 核心特性 + +- **高精度频率测量**:自适应窗口脉冲计数,归一化基线 ≈ 131072,保留全部采样精度 +- **专利离开判定**:频率 + 一阶导数 + 二阶导数三条件平坦性判定,防大车误检 +- **上电稳定期**:128ms 线圈振荡稳定窗口,避免上电误判 +- **线圈重连保护**:断开期间保持有车状态,重连后快速恢复,误判率极低 +- **诊断黄灯**:断开/重连次数编码闪烁,现场故障一目了然 +- **灵敏度 4 级可调**:通过 DIP 开关配置,0.015% ~ 0.33% 频率变化检测 +- **双输出模式**:存在输出 / 脉冲输出可选 +- **宽频率范围**:支持 30 ~ 200 kHz 线圈频率 + +### 1.2 适用场景 + +| 场景 | 说明 | +|------|------| +| 道闸控制 | 车辆到达触发抬杆,离开触发落杆 | +| 车位检测 | 实时监测车位占用状态 | +| 流量统计 | 配合上位机统计车流量 | +| ETC/收费站 | 触发抓拍、计费 | +| 红绿灯触发 | 感应线圈触发信号灯相位切换 | + +--- + +## 2. 技术参数 + +| 项目 | 参数 | +|------|------| +| 产品型号 | DLD154V4B | +| 微控制器 | AT32F421F8P7 (ARM Cortex-M4) | +| 主频 | 120 MHz | +| Flash | 64 KB | +| SRAM | 16 KB | +| 线圈通道数 | 1 路 | +| 工作电压 | DC 12V / 24V(宽压) | +| 功耗 | < 2W | +| 线圈电感范围 | 50 ~ 1000 μH(推荐 100 ~ 300 μH) | +| 频率测量范围 | 30 ~ 200 kHz | +| 频率测量精度 | 优于 0.01% | +| 灵敏度等级 | 4 级(拨码可调) | +| 响应时间 | < 10 ms(进入检测) | +| 进入防抖 | 500 ms | +| 离开防抖 | 1.9 s + 平坦性三条件确认 | +| 脉冲输出宽度 | 950 ms | +| 继电器输出 | 2 路(主输出 + 辅助输出) | +| 继电器触点容量 | AC 250V / 3A | +| 通信接口 | RS485(通过外部芯片) | +| 工作温度 | -40°C ~ +85°C | +| 存储温度 | -55°C ~ +125°C | +| 防护等级 | IP65(封装后) | +| 外形尺寸 | 标准 DIN 导轨安装 | +| 重量 | 约 120g | + +--- + +## 3. 硬件接口 + +### 3.1 端子定义 + +| 端子 | 标识 | 功能 | 说明 | +|------|------|------|------| +| 1 | V+ | 电源正极 | DC 12V / 24V | +| 2 | GND | 电源地 | — | +| 3 | LOOP | 线圈端子 | 接环形线圈两端 | +| 4 | LOOP | 线圈端子 | 接环形线圈两端 | +| 5 | RLY1-NO | 继电器 1 常开 | 主输出(存在 / 脉冲) | +| 6 | RLY1-COM | 继电器 1 公共 | — | +| 7 | RLY1-NC | 继电器 1 常闭 | — | +| 8 | RLY2-NO | 继电器 2 常开 | 辅助输出 | +| 9 | RLY2-COM | 继电器 2 公共 | — | +| 10 | RS485-A | RS485 A | 通信接口 | +| 11 | RS485-B | RS485 B | 通信接口 | + +### 3.2 指示灯 + +| 指示灯 | 颜色 | 引脚 | 功能 | +|--------|------|------|------| +| 红灯 | 红色 | PB1 | 系统运行指示(PWM 呼吸灯) | +| LEDA | 绿色 | PA9 | 车辆检测指示 / 自检 | +| LEDC | 黄色 | PA10 | 故障诊断指示 | + +--- + +## 4. 功能说明 + +### 4.1 检测原理 + +环形线圈埋于路面下,与检测器内部电容构成 LC 谐振回路。当金属物体(车辆)经过线圈上方时,线圈电感发生变化,导致谐振频率上升。检测器通过高精度输入捕获实时监测频率偏移,当偏移量超过灵敏度阈值时,判定为有车。 + +**频率-检测映射:** + +``` +线圈频率 f₀ (无车基线) → 车辆进入 → f ↑ (频率上升) + ↓ + f - f₀ > 阈值 → 判定"有车" + ↓ + 车辆离开 → f ↓ → f ≈ f₀ + ↓ + 平坦性三条件确认 → 判定"无车" +``` + +### 4.2 灵敏度配置 + +通过 DIP 开关 SA_1、SA_2 设置 4 级灵敏度: + +| SA_2 | SA_1 | 灵敏度 | 频率变化阈值 | 适用场景 | +|------|------|--------|-------------|----------| +| ON (1) | ON (1) | **低** | 0.33% | 大车 / 高底盘车辆 | +| ON (1) | OFF (0) | **中** | 0.16% | 普通轿车 | +| OFF (0) | ON (1) | **高** | 0.055% | 摩托车 / 小轿车 | +| OFF (0) | OFF (0) | **最高** | 0.015% | 高灵敏度场景 | + +> **注**:DIP 拨向 ON = 1。灵敏度越高,检测越灵敏,但也越容易受环境干扰。建议从"中"灵敏度开始调试。 + +### 4.3 DIP 开关完整配置 + +| 引脚 | DIP | 功能 | ON | OFF | +|------|-----|------|-----|-----| +| PA0 | SA_1 | 灵敏度 bit0 | — | — | +| PA1 | SA_2 | 灵敏度 bit1 | — | — | +| PA2 | SW_3 | 输出模式 | 脉冲输出 | 存在输出 | +| PA3 | SW_4 | 延时 | 延时 2s | 无延时 | +| PA4 | SW_5 | 安全复位 | 触发复位 | 正常运行 | + +### 4.4 输出模式 + +**存在输出(SW_3 = OFF):** +- 有车时 RLY1 持续吸合 +- 无车时 RLY1 释放 +- 配合 OUT_DELAY 1.9s 离开延时 + +**脉冲输出(SW_3 = ON):** +- 车辆确认进入时 RLY1 吸合 950ms 后释放 +- 适用于触发道闸抬杆等需要单次脉冲的场景 + +**延时功能(SW_4 = ON):** +- 额外增加 2 秒延时 +- 常用于需要延迟落杆的场景 + +### 4.5 安全复位 + +当 SW_5 拨向 ON 时,检测器进入安全复位模式: +- 所有继电器输出关闭 +- 频率基线清空,重新学习 +- 绿灯慢闪等待线圈稳定 +- 约 4 分钟后自动恢复正常(或手动拨回 OFF) + +> **⚠ 安全复位仅在维护或更换线圈后使用,正常运行时请保持 SW_5 = OFF。** + +--- + +## 5. 指示灯行为 + +### 5.1 正常状态 + +| 状态 | 红灯 (PB1) | 绿灯 (LEDA/PA9) | 黄灯 (LEDC/PA10) | +|------|-----------|-----------------|-------------------| +| 上电自检中 | 呼吸 | **慢闪** (200ms) | 快闪 (200ms) | +| 正常运行,无车 | 呼吸 | 灭 | 灭 | +| 正常运行,有车 | 呼吸 | **亮** | 灭 | + +### 5.2 故障状态 + +| 故障类型 | 红灯 | 绿灯 | 黄灯 | 说明 | +|---------|------|------|------|------| +| 线圈断开(当前) | 呼吸 | 灭 | **快闪** (200ms) | 检查线圈连接 | +| 线圈重连,断开 1 次 | 呼吸 | 正常 | **1 短闪** + 1.2s 灭 | 发生过 1 次断开,已恢复 | +| 线圈重连,断开 2 次 | 呼吸 | 正常 | **2 短闪** + 1.2s 灭 | 发生过 2 次断开,已恢复 | +| 线圈重连,断开 3+ 次 | 呼吸 | 正常 | **3 短闪** + 1.2s 灭 | 多次断开,建议检查接头 | + +- **快闪**:200ms 亮 / 200ms 灭 +- **N 短闪**:N × (80ms 亮 + 200ms 灭),循环间隔 1.2s +- **呼吸**:PWM 渐变,系统运行指示 + +> **提示**:上电后如果黄灯快闪且绿灯慢闪,说明线圈未连接或已断开;接好线圈后黄灯灭、绿灯正常工作。 + +--- + +## 6. 安装指南 + +### 6.1 线圈安装 + +1. **线圈尺寸**:推荐 1m × 2m 矩形,绕 3 ~ 4 匝 +2. **埋设深度**:地表下 3 ~ 5 cm +3. **线圈电感**:100 ~ 300 μH(推荐值) +4. **引线**:双绞屏蔽线,长度 < 100m +5. **防水处理**:线圈和接头做防水密封 + +### 6.2 检测器安装 + +1. 固定在 DIN 导轨或机柜内 +2. 远离强电磁干扰源(变频器、大电机等) +3. 线圈引线独立走线,勿与强电线并行走线 +4. 确保良好接地 + +### 6.3 上电调试 + +1. 确认线圈正确连接后上电 +2. 观察绿灯:慢闪 ~1s 后熄灭(无车状态),表示稳定就绪 +3. 金属物体(铁板或车辆)靠近线圈 → 绿灯应亮起 +4. 根据实际灵敏度调整 SA_1/SA_2 +5. 选择输出模式(SW_3)和延时(SW_4) + +--- + +## 7. 故障排查 + +| 现象 | 可能原因 | 处理方法 | +|------|---------|----------| +| 黄灯快闪,绿灯灭 | 线圈断开或未连接 | 检查线圈接头、引线通断 | +| 绿灯常亮不灭 | 灵敏度太高 / 线圈频率漂移 | 降低灵敏度 / 检查线圈 | +| 绿灯从不亮 | 灵敏度太低 / 线圈 Q 值过低 | 提高灵敏度 / 更换线圈 | +| 红灯不亮 | 电源故障 | 检查供电电压 | +| 频繁误触发 | 电磁干扰 / 灵敏度太高 | 降低灵敏度 / 屏蔽干扰源 | +| 大车通过时多次触发 | 旧版固件 / 平坦性未开启 | 升级 V1.4+ 固件 | +| 安全复位后不恢复 | 线圈频率异常 | 检查线圈电感是否在范围内 | + +--- + +## 8. 版本历史 + +| 版本 | 日期 | 说明 | +|------|------|------| +| V1.0 | 2026-06-22 | 初版,基于 M1H / TLD-110 参考实现 | +| V1.1 | 2026-06-23 | 精简重构,代码量 -40% | +| V1.2 | 2026-06-23 | 去掉 <<6/>>6 精度浪费,TIM3 DIV_2 分频 | +| V1.3 | 2026-06-23 | 指示灯行为规范化,上电稳定期,线圈重连保护 | +| V1.4 | 2026-06-23 | 移植 CN200910309382 平坦性离开判定 | +| V1.5 | 2026-06-23 | Origin 基线污染保护,USE_FLATNESS_EXIT 编译开关 | + +--- + +## 9. 订购信息 + +| 型号 | 说明 | +|------|------| +| DLD154V4B | 单路环形线圈车辆检测器,AT32F421,RS485 | + +--- + +> **技术规格书**(算法详情、IO 分配、电气参数、通信协议等)请参阅 [技术规格书](technical-spec.md) diff --git a/docs/technical-spec.md b/docs/technical-spec.md new file mode 100644 index 0000000..0afdd47 --- /dev/null +++ b/docs/technical-spec.md @@ -0,0 +1,605 @@ +# DLD154V4B 技术规格书 + +> 单路线圈车辆检测器 | 固件版本: V1.5 | 文档版本: V1.0 +> 本文档面向工程开发、系统集成、通信协议对接及故障深度分析 + +--- + +## 1. 系统架构 + +### 1.1 硬件架构 + +``` + ┌──────────────────────────────────┐ + 线圈 ────────────┤ PA7 (TIM3_CH2) AT32F421F8P7 │ + │ 输入捕获 Cortex-M4 ├──── PB1 (TMR14 PWM) ──── 红灯 + │ 120MHz / 64KB │ + DIP ×5 ─────────┤ PA0~PA4 (GPIO) ├──── PA9 (GPIO) ──────── 绿灯 + │ │ + RS485 ◄─────────┤ USART (外部 PHY) ├──── PA10 (GPIO) ─────── 黄灯 + │ │ + │ PA5 (GPIO) ──┼──── RLY2 继电器 + │ PA6 (GPIO) ──┼──── RLY1 继电器 + │ │ + │ SWD (PA13/PA14) ────────────────┼──── 调试接口 + └──────────────────────────────────┘ +``` + +### 1.2 软件架构 + +``` +FreeRTOS Kernel (CMSIS-RTOS v2) +├── loop_task (主检测任务) +│ ├── vd1_task() — 每 5ms tick 执行 +│ │ ├── IIR 滤波 (ALFA_CAP1 = 79/256) +│ │ ├── 基线跟踪 (100 窗口滑动平均) +│ │ ├── 进入/离开检测 +│ │ ├── 时序状态机 (IN/OUT/PULSE/HOLD) +│ │ └── 平坦性离开判定 (CN200910309382) +│ ├── poll_sw_state() — 拨码去抖 +│ ├── poll_green_led() — 绿灯驱动 +│ └── poll_yellow_led() — 黄灯故障编码 +├── TMR3_ISR() — 线圈频率捕获 +├── TMR15_ISR() — 5ms 系统 tick (LED 驱动) +└── TMR14_PWM() — 红灯呼吸 +``` + +--- + +## 2. 电气参数 + +| 参数 | 最小值 | 典型值 | 最大值 | 单位 | 备注 | +|------|--------|--------|--------|------|------| +| 供电电压 (VDD) | 10 | 12 / 24 | 30 | V | 宽压输入 | +| 功耗 | — | 0.5 | 2 | W | 含继电器吸合 | +| 工作温度 | -40 | — | +85 | °C | 工业级 | +| 存储温度 | -55 | — | +125 | °C | — | +| 线圈电感范围 | 50 | 200 | 1000 | μH | 超出范围可工作但精度下降 | +| 线圈频率范围 | 30 | 100 | 200 | kHz | — | +| 线圈 Q 值 | 5 | — | — | — | 过低导致振荡不稳定 | +| 继电器触点电压 | — | — | 250 | VAC | — | +| 继电器触点电流 | — | — | 3 | A | — | +| GPIO 输出电压 | 0 | 3.3 | 3.6 | V | CMOS 电平 | +| GPIO 输出电流 | — | — | 25 | mA | 单引脚最大 | +| ESD 防护 | ±2 | — | — | kV | HBM | + +--- + +## 3. IO 引脚分配 + +### 3.1 完整引脚表 + +| 引脚 | 标识 | 功能 | 方向 | 外设 | 初始状态 | 备注 | +|------|------|------|------|------|---------|------| +| PA0 | SA_1 | 灵敏度 bit0 | IN | GPIO, 上拉 | — | DIP 开关 | +| PA1 | SA_2 | 灵敏度 bit1 | IN | GPIO, 上拉 | — | DIP 开关 | +| PA2 | SW_3 | 存在/脉冲选择 | IN | GPIO, 上拉 | — | 0=存在, 1=脉冲 | +| PA3 | SW_4 | 延时使能 | IN | GPIO, 上拉 | — | 0=无, 1=2s | +| PA4 | SW_5 | 安全复位 | IN | GPIO, 上拉 | — | 1=复位 | +| PA5 | RLY2 | 继电器 2 | OUT | GPIO PP | 0 (开路) | 辅助输出 | +| PA6 | RLY1 | 继电器 1 | OUT | GPIO PP | 0 (开路) | 主输出 | +| **PA7** | **LP** | 线圈频率捕获 | IN | **TIM3_CH2** | — | **核心输入** | +| PA9 | LEDA | 绿灯 | OUT | GPIO PP | 0 (灭) | 有车/自检 | +| PA10 | LEDC | 黄灯 | OUT | GPIO PP | 0 (灭) | 故障诊断 | +| PB1 | LEDA_RED | 红灯 | ALT | TMR14_CH1 PWM | — | 呼吸灯 | +| PA13 | SWDIO | 调试数据 | I/O | SWD | — | 仅调试 | +| PA14 | SWCLK | 调试时钟 | IN | SWD | — | 仅调试 | + +### 3.2 拨码开关逻辑 + +```c +// DIP 开关读取与解码 +SENS = 3 - (sw & 0x03); +// SA_2:SA_1 = 11 → SENS = 0 (低灵敏) +// SA_2:SA_1 = 10 → SENS = 1 +// SA_2:SA_1 = 01 → SENS = 2 +// SA_2:SA_1 = 00 → SENS = 3 (最高灵敏) + +SET_PLUS = (sw >> 2) & 0x01; // PA2 = SW_3 +SET_DLY = (sw >> 3) & 0x01; // PA3 = SW_4 +SET_SAFE = (sw >> 4) & 0x01; // PA4 = SW_5 +``` + +**拨码去抖**:连续 5 次读取一致才生效(对齐 M1H 参考实现)。 + +--- + +## 4. 检测算法 + +### 4.1 频率测量 + +#### 4.1.1 硬件链路 + +DLD154V4B **不使用** CD4060 外部分频芯片。线圈直接驱动 PA7 (TIM3_CH2),利用 AT32F421 内置 TIM3 输入分频器 DIV_2 (÷2)。 + +| 对比项 | M1H/TLD-110 | DLD154V4B | +|--------|-------------|-----------| +| 外部分频 | CD4060 Pin5 (÷32) | **无(直连)** | +| MCU 内部分频 | 无 | TIM3 DIV_2 (÷2) | +| 总分频比 | ÷32 | **÷2** | +| 中断率 @100kHz | ~3.1k/s | **50k/s** | +| CPU 占用 @120MHz | — | < 3% | + +#### 4.1.2 捕获流程 + +``` +线圈边沿 → PA7 (TIM3_CH2) + │ + ▼ +TIM3 自由运行 (16-bit, 120MHz/DIV_2 = 60MHz 时钟) + └─ 每个边沿 → CH2 捕获 → 读 CCR2 + │ + ▼ +TMR3 ISR: + CCR2_now → 存为 CapThis + Xn = CapThis - CapLast (相邻边沿周期差) + 处理 16-bit 溢出: if (Xn & 0x8000) Xn += 0x10000 + CapLast = CapThis + │ + ▼ + LPCNT = MEASUREMENT_BASE / Xn (自适应窗口) + CapSum += Xn + CapCnt++ + │ + CapCnt >= LPCNT ? + YES → Value = CapSum (≈ MEASUREMENT_BASE) + CapCnt = CapSum = 0 + loop1_CAP_OK = 1 (通知 vd1_task) +``` + +#### 4.1.3 关键常量 + +```c +#define MEASUREMENT_BASE 131072 // 2^17 +#define g_input_div 2 // TIM3 DIV_2 +``` + +| 线圈频率 | Xn @DIV_2 | LPCNT | 测量窗口 | Value 范围 | +|---------|-----------|-------|---------|-----------| +| 50 kHz | 1200 | 109 | 2.2 ms | ~130800 | +| 100 kHz | 600 | 218 | 2.2 ms | ~130800 | +| 150 kHz | 400 | 328 | 2.2 ms | ~131200 | +| 200 kHz | 300 | 437 | 2.2 ms | ~131100 | + +> **设计要点**:LPCNT 自适应使不同频率下 Value 归一化到 ~131072,百分比阈值(灵敏度)直接适用,无需频率补偿。 + +#### 4.1.4 精度陷阱(已修复) + +旧代码存在 `<<6` 和 `>>6` 互相抵消的精度浪费: + +``` +旧: LPCNT = (32768 << 6) / Xn = 437 → 窗口 17.5ms + Value >>= 6 → 等效 7 样本精度 +新: LPCNT = 131072 / Xn = 27~54 → 窗口 ~1ms + 不做右移 → 全样本精度 +``` + +**改进效果**:响应速度提升 16 倍,精度保留全部采样信息。 + +### 4.2 IIR 滤波 + +```c +// α = Flt_Reg / 256 = 79 / 256 ≈ 0.3086 +if (Value > CAPVD) + CAPVD += ((Value - CAPVD) * 79) >> 8; +else + CAPVD -= ((CAPVD - Value) * 79) >> 8; +``` + +| 参数 | 值 | 说明 | +|------|-----|------| +| α | 79/256 ≈ 0.3086 | 指数平滑系数 | +| 响应速度 | ~3 次达 63% | ~15ms @5ms tick | +| 噪声抑制 | 良好 | 单次野值影响 < 31% | + +### 4.3 检测判据 + +#### 4.3.1 灵敏度表 + +```c +const uint16_t SensTable[4] = {216, 108, 36, 10}; // 进入阈值 +const uint16_t SensTable_1[4] = {108, 72, 18, 9}; // 离开阈值(滞回 ~50%) +``` + +| SENS | SensTable | 进入阈值 (×Origin/65536) | SensTable_1 | 离开阈值 (×Origin/65536) | +|------|-----------|-------------------------|-------------|-------------------------| +| 0 (低) | 216 | 0.33% | 108 | 0.16% | +| 1 | 108 | 0.16% | 72 | 0.11% | +| 2 | 36 | 0.055% | 18 | 0.027% | +| 3 (高) | 10 | 0.015% | 9 | 0.014% | + +#### 4.3.2 进入检测 + +```c +dlt_ORG = (Origin * SensTable[SENS]) >> 16; // /65536 +if (CAPVD > Origin + dlt_ORG) { + // 频率上升超过阈值 → 有车 + // 进入 IN_DELAY (500ms) 防抖 +} +``` + +> **注**:有车时线圈电感减小 → 频率上升 → CAPVD > Origin。公式为 `CAPVD > Origin + dlt_ORG`(判定上升量)。 + +#### 4.3.3 离开检测(滞回) + +##### 模式 1:简单防抖 (USE_FLATNESS_EXIT=0) + +```c +dlt_ORG = (Origin * SensTable_1[SENS]) >> 16; // 更小的离开阈值 +if (CAPVD < Origin + dlt_ORG) { + if (++cnt_release >= 3) { // 连续 3 次确认 + VD_FLAG = 0; FLAG_OUT = 1; + } +} else { + cnt_release = 0; // 回落立即重置 +} +``` + +##### 模式 2:平坦性判定 (USE_FLATNESS_EXIT=1) — 默认 + +基于专利 **CN200910309382**(中山大学),解决大车通行时频率多峰导致的多次误触发。 + +**算法架构:** + +``` +车辆到达 → 单一阈值法 (沿用 SensTable) + │ + ▼ Phase 1: g_exit_state = 0 (追踪第一上升坡面) + │ 追踪最大 |f'| 和 |f''| + │ 当 |f'| 连续 3 次 < SLOPE_FLAT_THRESH: + │ Δ2 = max_slope / K1 (一阶平坦阈值) + │ Δ3 = max_slope_rate / K2 (二阶平坦阈值) + │ g_exit_state = 1 + │ + ▼ Phase 2: g_exit_state = 1 (平坦性判定) + 三条件同时满足: + ① |f - f_b| < dlt_ORG (频率回归基频) + ② |f'| < Δ2 (一阶导数近零) + ③ |f''| < Δ3 (二阶导数近零) + │ + 连续 FLAT_CONFIRM_CNT(3) 次全部满足 → 车辆离开 +``` + +**参数表:** + +| 常量 | 值 | 含义 | +|------|-----|------| +| K1, K2 | 8 | 动态阈值除数(专利推荐值) | +| SLOPE_FLAT_THRESH | 100 | 斜率趋零判断阈值 | +| MIN_DELTA2 | 5 | Δ2 下限(防除数过小) | +| MIN_DELTA3 | 2 | Δ3 下限 | +| FLAT_CONFIRM_CNT | 3 | 平坦确认次数 | + +**整数化适配:** 专利原实现用 float(Hz 频率值),DLD154V4B 用 uint32 定点(Origin ≈ 131K)。导数计算用 int32 整数差分,阈值 /K1、/K2 做整数除法,精度足够。 + +### 4.4 基线跟踪 + +```c +// 有车时冻结,无车时 100 窗口滑动平均 +if (!VD_FLAG && !FLAG_OUT) { + if (CAPVD - Origin < dlt_ORG * 4) { // Origin 污染保护 + ORG_SUM += CAPVD; + if (++ORG_CNT >= 100) { + Origin = ORG_SUM / 100; + ORG_SUM = ORG_CNT = 0; + } + } else { + // 冻结:CAPVD 偏离 Origin 超过进入阈值的 4 倍 + ORG_SUM = ORG_CNT = 0; + } +} +``` + +| 设计决策 | 原因 | +|---------|------| +| 有车时冻结基线 | 防止把车辆的影响"学"进基线(仿 TLD-110) | +| 100 窗口跟踪 | 缓慢跟踪温漂,但不响应车辆 | +| 4× 冻结阈值 | 防止异常 CAPVD 上升污染基线(V1.5 新增) | + +### 4.5 Origin 污染保护(V1.5) + +**问题**:实测发现车辆驶入时 Xn 偶尔先增大再减小。无车状态下 Origin 跟踪上升被污染到虚高值,导致离开时 `|f - f_b|` 远超阈值 → 绿灯常亮、永远不释放。 + +**修复**:基线跟踪前增加保护条件: + +```c +// 仅当 CAPVD 偏离 Origin < dlt_ORG × 4 时才更新基线 +// 超出则冻结+重置累计 +if (CAPVD - Origin < dlt_ORG * 4) + update_moving_average(...); +else + freeze(); +``` + +| 场景 | Origin | CAPVD | dev | 4×阈值 | 结果 | +|------|--------|-------|-----|--------|------| +| 正常无车 | 127080 | 127081 | +1 | 276 | 跟踪 ✓ | +| 异常上升 | 127085 | 127884 | +799 | 276 | 冻结 ✓ | + +--- + +## 5. 时序状态机 + +### 5.1 状态转移 + +``` + IN_DELAY=10 OUT_DELAY=38 + [空闲] ──有车──→ [进入延时] ──超时──→ [有车确认] + ↑ │ + │ 车辆离开 + │ ↓ + └──脉冲结束───── [脉冲输出] ←──超时── [离开延时] + PULSE_DELAY=19 +``` + +### 5.2 时序参数 + +| 参数 | Tick (50ms) | 时间 | 说明 | +|------|------------|------|------| +| IN_DELAY | 10 | **500 ms** | 进入确认防抖 | +| OUT_DELAY | 38 | **1.9 s** | 离开确认防抖 | +| PULSE_DELAY | 19 | **950 ms** | 脉冲输出宽度 | +| HOLD_TIME | 5×1200 | **~5 min** | 有限存在超时 | +| LC_HOLD_TIME | 4×1200 | **~4 min** | 安全复位超时 | +| STABLE_SAMPLES | 128 tick | **~128 ms** | 上电稳定期 | + +### 5.3 系统 Tick 来源 + +TMR15 每 5ms 产生一次中断,`TM1cnt` 计数到 10 后触发 vd1_task(50ms 周期)。TMR15 ISR 同时驱动 LED。 + +--- + +## 6. 指示灯状态机 + +### 6.1 三 LED 驱动架构 + +``` +TMR15 ISR (每 5ms) +├── 红灯 PB1 — TMR14 PWM 呼吸(硬件自主,不需软件干预) +├── 绿灯 PA9 — poll_green_led() 每 tick 更新 +└── 黄灯 PA10 — poll_yellow_led() 每 tick 更新 +``` + +> **设计原则**:三 LED 由 TMR15 ISR 统一驱动,单点控制。vd1_task 只设标志位,ISR 据此刷新硬件。 + +### 6.2 绿灯行为表 + +```c +void poll_green_led(void) { + if (loop1_INI_LOOP || !g_loop_stable) { + // 自检 / 稳定期:慢闪 200ms + blink_200ms(); + } else if (g_disconnect_active) { + // 当前断开中:强制灭 + LEDA_OFF; + } else if (VD_FLAG || FLAG_IN || FLAG_OUT) { + // 有车 / 进入 / 离开延时中:亮 + LEDA_ON; + } else { + // 无车:灭 + LEDA_OFF; + } +} +``` + +### 6.3 黄灯行为表 + +| 条件 | 行为 | 参数 | 诊断含义 | +|------|------|------|---------| +| `g_disconnect_active == 1` | **快闪** | 200ms 亮 / 200ms 灭 | 线圈当前断开中 | +| `!g_loop_power_up_state` | **快闪** | 200ms 亮 / 200ms 灭 | 上电后从未连接线圈 | +| `g_disconnect_count == 1` | **1 短闪** | 80ms 亮 / 200ms 灭 → 1.2s 灭(循环) | 断开 1 次,已恢复 | +| `g_disconnect_count == 2` | **2 短闪** | 同上 | 断开 2 次 | +| `g_disconnect_count >= 3` | **3 短闪** | 同上 | 断开 3+ 次 | +| 正常 | **灭** | — | 一切正常 | + +```c +void poll_yellow_led(void) { + if (g_disconnect_active || !g_loop_power_up_state) + fast_blink_200ms(); // 断开中快闪 + else if (g_disconnect_count > 0) + n_short_flash(g_disconnect_count); // N 短闪编码 + else + led_off(); // 正常 +} +``` + +> **注意**:"上电后不接线,之后再接线圈"不计入断开次数(`g_loop_power_up_state` 控制)。只有已连接过的线圈断开才计入 `g_disconnect_count`。 + +--- + +## 7. 上电稳定期 + +### 7.1 背景 + +Origin 首次确立后,线圈振荡未真正稳定。立即启用检测容易误判为有车(绿灯常亮)。 + +### 7.2 实现 + +```c +#define STABLE_SAMPLES 128 // ~128ms + +if (!g_loop_stable) { + // 仅跟踪基线,不检测车辆 + update_moving_average(&ORG_SUM, &ORG_CNT, &Origin, CAPVD, 100); + if (++_stable_cnt >= STABLE_SAMPLES) + g_loop_stable = 1; // 稳定确认,正式启用检测 + return; // 跳过进入/离开判断 +} +``` + +稳定期间绿灯继续慢闪(`poll_green_led` 条件包含 `!g_loop_stable`)。 +安全复位时 `loop1_LC_Reset` 重置 `g_loop_stable = 0`。 + +--- + +## 8. 线圈重连逻辑 + +### 8.1 设计目标 + +断开时不丢 VD_FLAG(车辆仍在线圈上方),重连后快速收敛 IIR。 + +### 8.2 状态机 + +``` +断开检测: loop1_RF_FLAG == 0 (没有收到边沿) + ├─ loop1_LOOP_OK = 0 + ├─ g_disconnect_active = 1 + ├─ g_disconnect_count++ (≤3) + ├─ 保留 loop1_VD_FLAG ← 关键:不丢有车状态 + ├─ 关断继电器输出 + └─ 绿灯强制灭 + +重连检测: loop1_RF_FLAG == 1 (重新收到边沿) + ├─ loop1_LOOP_OK = 1 + ├─ g_disconnect_active = 0 + ├─ loop1_CAPVD = 0 ← 触发快速收敛 + └─ vd1_task: CAPVD == 0 → CAPVD = Value (直锁首个样本) +``` + +### 8.3 断开-重连场景矩阵 + +| 断开前 | 断开期间 | 重连后 | VD_FLAG | 绿灯 | 继电器 | +|--------|---------|--------|---------|------|--------| +| 有车 | 车仍在 | 车仍在 | 1 → 保持 | 恢复亮 | 恢复输出 | +| 有车 | 车离开 | 无车 | 1 → cnt_release→3 → 0 | 灭 | 释放 | +| 无车 | 车进入 | 有车 | 0 → CAPVD>Origin+dlt → 1 | 亮 | 吸合 | + +--- + +## 9. 通信协议 (RS485) + +### 9.1 物理层 + +| 参数 | 值 | +|------|-----| +| 接口 | RS485 半双工 | +| 波特率 | 9600(默认) | +| 数据位 | 8 | +| 停止位 | 1 | +| 校验 | 无 | +| 终端电阻 | 120Ω(外部) | + +### 9.2 协议格式 + +> 协议详细定义待后续版本补充。当前版本支持基本状态查询和灵敏度设置。 + +--- + +## 10. 故障检测 + +### 10.1 检测项 + +| 检测项 | 判定条件 | 触发动作 | +|--------|---------|---------| +| 线圈断开 | `loop1_RF_FLAG == 0` 持续 | 黄灯快闪 / 继电器释放 | +| 线圈短路 | Xn 持续为 0 或极小 | 黄灯快闪 / 继电器释放 | +| 频率过低 | Value 持续 < MIN_FREQ | 黄灯编码闪烁 | +| 频率过高 | Value 持续 > MAX_FREQ | 黄灯编码闪烁 | + +### 10.2 黄灯编码设计 + +断开次数编码提供了比 TLD-110 的均匀闪烁更丰富的诊断信息: +- **快闪=当前故障** → 现场立即处理 +- **N短闪=历史故障** → 判断是偶发还是持续问题 + +--- + +## 11. 代码架构 + +### 11.1 目录结构 + +``` +DLD154V4B/ +├── utilities/at32f421_freertos_demo/ +│ ├── src/ +│ │ └── TaskLoop.c # 主检测逻辑 (~868 行 V1.5) +│ ├── inc/ +│ │ └── TaskLoop.h # 全局变量和函数声明 +│ └── ... # FreeRTOS + HAL 框架 +├── docs/ +│ ├── product-manual.md # 产品手册 +│ ├── technical-spec.md # 本文档 +│ ├── devlog.md # 开发日志 +│ └── reference_analysis.md # M1H/TLD-110 参考分析 +└── README.md +``` + +### 11.2 代码精简历程 + +| 版本 | 代码量 | 说明 | +|------|--------|------| +| 原始 | ~1177 行 | 包含二阶滤波、FltHistoryManager 等死代码 | +| V1.1 | ~706 行 | 精简重构,-40% | +| V1.5 | ~868 行 | 增加平坦性判定、污染保护 | + +**删除的死代码:** +- 二阶差分滤波(计算但从未参与判决) +- FltHistoryManager(20+ 未用字段) +- StageRangeConfig(区间约束未引用) +- 动态窗口切换(LOOP_WINDOW_SIZE_LOW → FAST) +- 中间层时序状态(PLUSE_IN_F / PLUSE_IN) + +--- + +## 12. 性能基准 + +### 12.1 检测性能 + +| 指标 | 值 | 说明 | +|------|-----|------| +| 进入检测延迟 | < 3 ms (测量) + 500 ms (防抖) | 电信号延迟 | +| 离开检测延迟 | < 3 ms (测量) + 平坦性确认 + 1.9 s (防抖) | 含双重确认 | +| 误检率(单阈值) | — | 基准参考 | +| 误检率(平坦性) | 显著降低 | 大车多峰场景 | +| 频率分辨率 | < 0.01% | 取决于线圈 Q 值 | +| 温漂补偿 | 自动(100 窗口基线跟踪) | 仅无车时 | + +### 12.2 CPU 占用 + +| 任务 | 频率 | CPU 占用 @120MHz | 说明 | +|------|------|-----------------|------| +| TMR3 ISR (捕获) | 50k/s @100kHz | ~2.1% | 每边沿约 50 周期 | +| TMR15 ISR (tick) | 200/s | < 1% | LED + 计数 | +| vd1_task | 20/s | < 1% | 滤波 + 检测 | +| FreeRTOS 开销 | — | < 1% | 任务调度 | +| **总计** | — | **< 5%** | 余量充足 | + +### 12.3 RAM 占用 + +| 模块 | 大小 | 说明 | +|------|------|------| +| 全局检测变量 | ~100 B | 状态、计数、滤波值 | +| FreeRTOS 堆栈 | ~4 KB | 任务栈 + 系统堆 | +| 剩余 | ~11 KB | 可用于扩展功能 | + +--- + +## 13. 编译选项 + +```c +// TaskLoop.h + +#define USE_FLATNESS_EXIT 1 // 1 = 平坦性离开判定 (CN200910309382) + // 0 = 简单 cnt_release 防抖 +``` + +置 0 回退到传统 `cnt_release >= 3`,方便对比测试两种方案的差异。 + +--- + +## 14. 关键专利 + +| 专利号 | 名称 | 权利人 | 应用 | +|--------|------|--------|------| +| CN200910309382 | 一种防误检环形线圈车辆检测器 | 中山大学 张辉/黄永强/陈古典 | 平坦性三条件离开判定 | + +DLD154V4B V1.4 起实现该专利的整数化版本,用于大车通行时的离开判定,有效抑制频率曲线多峰导致的多次误触发。 + +--- + +## 15. 修订记录 + +| 版本 | 日期 | 说明 | +|------|------|------| +| V1.0 | 2026-06-24 | 技术规格书初版 |