- Loop154_Unit 新增 relay_delay 字段 - storage.c 从 delay_time 计算: relay_delay = delay_time * 2 - TMR15_GLOBAL_IRQHandler 使用 unit->relay_delay 替代固定 OUT_DELAY
197 lines
8.2 KiB
C
197 lines
8.2 KiB
C
/**
|
||
**************************************************************************
|
||
* @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 <stdint.h>
|
||
#include <stddef.h>
|
||
|
||
/*===========================================================================
|
||
* 时序参数(每 tick = 50ms,由 TMR15 5ms×10 产生)
|
||
*===========================================================================*/
|
||
#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
|
||
|
||
/*===========================================================================
|
||
* 滤波参数
|
||
*===========================================================================*/
|
||
#define ALFA_CAP1 79 // IIR 指数平滑 α = 79/256 ≈ 0.31
|
||
#define STABLE_SAMPLES 128 // 稳定期样本数
|
||
|
||
/*===========================================================================
|
||
* 离开检测: 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 100 // 基线跟踪窗口
|
||
|
||
/*===========================================================================
|
||
* 频率测量
|
||
* 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 滤波系数
|
||
|
||
/*--- 标志位 ---*/
|
||
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,
|
||
uint8_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__ */
|