diff --git a/utilities/at32f421_freertos_demo/inc/TaskLoop.h b/utilities/at32f421_freertos_demo/inc/TaskLoop.h index f07de2f..cb1b73b 100644 --- a/utilities/at32f421_freertos_demo/inc/TaskLoop.h +++ b/utilities/at32f421_freertos_demo/inc/TaskLoop.h @@ -38,6 +38,7 @@ #define ALFA_FAST 128 // 快速 IIR α = 128/256 = 0.5 (@10ms → τ≈28ms, 用于检测) #define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% (物理限制, 拒绝 EMI 尖峰) #define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车 +#define FREEZE_TIMEOUT 3000 // 基线冻结超时: ~30s @ 10ms/tick, 持续偏高后强制更新基线 /*=========================================================================== * 离开检测模式 @@ -103,6 +104,7 @@ extern uint8_t loop1_cnt_release; // 离开防抖计数 /* M4 优化: 快速 IIR + 进入确认 */ extern uint32_t loop1_CAPVD_fast; // 快速 IIR 值 (α=0.5, τ≈28ms, 用于检测) extern uint8_t loop1_entry_cnt; // 进入确认计数 +extern uint16_t loop1_freeze_cnt; // 基线冻结持续计数(超时后强制更新 Origin) #if USE_FLATNESS_EXIT extern uint8_t g_exit_state; // 离开检测: 0=追踪斜率, 1=等待平坦 extern uint16_t g_max_slope; // 第一上升坡面最大 |f'| diff --git a/utilities/at32f421_freertos_demo/src/TaskLoop.c b/utilities/at32f421_freertos_demo/src/TaskLoop.c index 2cb90a0..f6d2828 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -39,6 +39,7 @@ uint8_t Flt_Reg; /* M4 优化: 快速 IIR + 进入确认 */ uint32_t loop1_CAPVD_fast; uint8_t loop1_entry_cnt; +uint16_t loop1_freeze_cnt; /*=========================================================================== * 全局状态变量 — 标志位 @@ -342,6 +343,7 @@ void INIT_VD(void) /* M4 优化: 快速 IIR + 进入确认 */ loop1_CAPVD_fast = 0; loop1_entry_cnt = 0; + loop1_freeze_cnt = 0; #if USE_FLATNESS_EXIT g_exit_state = 0; g_max_slope = 0; @@ -699,13 +701,25 @@ void vd1_task(void) { int32_t dev = (int32_t)loop1_CAPVD - (int32_t)loop1_Origin; if (dev < (int32_t)(loop1_dlt_ORG * 4)) { - /* CAPVD 未显著高于基线 → 安全跟踪 */ + /* CAPVD 未显著高于基线 → 安全跟踪,重置冻结计数 */ + loop1_freeze_cnt = 0; update_moving_average(&loop1_ORG_SUM, &loop1_ORG_CNT, &loop1_Origin, loop1_CAPVD, 100); } else { - /* CAPVD 异常偏高 → 冻结跟踪,重置累计 */ - loop1_ORG_CNT = 0; - loop1_ORG_SUM = 0; + /* CAPVD 异常偏高 → 冻结跟踪 */ + loop1_freeze_cnt++; + if (loop1_freeze_cnt >= FREEZE_TIMEOUT) { + /* 超时: CAPVD 持续偏高但稳定 → 可能是环境变化,强制更新基线 */ + loop1_Origin = loop1_CAPVD; + loop1_freeze_cnt = 0; + loop1_ORG_CNT = 0; + loop1_ORG_SUM = 0; + PRINT("Baseline timeout update, new Origin:%d\\n", loop1_Origin); + } else { + /* 未超时: 保持冻结,重置累计(防止突然解冻时旧数据污染) */ + loop1_ORG_CNT = 0; + loop1_ORG_SUM = 0; + } } } @@ -722,6 +736,7 @@ void vd1_task(void) loop1_VD_FLAG = 1; loop1_FLAG_IN = 1; loop1_entry_cnt = 0; + loop1_freeze_cnt = 0; // 入场时重置冻结计数 /* 有限存在计时(非安全复位模式下) */ if (!SET_SAFE) {