From 278d470b60e024a7b51c0e43a6c56e6c485c2a9b Mon Sep 17 00:00:00 2001 From: wangfq Date: Wed, 2 Sep 2026 09:49:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(V4B):=20Debug=E4=B8=B2=E5=8F=A3=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E9=87=8D=E7=BB=84=20=E2=80=94=20=E9=A2=91=E7=8E=87/?= =?UTF-8?q?=E9=87=87=E6=A0=B7/=E5=9F=BA=E5=87=86=E5=85=A8=E9=87=8F?= =?UTF-8?q?=E8=BE=93=E5=87=BA=20(V4.20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现场有影响算法的异常待分析, 扩充调试输出: 1. 周期状态行(2s, DBG|前缀): f频率kHz/Xn/LPCNT/Value/CAPVD/slow/Origin/dlt/SENS/VD/FRZ/LIM/LOOP/STBL - calc_freq_khz(): f=60000×LPCNT/CAPVD (60MHz捕获时钟, 无车≈99kHz/深车124kHz验证✓) - g_slope_limit_cnt: 斜率限幅截断计数(EMI线索, 周期清零) 2. 事件行(EVT|前缀): enter_try(进入线首中)/leave_try(离开线首中)/loop_disconnect/loop_reconnect - 原有 Car_In/Car_OFF/Loop stable/Baseline timeout 保留 3. cmcng.h 新增 DEBUG_ENABLE 开关(1=开现场分析 0=关发布) 文档: devlog V2.18 --- docs/devlog.md | 45 +++++++++++++++ utilities/at32f421_freertos_demo/inc/cmcng.h | 8 +++ .../at32f421_freertos_demo/src/TaskLoop.c | 57 ++++++++++++++++--- 3 files changed, 103 insertions(+), 7 deletions(-) diff --git a/docs/devlog.md b/docs/devlog.md index 7a4296d..d3b49b8 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -4,6 +4,51 @@ --- +## 2026-09-01 — Debug 串口打印重组:频率/采样/基准全量输出(固件 V4.20) + +> **固件版本:V4.20**。devlog 修订 V2.18。 +> **目的**:现场有影响算法的异常情况待分析,扩充调试输出便于定位。 + +### 打印内容(TTL 调试口,波特率 230400) + +**① 周期状态行(每 2s,前缀 `DBG|`)**——频率/采样/基准全量: +``` +DBG|t=2000ms f=99kHz Xn=600 LPCNT=218 Value=131072 CAPVD=131072 slow=131072 Origin=131072 dlt=32 SENS=3 VD=0 FRZ=0/0 LIM=0 LOOP=1 STBL=1 +``` +| 字段 | 含义 | +|------|------| +| f | 线圈振荡频率 kHz(=60000×LPCNT/CAPVD,无车≈100) | +| Xn / LPCNT | 瞬时周期 / 自适应窗口 | +| Value / CAPVD / slow | 原始采样 / 主滤波 / 慢滤波(方案A) | +| Origin / dlt | 基准值 / 当前阈值(无车=进入线,有车=释放线) | +| SENS / VD | 灵敏度档 / 车辆状态 | +| FRZ | freeze_cnt / freeze_ref(基线冻结状态) | +| LIM | 斜率限幅截断计数(2s 内 EMI/干扰次数,周期清零) | +| LOOP / STBL | 线圈状态 / 稳定期标志 | + +**② 事件行(前缀 `EVT|`)**: +- `enter_try`:进入线第一次命中(定位触发来源) +- `leave_try`:离开线第一次命中(定位释放来源) +- `loop_disconnect` / `loop_reconnect`:线圈断开/重连(带断开计数、断开瞬间 Xn/CAPVD/Origin/频率) +- 原有 `Car_In`/`Car_OFF`/`Loop stable`/`Baseline timeout`/`SENS changed` 保留 + +**③ 调试开关**(cmcng.h): +```c +#define DEBUG_ENABLE 1 // 1=开启(现场分析) 0=关闭(发布) +``` + +### 辅助实现 + +- `calc_freq_khz(capvd, lp_cnt)`:f_kHz = 60000×LPCNT/CAPVD(60MHz 捕获时钟),验证:无车 99kHz / 深车 124kHz ✓ +- `g_slope_limit_cnt`:斜率限幅截断计数(IIR 输入被 5% 限幅截断时 +1,周期打印带出后清零) + +### 待办 + +- 现场抓数:串口 230400 收 `DBG|`/`EVT|` 行,异常复现时完整记录(至少覆盖异常前后 30s) +- 分析:重点看 f 是否突变(线圈/干扰)、Origin 是否异常更新(freeze 误触发)、LIM 是否高频(EMI) + +--- + ## 2026-09-01 — 方案B 调校定稿:发布版本号 V4.20 > **固件版本:V4.20**(cmcng.h:FIRMWARE_VER="4.20" + MAIN=4/SUB=20)。devlog 修订 V2.17。 diff --git a/utilities/at32f421_freertos_demo/inc/cmcng.h b/utilities/at32f421_freertos_demo/inc/cmcng.h index ffc9353..fa733b8 100644 --- a/utilities/at32f421_freertos_demo/inc/cmcng.h +++ b/utilities/at32f421_freertos_demo/inc/cmcng.h @@ -26,6 +26,14 @@ #include +#ifndef DEBUG_ENABLE +#define DEBUG_ENABLE 1 // 1=Դڴӡ(ֳ) 0=ر(), V4.20 +#endif +#if DEBUG_ENABLE +#ifndef DEBUG +#define DEBUG +#endif +#endif #ifdef DEBUG #define PRINT(X...) printf(X) #else diff --git a/utilities/at32f421_freertos_demo/src/TaskLoop.c b/utilities/at32f421_freertos_demo/src/TaskLoop.c index b8f30fb..9c95796 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -681,6 +681,22 @@ void TMR15_GLOBAL_IRQHandler(void) } } +/*=========================================================================== + * 调试打印辅助 — V4.20 debug 打印重组 (2026-09-01) + * + * calc_freq_khz: 由窗口量反算线圈振荡频率 + * f = 捕获时钟(60MHz) / Xn_avg, Xn_avg = CAPVD / LPCNT + * → f_kHz = 60000 × LPCNT / CAPVD + * 无车: CAPVD≈131072, LPCNT≈218 → ≈99.8kHz; 有车: Xn↓ → f↑ + *===========================================================================*/ +uint32_t g_slope_limit_cnt = 0; // 斜率限幅截断计数 (EMI/干扰线索, 周期打印带出) + +static uint32_t calc_freq_khz(uint32_t capvd, uint16_t lp_cnt) +{ + if (capvd == 0) return 0; + return (60000UL * lp_cnt) / capvd; +} + /*=========================================================================== * vd1_task — 核心检测算法(对齐 M1H VD1_TASK) * @@ -710,8 +726,8 @@ void vd1_task(void) int32_t raw_delta = (int32_t)loop1_Value - (int32_t)loop1_CAPVD; int32_t max_step = (int32_t)(loop1_CAPVD * MAX_SLOPE_RATE / 100); if (max_step < 100) max_step = 100; - if (raw_delta > max_step) raw_delta = max_step; - if (raw_delta < -max_step) raw_delta = -max_step; + if (raw_delta > max_step) { raw_delta = max_step; g_slope_limit_cnt++; } + if (raw_delta < -max_step) { raw_delta = -max_step; g_slope_limit_cnt++; } uint32_t clamped_value = (uint32_t)((int32_t)loop1_CAPVD + raw_delta); loop1_CAPVD = get_flt_value(clamped_value, loop1_CAPVD); } @@ -784,6 +800,12 @@ void vd1_task(void) /*--- 进入确认 — 连续 ENTRY_CONFIRM 次低于阈值才判有车 ---*/ if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG)) { + if (loop1_entry_cnt == 0) { + /* 过渡事件: 第一次命中进入线 (定位"为什么开始进入") */ + PRINT("EVT|enter_try Value:%d CAPVD:%d Origin:%d dlt:%d f:%dkHz LPCNT:%d Xn:%d\n", + loop1_Value, loop1_CAPVD, loop1_Origin, loop1_dlt_ORG, + calc_freq_khz(loop1_CAPVD, loop1_LPCNT), loop1_LPCNT, loop1_Xn); + } loop1_entry_cnt++; if (loop1_entry_cnt >= ENTRY_CONFIRM) { PRINT("Car_In, Value:%d, CAPVD:%d, Origin:%d, dlt:%d\\n", @@ -899,6 +921,18 @@ void vd1_task(void) #else if ((loop1_Origin - loop1_dlt_ORG) < loop1_CAPVD) { // 方案B/原逻辑: 快滤波直接判释放 #endif + if (loop1_cnt_release == 0) { + /* 过渡事件: 第一次命中离开线 (定位"为什么开始释放") */ + PRINT("EVT|leave_try Value:%d CAPVD:%d slow:%d Origin:%d dlt:%d f:%dkHz LPCNT:%d Xn:%d\n", + loop1_Value, loop1_CAPVD, +#if USE_SLOW_RELEASE + loop1_CAPVD_slow, +#else + loop1_CAPVD, +#endif + loop1_Origin, loop1_dlt_ORG, + calc_freq_khz(loop1_CAPVD, loop1_LPCNT), loop1_LPCNT, loop1_Xn); + } loop1_cnt_release++; if (loop1_cnt_release >= 3) { PRINT("Car_OFF, Value:%d CAPVD:%d Origin:%d dlt:%d\n", @@ -936,6 +970,7 @@ void loop_task_function(void *pvParameters) g_disconnect_active = 0; // 重连,清除断开标记 loop1_CAPVD = 0; // 强制 IIR 从首个有效值重新收敛 loop1_CAPVD_slow = 0; // 方案A: 释放慢滤波同步收敛 + PRINT("EVT|loop_reconnect\n"); } if (loop1_CAP_OK) { @@ -971,22 +1006,30 @@ void loop_task_function(void *pvParameters) } g_fault_phase = 0; g_fault_tick = 0; + PRINT("EVT|loop_disconnect cnt=%d Xn:%d CAPVD:%d Origin:%d f:%dkHz\n", + g_disconnect_count, loop1_Xn, loop1_CAPVD, loop1_Origin, + calc_freq_khz(loop1_CAPVD, loop1_LPCNT)); } vTaskDelay(150); } - /*--- 调试输出(每 2 秒) ---*/ + /*--- 调试输出(每 2 秒): V4.20 重组 — 频率/采样/基准全量状态 ---*/ #ifdef DEBUG { static uint32_t _dbg_cnt = 0; _dbg_cnt++; if (_dbg_cnt >= 200) { // 200 × 10ms = 2s _dbg_cnt = 0; - PRINT("SET_DLY:%d, SAFE:%d, Xn:%d, LPCNT:%d, " - "CAPVD:%d, Origin:%d, VD:%d\n", - SET_DLY, SET_SAFE, loop1_Xn, loop1_LPCNT, - loop1_CAPVD, loop1_Origin, loop1_VD_FLAG); + PRINT("DBG|t=%ums f=%dkHz Xn=%d LPCNT=%d Value=%d CAPVD=%d slow=%d " + "Origin=%d dlt=%d SENS=%d VD=%d FRZ=%d/%d LIM=%d LOOP=%d STBL=%d\n", + _dbg_cnt * 10, + calc_freq_khz(loop1_CAPVD, loop1_LPCNT), + loop1_Xn, loop1_LPCNT, loop1_Value, loop1_CAPVD, loop1_CAPVD_slow, + loop1_Origin, loop1_dlt_ORG, loop1_SensLevel, loop1_VD_FLAG, + loop1_freeze_cnt, loop1_freeze_ref, g_slope_limit_cnt, + loop1_LOOP_OK, g_loop_stable); + g_slope_limit_cnt = 0; // 限幅计数按周期清 (统计最近 2s) } } #endif