Files
DLD154V4B/docs/technical-spec.md

630 lines
21 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.
# 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) ──────── 绿灯
│ │
Tx ─────────────┤ USART (TTL) ├──── 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=500ms |
| 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 | 平坦确认次数 |
**整数化适配:** 专利原实现用 floatHz 频率值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.4.1 更新速率
`vd1_task` 每 50msTMR15 5ms×10执行一次。空闲时每次累加 CAPVD 到 `ORG_SUM`,满 100 次后取平均更新 Origin
```
100 样本 × 50ms/tick = 5000ms = 5 秒
```
| 产品 | 窗口大小 | 更新周期 | 空闲时跟踪 | 有车时冻结 |
|------|---------|---------|-----------|-----------|
| **DLD154V4B** | 100 次 | **5000ms** | ✅ | ✅ |
| **M1H** | 100 次 | **5000ms** | ✅ | ❌(有车也跟踪) |
| **TLD-110** | 16 次 | **~800ms** | ✅ | ✅ |
**关键差异:**
- **DLD154V4B vs M1H**:同为 100 窗口 5s但 DLD154V4B 有车时冻结基线。M1H 有车也跟踪的风险——长时间有车会把频率偏移"学"进基线,安全性不如冻结方案。
- **TLD-110 最快**16 次累积 ~800ms 完成一次更新,有车冻结 + 小窗口快跟踪,对温漂响应最敏捷。但 16 样本窗口的抗噪能力弱于 100 窗口。
- DLD154V4B 的 100 窗口 5s 取 M1H 的窗口大小 + TLD-110 的冻结策略Origin 更稳定但温漂跟踪慢于 TLD-110。
- 注意TMR3 ISR 在 50ms 间隙内可能完成多次测量窗口(每次 ~1ms但 vd1_task 只取最新一个 Value 做 IIR基线更新速率受 vd1_task 的 50ms tick 限制,与测量窗口大小无关。
### 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=10
[空闲] ──有车──→ [进入延时] ──超时──→ [有车确认]
↑ │
│ 车辆离开 (+ SW_4离开延时)
│ ↓
└──脉冲结束───── [脉冲输出] ←──超时── [离开延时]
PULSE_DELAY=10
```
### 5.2 时序参数
| 参数 | Tick (50ms) | 时间 | 说明 |
|------|------------|------|------|
| IN_DELAY | 10 | **500 ms** | 进入确认防抖 |
| OUT_DELAY | 10 | **500 ms** | 离开防抖(仅 SW_4=ON 时生效OFF 时为 0 |
| PULSE_DELAY | 10 | **500 ms** | 脉冲输出宽度 |
| HOLD_TIME | 5×1200 | **~5 min** | 有限存在超时 |
| LC_HOLD_TIME | 4×1200 | **~4 min** | 安全复位超时 |
| STABLE_SAMPLES | 128 tick | **~128 ms** | 上电稳定期 |
> **SW_4 离开延时**SW_4=ON 时OUT_DELAY=500msSW_4=OFF 时,离开延时为 0FLAG_OUT 立即切换到 FLAG_PLUSE。PULSE_DELAY 固定 500ms不受 SW_4 影响。
### 5.3 系统 Tick 来源
TMR15 每 5ms 产生一次中断,`TM1cnt` 计数到 10 后触发 vd1_task50ms 周期。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. 调试接口 (TTL Tx)
### 9.1 物理层
| 参数 | 值 |
|------|-----|
| 接口 | TTL 电平 UART Tx |
| 电平 | 3.3V CMOS |
| 波特率 | 9600默认 |
| 数据位 | 8 |
| 停止位 | 1 |
| 校验 | 无 |
| 用途 | 调试信息输出(频率、状态、标志位) |
### 9.2 数据格式
> 调试输出内容待后续版本补充。当前版本可通过 TTL 串口输出检测状态和原始频率值,用于开发调试和现场调参。
---
## 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 行 | 增加平坦性判定、污染保护 |
**删除的死代码:**
- 二阶差分滤波(计算但从未参与判决)
- FltHistoryManager20+ 未用字段)
- 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 | 技术规格书初版 |