Files
DLD110SV4B/docs/technical-spec.md

458 lines
16 KiB
Markdown
Raw Permalink 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.
# DLD110SV4 技术规格书
> 单路线圈蓝牙车辆检测器 | 固件版本: V4.31 | 文档版本: V1.0
> 本文档面向工程开发、系统集成及故障深度分析
---
## 1. 系统架构
### 1.1 硬件架构
```
┌──────────────────────────────────┐
线圈 ────────────┤ PA9 (TMR0) CH591R │
│ 输入捕获 RISC-V ├──── PA8 (GPIO) ──────── RLY1 功能继电器
│ 60MHz / 192KB │
调频电容 ×2 ────┤ PA12/PA13 (GPIO) ├──── PB23 (GPIO) ─────── RLY2 存在继电器
│ │
滑动开关 ×2 ────┤ PA14/PA15 (GPIO) ├──── PB22 (GPIO) ─────── LEDA 绿灯
│ │
BLE ────────────┤ 内置 2.4GHz RF ├──── 小程序配置 + OTA
└──────────────────────────────────┘
```
### 1.2 软件架构
```
主循环轮询 (无 RTOS)
├── TMR0 ISR — 线圈频率捕获 (FallEdge_To_FallEdge)
│ ├── Xn = TMR0_CAPGetData() (直接获取周期)
│ ├── LPCNT = 2^19 / Xn (自适应测量窗)
│ └── CapCnt >= LPCNT → Value = ΣXn, CAP_OK = 1
├── TMR1 ISR — 5ms 系统 tick (LED 驱动 + 50ms 状态机)
├── cjq_srv() — 主循环服务
│ ├── 线圈断开/重连检测
│ ├── CAP_OK → vd1_task() (核心检测算法, ~8.74ms 周期)
│ │ ├── IIR 滤波 (ALFA_CAP1=79/256, τ≈24ms)
│ │ ├── 斜率限幅 (MAX_SLOPE_RATE=5%)
│ │ ├── 基线跟踪 (500 窗口滑动平均, ~4.4s)
│ │ ├── 进入确认 (ENTRY_CONFIRM=3 次)
│ │ ├── 离开检测 (平坦性三条件 / cnt_release)
│ │ └── 冻结超时恢复 (~8.7s + ±2% 稳定性检查)
│ └── BLE 状态上报 (variation / frequent / car_state)
└── BLE 协议栈 — DBN 命令解析 + 传感器数据上报
```
---
## 2. 电气参数
| 参数 | 最小值 | 典型值 | 最大值 | 单位 | 备注 |
|------|--------|--------|--------|------|------|
| 供电电压 (VDD) | 3.0 | 3.3 | 3.6 | V | CH591R 内核电压 |
| 功耗 | — | 0.1 | 0.3 | W | BLE 广播 + 检测 |
| 工作温度 | -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 | 单引脚最大 |
| BLE 发射功率 | — | 0 | +3 | dBm | 可配置 |
| BLE 通信距离 | — | 30 | 100 | m | 无遮挡/有遮挡 |
---
## 3. IO 引脚分配
### 3.1 完整引脚表
| 引脚 | 标识 | 功能 | 方向 | 外设 | 初始状态 | 备注 |
|------|------|------|------|------|---------|------|
| **PA9** | **LP** | 线圈频率捕获 | IN | **TMR0** | — | **核心输入** |
| PA8 | RLY1 | 功能继电器 | OUT | GPIO PP | 0 (开路) | 存在/进入脉冲/离开脉冲 |
| PB23 | RLY2 | 存在继电器 | OUT | GPIO PP | 0 (开路) | 固定存在输出 |
| PB22 | LEDA | 绿灯 | OUT | GPIO PP | 0 (灭) | 有车/自检/故障指示 |
| PA12 | FLEVEL_H | 调频电容 33nF | OUT | GPIO PP | — | 0=接入, 1=断开 |
| PA13 | FLEVEL_L | 调频电容 10nF | OUT | GPIO PP | — | 0=接入, 1=断开 |
| PA14 | KEY_SA1 | 灵敏度 bit0 | IN | GPIO, 上拉 | — | 滑动开关 |
| PA15 | KEY_SA2 | 灵敏度 bit1 | IN | GPIO, 上拉 | — | 滑动开关 |
### 3.2 调频电容组合
| loopFreq_Level | FLEVEL_H (PA12) | FLEVEL_L (PA13) | 电容组合 | 说明 |
|----------------|-----------------|-----------------|---------|------|
| 0 (高频) | 0 | 0 | 33nF + 10nF | 总电容最大, 频率最低 |
| 1 (中高) | 0 | 1 | 33nF | — |
| 2 (中低) | 1 | 0 | 10nF | — |
| 3 (低频) | 1 | 1 | 0 | 无外加电容, 频率最高 |
> **注**:`0=接入电容`(低电平),`1=断开电容`(高电平)。调频档位由 BLE 配置参数 `loopFreq_Level` (1~4) 控制。
### 3.3 滑动开关编码
```c
// SA1/SA2 读取与解码 (与 DLD154V4B 一致)
SENS = 3 - (sw & 0x03);
// SA2:SA1 = 11 → SENS = 0 (低灵敏)
// SA2:SA1 = 10 → SENS = 1
// SA2:SA1 = 01 → SENS = 2
// SA2:SA1 = 00 → SENS = 3 (最高灵敏, BLE 灵敏度表)
```
附加灵敏度等级通过 BLE 配置 `g_loop_sens_list.sens[freq_level].sens_in/sens_out`,支持运行时覆盖。
---
## 4. 检测算法
### 4.1 频率测量
#### 4.1.1 硬件链路
DLD110SV4 使用 CH591R 内置 TMR0 输入捕获,直接捕获线圈振荡边沿周期(FallEdge_To_FallEdge)。
| 对比项 | DLD154V4B (AT32F421) | DLD110SV4 (CH591R) |
|--------|----------------------|---------------------|
| MCU | Cortex-M4 @120MHz | RISC-V @60MHz |
| 捕获外设 | TIM3_CH2 | TMR0 |
| 分频 | DIV_2 (÷2) | 无 |
| 捕获方式 | CapThis - CapLast 差分 | TMR0_CAPGetData() 直接返回 |
| 定时器宽度 | 16-bit | 16-bit |
#### 4.1.2 捕获流程
```
线圈边沿 → PA9 (TMR0)
TMR0 自由运行 (16-bit, 60MHz)
└─ FallEdge_To_FallEdge → TMR0_CAPGetData() → Xn
TMR0 ISR:
Xn == 0 → 除零保护, return
LPCNT = MEASUREMENT_BASE / Xn (自适应窗口)
if (LPCNT > 65535) return (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 524288L // 2^19
```
| 线圈频率 | Xn @60MHz | LPCNT | 测量窗口 | Value 范围 |
|---------|-----------|-------|---------|-----------|
| 50 kHz | 1200 | 437 | ~7.3 ms | ~524400 |
| 100 kHz | 600 | 874 | ~8.7 ms | ~524400 |
| 150 kHz | 400 | 1311 | ~8.7 ms | ~524400 |
| 200 kHz | 300 | 1748 | ~8.7 ms | ~524400 |
> **设计要点**:LPCNT 自适应使不同频率下 Value 归一化到 ~524288,百分比阈值(灵敏度)直接适用,无需频率补偿。
### 4.2 IIR 滤波
```c
#define ALFA_CAP1 79 // IIR α = 79/256 ≈ 0.31 (@8.74ms → τ≈24ms)
// get_flt_value(): 通用一阶 IIR
CAPVD = (|Value - CAPVD| * ALFA_CAP1) >> 8
```
| 参数 | 值 | 说明 |
|------|-----|------|
| α | 79/256 ≈ 0.31 | 指数平滑系数 |
| τ | ~24ms @8.74ms tick | 3 次更新达 63% |
| 噪声抑制 | 良好 | 单次野值影响 < 31% |
进入确认:CAPVD 连续 ENTRY_CONFIRM=3 次低于阈值才判定有车。
### 4.3 检测判据
#### 4.3.1 灵敏度表
灵敏度通过 BLE 配置的 `g_loop_sens_list` 表实现,支持 4 级频率档 × 多级灵敏度。滑动开关选择当前生效的灵敏度索引,BLE 可在线修改表值。
| SENS (滑动开关) | 进入阈值 (sens_in/65536) | 离开阈值 (sens_out/65536) | 典型频偏 |
|----------------|-------------------------|--------------------------|---------|
| 0 (低) | ~0.33% | ~0.16% | 大车/高底盘 |
| 1 (中) | ~0.16% | ~0.11% | 普通轿车 |
| 2 (高) | ~0.055% | ~0.027% | 摩托车/小轿车 |
#### 4.3.2 进入检测
```c
// CAPVD 连续 ENTRY_CONFIRM 次低于阈值才判定有车
dlt_ORG = (Origin * sens_in) >> 16;
if (CAPVD < Origin - dlt_ORG) {
entry_cnt++;
if (entry_cnt >= ENTRY_CONFIRM) { // 3 次连续确认
VD_FLAG = 1; FLAG_IN = 1;
entry_cnt = 0;
}
} else {
if (entry_cnt > 0) entry_cnt = 0;
}
```
| 参数 | 值 | 说明 |
|------|-----|------|
| ENTRY_CONFIRM | 3 | 连续确认次数 |
| 进入响应 | ~530ms | 3×8.74ms 确认 + 500ms IN_DELAY |
#### 4.3.3 离开检测(滞回)
##### 模式 1:简单防抖 (USE_FLATNESS_EXIT=0)
```c
dlt_ORG = (Origin * sens_out) >> 16;
if (CAPVD < Origin + dlt_ORG) {
if (++cnt_release >= 3) { VD_FLAG = 0; FLAG_OUT = 1; }
} else {
cnt_release = 0;
}
```
##### 模式 2:平坦性判定 (USE_FLATNESS_EXIT=1) — 默认
基于专利 **CN200910309382**(中山大学),解决大车通行时频率多峰导致的多次误触发。
**三条件判定**:频率回归基频 + 一阶导数近零 + 二阶导数近零,连续 FLAT_CONFIRM_CNT(3) 次全部满足。
| 常量 | 值 | 含义 |
|------|-----|------|
| SLOPE_FLAT_THRESH | 350 | 斜率趋零判断阈值 (幅值基准 2^19) |
| MIN_DELTA2 | 18 | Δ2 下限 |
| MIN_DELTA3 | 7 | Δ3 下限 |
| FLAT_CONFIRM_CNT | 3 | 平坦确认次数 |
### 4.4 基线跟踪
#### 4.4.1 斜率限幅
```c
#define MAX_SLOPE_RATE 5 // 单次最大变化 5%
int32_t raw_delta = Value - CAPVD;
int32_t max_step = CAPVD * MAX_SLOPE_RATE / 100;
if (max_step < 100) max_step = 100; // 最小限幅,防止低 Origin 时锁死
if (raw_delta > max_step) raw_delta = max_step;
if (raw_delta < -max_step) raw_delta = -max_step;
CAPVD = get_flt_value(CAPVD + raw_delta, CAPVD);
```
EMI/闪电等瞬态干扰被截断,真实车辆信号不受影响。
#### 4.4.2 基线更新速率(两阶段)
| 阶段 | 窗口 | 周期 | 用途 |
|------|------|------|------|
| 稳定期 (`!g_loop_stable`) | 100 | **~0.9s** | 绕过 IIR/限幅,快速收敛 |
| 正常运行 | 500 (WINDOW_ORIGIN) | **~4.4s** | 强噪声抑制,稳定跟踪 |
#### 4.4.3 冻结超时恢复
| 常量 | 值 | 说明 |
|------|-----|------|
| 冻结触发阈值 | dlt_ORG × 4 | CAPVD 偏离 Origin 的倍数 |
| FREEZE_TIMEOUT | 1000 | ~8.7s @8.74ms/tick |
| FREEZE_STABILITY_RATE | 2 | 稳定性窗口:参考值的 ±2% |
---
## 5. 时序状态机
### 5.1 时序参数
| 参数 | 50ms Tick 数 | 时间 | 说明 |
|------|-------------|------|------|
| IN_DELAY | 10 | **500 ms** | 进入确认防抖 |
| OUT_DELAY | 由 delay_time 配置 | 100ms × delay_time | 离开延时(可配) |
| PULSE_DELAY | 10 | **500 ms** | 脉冲输出宽度 |
| HOLD_TIME | 由 exist_mode 配置 | 30s × exist_mode | 有限存在超时 |
| STABLE_SAMPLES | 128 窗 | **~1.1 s** | 上电稳定期 |
| FREEZE_TIMEOUT | 1000 窗 | **~8.7 s** | 基线冻结超时 |
### 5.2 系统 Tick 来源
TMR1 每 5ms 产生一次中断。`TM1cnt` 计数到 10 后执行 50ms 状态机(进入/离开/脉冲标志处理 + 继电器时序)。
---
## 6. 线圈重连逻辑
### 6.1 设计目标
断开时不丢 VD_FLAG(车辆仍在线圈上方),重连后 CAPVD=0 触发首个样本直锁快速收敛。
### 6.2 状态机
```
断开检测: loop1_RF_FLAG == 0 (没有收到边沿)
├─ loop1_LOOP_OK = 0
├─ g_disconnect_active = 1
├─ g_loop_cut_amount++ (≤3)
├─ 保留 loop1_VD_FLAG ← 关键:不丢有车状态
├─ 关断继电器输出
└─ LEDA 200ms 快闪
重连检测: loop1_RF_FLAG == 1 (重新收到边沿)
├─ loop1_LOOP_OK = 1
├─ g_disconnect_active = 0
├─ loop1_CAPVD = 0 ← 触发快速收敛
└─ vd1_task: CAPVD == 0 → CAPVD = Value (直锁首个样本)
```
### 6.3 断开-重连场景矩阵
| 断开前 | 断开期间 | 重连后 | VD_FLAG | LEDA | 继电器 |
|--------|---------|--------|---------|------|--------|
| 有车 | 车仍在 | 车仍在 | 1 → 保持 | 正常 | 恢复输出 |
| 有车 | 车离开 | 无车 | 1 → cnt_release→3 → 0 | 灭 | 释放 |
| 无车 | 车进入 | 有车 | 0 → entry→3 → 1 | 亮 | 吸合 |
---
## 7. 指示灯状态机
### 7.1 LEDA (绿灯) 行为表
DLD110SV4 仅有一个绿色 LEDA (PB22),承担自检、有车指示、故障诊断三重功能。
| 条件 | 行为 | 含义 |
|------|------|------|
| `g_disconnect_active == 1` | **200ms 快闪** | 线圈当前断开中 |
| `!g_loop_power_up_state` | **200ms 快闪** | 上电后从未连接线圈 |
| `!g_loop_stable` | **200ms 慢闪** | 稳定期中(自检) |
| `VD_FLAG == 1` (有车) | **常亮** | 有车检测中 |
| 正常运行,无车 | **灭** | 一切正常 |
> **注意**:有车常亮优先级最高,覆盖闪烁状态。
---
## 8. BLE 协议接口
### 8.1 DBN BLE 协议
DLD110SV4 通过 BLE GATT 与小程序通信,协议基于 DBN (Device Binary Notification) 框架。
- **服务 UUID**: `0xFFE0`
- **通知 Characteristic**: `0xFFE1` (NOTIFY)
- **写入 Characteristic**: `0xFFE2` (WRITE_NO_RESPONSE)
- **Magic Byte**: `0x7F`
- **帧格式**: Magic(1) + Len(1) + Cmd(1) + Sub(1) + Value(LEN) + XOR(1) + SUM(1)
### 8.2 传感器数据上报
通过 `CMD_SUB_SENS_REPORT` 主动上报线圈动态信息:
| 字段 | 字节 | 说明 |
|------|------|------|
| loop_state | 1 | 线圈状态 |
| cut_amount | 3 | 累计断开次数(上电持续累计,不截断;上电未连时为 1) |
| frequent | 3 | 实时频率 (Hz), 小端序 |
| variation | **3** | Origin CAPVD, 有符号 int24, 小端序 |
> **V4.20 变更**`variation` 从 2B 升级为 3B 有符号(int24),范围 ±8,388,607,完整覆盖 2^19 幅值基准。旧版 2B 无符号 ±32767 截断已废弃。
> **V4.31 变更**:① 0x24 读参响应追加偏移 8-10 = LOOP_MEASURE_BASE3B LE = 524288),供第三方 variation 归一化换算 ΔL/L`ΔL/L ≈ -2×variation/LOOP_MEASURE_BASE`);② 线圈断开次数改为**上电后持续累计**`g_loop_cut_total`,不截断),LED 快闪仍用 3 次上限(`g_loop_cut_amount`);③ 恢复重连时 `g_loop_cut_last = 0` 边沿记忆同步(修复第二次断开不计数)。
### 8.3 可配置参数
通过 BLE 读写命令配置:
| 参数 | 说明 | 范围 |
|------|------|------|
| sensitvity | 灵敏度索引 | 0~15 |
| delay_time | 离开延时 | 0~255 (×100ms) |
| output_mode | 输出模式 | 0=存在, 1=进入脉冲, 2=离开脉冲 |
| direction_mode | 方向模式 | — |
| loopFreq_Level | 频率档位 | 1~4 |
| loopSafe_Timeout | 安全复位超时 | 0=关闭, >0=超时秒数 |
| exist_mode | 有限存在 | 0=无限, >0=超时×30s |
---
## 9. 编译选项
```c
// peripheral_main.c
#define USE_FLATNESS_EXIT 1 // 1 = 平坦性离开判定 (CN200910309382)
// 0 = 简单 cnt_release 防抖
// 算法参数
#define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5%
#define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值
#define FREEZE_TIMEOUT 1000 // 冻结超时: ~8.7s @8.74ms/tick
#define FREEZE_STABILITY_RATE 2 // 稳定性窗口: 参考值的 ±2%
```
---
## 10. 关键专利
| 专利号 | 名称 | 权利人 | 应用 |
|--------|------|--------|------|
| CN200910309382 | 一种防误检环形线圈车辆检测器 | 中山大学 张辉/黄永强/陈古典 | 平坦性三条件离开判定 |
DLD110SV4 自 V2.0 起实现该专利的整数化版本,用于大车通行时的离开判定。
---
## 11. 代码架构
### 11.1 目录结构
```
DLD110SV4/
├── BLE/DLD110S_Peripheral_28K/APP/
│ ├── peripheral_main.c # 主流程 + 检测算法 + TMR0/TMR1 ISR
│ ├── dbn_ble_srv.c # DBN BLE 协议服务
│ ├── peripheral.c # BLE 外设角色管理
│ └── storage.c # 参数存储 (EEPROM)
├── BLE/HAL/ # MCU / RTC / KEY / LED 驱动
├── BLE/LIB/ # CH59x BLE ROM 库
├── SRC/ # 标准外设驱动 + RISC-V 启动
├── docs/ # 技术文档
└── tools/ # 辅助工具
```
### 11.2 与 DLD154V4B 的主要差异
| 项目 | DLD154V4B | DLD110SV4 |
|------|-----------|-----------|
| MCU | AT32F421 (Cortex-M4) | CH591R (RISC-V) |
| 主频 | 120 MHz | 60 MHz |
| MEASUREMENT_BASE | 131072 (2^17) | 524288 (2^19) |
| 有效 tick | 10ms (FreeRTOS) | ~8.74ms (主循环) |
| 配置方式 | DIP 开关 | BLE 小程序 + 滑动开关(灵敏度) |
| 指示灯 | 红/绿/黄 三色 | 单绿灯 LEDA |
| 对外接口 | TTL Tx | BLE |
| 定时器 | TIM3 + TIM15 | TMR0 + TMR1 |
| RTOS | FreeRTOS | 无 (主循环轮询) |
| 捕获方式 | CapThis - CapLast 差分 | TMR0_CAPGetData() 直接获取 |
---
## 12. 修订记录
| 版本 | 日期 | 说明 |
|------|------|------|
| V1.0 | 2026-07-20 | 技术规格书初版 (固件 V4.20) |
| V1.1 | 2026-08-26 | 同步固件 V4.31LOOP_MEASURE_BASE、断开次数持续累计、cut_amount 字段语义更新 |
> **产品手册**(安装指南、故障排查、使用说明等)请参阅 [产品手册](product-manual.md)