/** ************************************************************************** * @file TaskLoop.h * @version v2.0 * @date 2025-09-08 (original), 2026-06-25 (rewrite: DLD154V4B algo × 4ch) * @brief 四路线圈检测 — 移植自 DLD154V4B 算法 * * 算法来源: DLD154V4B vd1_task() + 平坦性离开 (CN200910309382) * 改动: 单路全局变量 → Loop154_Unit 结构体数组,四路独立 ************************************************************************** */ #ifndef __TASKLOOP_H__ #define __TASKLOOP_H__ #include #include /*=========================================================================== * 时序参数(每 tick = 50ms,由 TMR15 5ms×10 产生) * 主循环: vTaskDelay(10ms), M4 优化 *===========================================================================*/ #define HOLD_TIME (5 * 1200) // 有限存在保持(约 5 分钟) #define LC_HOLD_TIME (4 * 1200) // 安全复位时间(约 4 分钟) #define IN_DELAY 10 // 进入防抖 500ms #define OUT_DELAY 10 // 离开防抖 500ms #define PULSE_DELAY 10 // 脉冲宽度 500ms /*=========================================================================== * 滤波参数 — M4 优化版 (V2.0+) * tick 提升到 10ms,滤波系数同步调整,保持等效时间常数 *===========================================================================*/ #define ALFA_CAP1 79 // IIR α = 79/256 ≈ 0.31 (@10ms → τ≈32ms) #define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% #define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值 #define STABLE_SAMPLES 128 // 稳定期样本数 /*=========================================================================== * 基线冻结超时 (V2.3~V2.5) *===========================================================================*/ #define FREEZE_TIMEOUT 1000 // 冻结超时: ~10s @ 10ms/tick #define FREEZE_STABILITY_RATE 2 // 稳定性窗口: 参考值的 ±2% /*=========================================================================== * 离开检测: 1 = 平坦性三条件 (CN200910309382), 0 = cnt_release 防抖 *===========================================================================*/ #define USE_FLATNESS_EXIT 1 /*=========================================================================== * 平坦性参数 *===========================================================================*/ #define K1 8 #define K2 8 #define SLOPE_FLAT_THRESH 100 #define MIN_DELTA2 5 #define MIN_DELTA3 2 #define FLAT_CONFIRM_CNT 3 #define WINDOW_ORIGIN 500 // 基线跟踪窗口 (500 × 10ms = 5s) /*=========================================================================== * 频率测量 * MEASUREMENT_BASE = 2^17 ≈ 131072 * LPCNT = MEASUREMENT_BASE / Xn, 使 Value 归一化到 ~131072 *===========================================================================*/ #define MEASUREMENT_BASE 131072 /*=========================================================================== * 通道数量 *===========================================================================*/ #define LOOP_CAPTURE_MAX 4 /*=========================================================================== * 灵敏度表(4级: 0=低, 3=高) * 进入阈值 = Origin × SensTable[SENS] / 65536 * 离开阈值 = Origin × SensTable_1[SENS] / 65536 *===========================================================================*/ extern const uint16_t SensTable[4]; extern const uint16_t SensTable_1[4]; /*=========================================================================== * Forward declaration *===========================================================================*/ struct tskTaskControlBlock; typedef struct tskTaskControlBlock* TaskHandle_t; /*=========================================================================== * 单通道状态结构体 — 对齐 DLD154V4B 全局变量 *===========================================================================*/ typedef struct { uint8_t loop_num; // 通道编号 0~3 /*--- 捕获 & 测量 ---*/ uint16_t loop_Xn; // 相邻边沿周期差 uint16_t loop_CapThis, loop_CapLast; uint16_t loop_LPCNT, loop_CapCnt; uint32_t loop_CapSum, loop_Value; uint32_t loop_CAPVD; // IIR 滤波后的频率值 uint32_t loop_Origin; // 基线(无车参考值) uint32_t loop_ORG_SUM; uint16_t loop_ORG_CNT; uint16_t loop_dlt_ORG; // 当前灵敏度阈值 uint8_t Flt_Reg; // IIR 滤波系数 /*--- M4 优化: 进入确认 + 冻结超时 ---*/ uint8_t loop_entry_cnt; // 进入确认计数 uint16_t loop_freeze_cnt; // 冻结持续计数 uint32_t loop_freeze_ref; // 冻结参考值 /*--- 标志位 ---*/ uint8_t loop_INI_LOOP; uint8_t loop_CAP_OK; // 新测量数据就绪 uint8_t loop_VD_FLAG; // 有车标志 uint8_t loop_VD_HOLD; // 有限存在计时启用 uint8_t loop_RF_FLAG; // 本 tick 收到线圈振荡边沿 uint8_t loop_LOOP_OK; // 线圈连接正常 uint8_t loop_LOOP_OK0; // 上周期连接状态 uint8_t loop_FLAG_IN; // 进入延时中 uint8_t loop_FLAG_OUT; // 离开延时中 uint8_t loop_FLAG_PLUSE; // 脉冲输出中 uint8_t loop_SensLevel; // 灵敏度等级 0~3 uint8_t loop_cnt_release; // 离开防抖计数 uint8_t loop_stable; // 数值已稳定 #if USE_FLATNESS_EXIT /*--- 平坦性离开状态 ---*/ uint8_t exit_state; // 0=追踪斜率, 1=等待平坦 uint16_t max_slope; // 第一上升坡面最大 |f'| uint16_t max_slope_rate; // 最大 |f''| uint16_t delta2; // Δ2: 一阶平坦阈值 uint16_t delta3; // Δ3: 二阶平坦阈值 int32_t prev_capvd; // 上一帧 CAPVD int32_t prev_first_deriv; // 上一帧一阶导数 uint8_t slope_flat_cnt; // 斜率趋零连续计数 uint8_t flat_ok_cnt; // 平坦条件满足连续计数 #endif /*--- 计数器 ---*/ uint16_t Hold_CNT; uint16_t hold_time; // 有限存在时长 (tick 数) uint16_t relay_delay; // 继电器延时 (tick 数) uint8_t INCNT, OUTCNT; /*--- 输出配置 ---*/ uint8_t SET_PLUS; // 0=脉冲, 1=存在输出 uint8_t SET_DLY; // 离开延时: 0=无, 1=500ms uint8_t SET_SAFE; // 1=安全复位 /*--- 安全复位 ---*/ uint8_t LC_HOLD; uint8_t LC_Reset; uint32_t LC_Hold_CNT; /*--- 断开检测 ---*/ uint8_t power_up_state; // 上电后是否曾连接 uint8_t disconnect_count; // 断开次数 (0~3) uint8_t disconnect_active; // 当前断开中 uint8_t fault_phase; uint16_t fault_tick; /*--- 稳定期 ---*/ uint16_t stable_cnt; /*--- 调试 ---*/ uint32_t xn_counter; } Loop154_Unit; /*=========================================================================== * 全局状态 *===========================================================================*/ typedef struct { uint32_t report_counter; Loop154_Unit loop_unit[LOOP_CAPTURE_MAX]; } Loop154_States; extern Loop154_States g_loop_states; /*=========================================================================== * 全局变量 *===========================================================================*/ extern uint32_t g_sys_freq; extern uint8_t g_input_div; extern uint32_t g_safe_max_cnt; /*=========================================================================== * 函数声明 *===========================================================================*/ void loop_task_function(void *pvParameters); void usart_task_function(void *pvParameters); void led_indicator_task_function(void *pvParameters); void vd1_task_per_channel(Loop154_Unit *unit); void init_vd_single(Loop154_Unit *unit); void INIT_VDs(Loop154_States *loops); void poll_red_pwm(void); void poll_green_led(Loop154_Unit *unit); void poll_yellow_led_single(Loop154_Unit *unit); uint32_t get_flt_value(uint32_t new_value, uint32_t last_Value); uint8_t update_moving_average(uint32_t* p_sum, uint16_t* p_cnt, uint32_t* p_origin, uint32_t new_value, uint16_t window); void set_loops_relay_on(uint8_t loop_num); void set_loops_relay_off(uint8_t loop_num); void wdt_feed(void); extern TaskHandle_t usart_task_handler; #endif /* __TASKLOOP_H__ */