perf: 提高测量精度和响应速度
- TIM3 分频 DIV_4→DIV_2(中断率×2,CPU仍<3%) - 去掉 XNSUM_FOR_ORIGIN_FACTOR (>>6),保留全部采样精度 - LPCNT = MEASUREMENT_BASE(131072)/Xn,替代 (32768<<6)/Xn - 测量窗口 17.5ms→~1ms(快16倍) - Origin 范围 32K→131K,灵敏度阈值自动按比例缩放 - 离开增加 cnt_release>=3 防抖,防瞬间噪声误落杆
This commit is contained in:
@@ -236,7 +236,7 @@ void loop_timer_io_init(void)
|
|||||||
g_tmr_input_config_struct.input_channel_select = TMR_SELECT_CHANNEL_2;
|
g_tmr_input_config_struct.input_channel_select = TMR_SELECT_CHANNEL_2;
|
||||||
g_tmr_input_config_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
|
g_tmr_input_config_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
|
||||||
g_tmr_input_config_struct.input_polarity_select = TMR_INPUT_RISING_EDGE;
|
g_tmr_input_config_struct.input_polarity_select = TMR_INPUT_RISING_EDGE;
|
||||||
_div = TMR_CHANNEL_INPUT_DIV_4;
|
_div = TMR_CHANNEL_INPUT_DIV_2;
|
||||||
tmr_input_channel_init(TMR3, &g_tmr_input_config_struct, _div);
|
tmr_input_channel_init(TMR3, &g_tmr_input_config_struct, _div);
|
||||||
for(i = 0; i< _div; i++){
|
for(i = 0; i< _div; i++){
|
||||||
g_input_div *= 2;
|
g_input_div *= 2;
|
||||||
|
|||||||
@@ -33,10 +33,11 @@
|
|||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
* 频率测量参数
|
* 频率测量参数
|
||||||
* XNSUM_FOR_ORIGIN_FACTOR: Value/LPCNT 的归一化右移量
|
* MEASUREMENT_BASE: 自适应测量窗口目标值 (≈131072)
|
||||||
* 使 Origin 保持在合理的 uint32 范围内
|
* LPCNT = MEASUREMENT_BASE / Xn, 使 Value ≈ MEASUREMENT_BASE
|
||||||
|
* 121072 = 2^17, 兼顾精度和 Origin 范围
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
#define XNSUM_FOR_ORIGIN_FACTOR 6 // >>6
|
#define MEASUREMENT_BASE 131072 // 2^17
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
* 灵敏度表 — 对齐 M1H
|
* 灵敏度表 — 对齐 M1H
|
||||||
@@ -81,6 +82,9 @@ extern uint8_t loop1_FLAG_OUT; // 离开延时中
|
|||||||
extern uint8_t loop1_FLAG_PLUSE; // 脉冲输出中
|
extern uint8_t loop1_FLAG_PLUSE; // 脉冲输出中
|
||||||
extern uint8_t loop1_SensLevel; // 当前灵敏度等级 (0~3)
|
extern uint8_t loop1_SensLevel; // 当前灵敏度等级 (0~3)
|
||||||
|
|
||||||
|
/* 离开防抖计数器(连续 CAPVD 恢复到阈值以上才释放) */
|
||||||
|
extern uint8_t loop1_cnt_release; // 离开防抖计数
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
* 全局状态变量 — 计数器
|
* 全局状态变量 — 计数器
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ uint8_t loop1_FLAG_IN;
|
|||||||
uint8_t loop1_FLAG_OUT;
|
uint8_t loop1_FLAG_OUT;
|
||||||
uint8_t loop1_FLAG_PLUSE;
|
uint8_t loop1_FLAG_PLUSE;
|
||||||
uint8_t loop1_SensLevel;
|
uint8_t loop1_SensLevel;
|
||||||
|
uint8_t loop1_cnt_release;
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
* 全局状态变量 — 计数器
|
* 全局状态变量 — 计数器
|
||||||
@@ -288,6 +289,7 @@ void INIT_VD(void)
|
|||||||
loop1_FLAG_IN = 0;
|
loop1_FLAG_IN = 0;
|
||||||
loop1_FLAG_OUT = 0;
|
loop1_FLAG_OUT = 0;
|
||||||
loop1_FLAG_PLUSE = 0;
|
loop1_FLAG_PLUSE = 0;
|
||||||
|
loop1_cnt_release = 0;
|
||||||
|
|
||||||
loop1_LC_HOLD = 0;
|
loop1_LC_HOLD = 0;
|
||||||
loop1_LC_Reset = 0;
|
loop1_LC_Reset = 0;
|
||||||
@@ -360,15 +362,14 @@ void TMR3_GLOBAL_IRQHandler(void)
|
|||||||
if (loop1_LPCNT == 0) {
|
if (loop1_LPCNT == 0) {
|
||||||
if (loop1_CapCnt > 10) {
|
if (loop1_CapCnt > 10) {
|
||||||
/*
|
/*
|
||||||
* 修复: 先乘后除,避免截断为 0
|
* 自适应测量窗口: MEASUREMENT_BASE / Xn
|
||||||
* 原代码: loop1_LPCNT = (32768 / Xn) << 6 ← 小 Xn 时溢出
|
* 使归一化 Value ≈ 131072,无需后续 >>6
|
||||||
* 新代码: (32768UL << 6) / Xn = 2097152 / Xn
|
|
||||||
*/
|
*/
|
||||||
loop1_LPCNT = (32768UL << XNSUM_FOR_ORIGIN_FACTOR) / loop1_Xn;
|
loop1_LPCNT = MEASUREMENT_BASE / loop1_Xn;
|
||||||
PRINT("First_calc_loop1_LPCNT:%d, loop1_Xn:%d\n",
|
PRINT("First_calc_loop1_LPCNT:%d, loop1_Xn:%d\n",
|
||||||
loop1_LPCNT, loop1_Xn);
|
loop1_LPCNT, loop1_Xn);
|
||||||
if (loop1_LPCNT == 0) {
|
if (loop1_LPCNT == 0) {
|
||||||
loop1_LPCNT = 1000;
|
loop1_LPCNT = 100;
|
||||||
}
|
}
|
||||||
loop1_CAPVD = 0;
|
loop1_CAPVD = 0;
|
||||||
loop1_CapSum = 0;
|
loop1_CapSum = 0;
|
||||||
@@ -379,7 +380,7 @@ void TMR3_GLOBAL_IRQHandler(void)
|
|||||||
loop1_CapSum += loop1_Xn;
|
loop1_CapSum += loop1_Xn;
|
||||||
if (loop1_CapCnt >= loop1_LPCNT) {
|
if (loop1_CapCnt >= loop1_LPCNT) {
|
||||||
loop1_CAPVD = loop1_CapSum;
|
loop1_CAPVD = loop1_CapSum;
|
||||||
loop1_Origin = loop1_CAPVD >> XNSUM_FOR_ORIGIN_FACTOR;
|
loop1_Origin = loop1_CAPVD; // 不再 >>6
|
||||||
PRINT("First_capSum:%d, Origin:%d\n",
|
PRINT("First_capSum:%d, Origin:%d\n",
|
||||||
loop1_CapSum, loop1_Origin);
|
loop1_CapSum, loop1_Origin);
|
||||||
loop1_INI_LOOP = 0;
|
loop1_INI_LOOP = 0;
|
||||||
@@ -560,13 +561,11 @@ void TMR15_GLOBAL_IRQHandler(void)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
void vd1_task(void)
|
void vd1_task(void)
|
||||||
{
|
{
|
||||||
uint32_t tmp_value;
|
|
||||||
|
|
||||||
if (loop1_Origin == 0) return;
|
if (loop1_Origin == 0) return;
|
||||||
|
|
||||||
/*--- 1. IIR 一阶低通滤波(对齐 M1H 公式) ---*/
|
/*--- 1. IIR 一阶低通滤波(对齐 M1H 公式) ---*/
|
||||||
tmp_value = loop1_Value >> XNSUM_FOR_ORIGIN_FACTOR;
|
/* Value 已经是 MEASUREMENT_BASE 级别的原始值,不再右移 */
|
||||||
loop1_CAPVD = get_flt_value(tmp_value, loop1_CAPVD);
|
loop1_CAPVD = get_flt_value(loop1_Value, loop1_CAPVD);
|
||||||
|
|
||||||
if (!loop1_VD_FLAG) {
|
if (!loop1_VD_FLAG) {
|
||||||
/*================================================================
|
/*================================================================
|
||||||
@@ -581,9 +580,8 @@ void vd1_task(void)
|
|||||||
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable[loop1_SensLevel]) >> 16;
|
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable[loop1_SensLevel]) >> 16;
|
||||||
|
|
||||||
if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG)) {
|
if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG)) {
|
||||||
PRINT("Car_In, Value:%d, CAPVD:%d, Origin:%d, dlt:%d, freq:%d\n",
|
PRINT("Car_In, Value:%d, CAPVD:%d, Origin:%d, dlt:%d\n",
|
||||||
tmp_value, loop1_CAPVD, loop1_Origin,
|
loop1_Value, loop1_CAPVD, loop1_Origin, loop1_dlt_ORG);
|
||||||
loop1_dlt_ORG, g_crm_clocks_freq_struct.sclk_freq);
|
|
||||||
|
|
||||||
loop1_VD_FLAG = 1;
|
loop1_VD_FLAG = 1;
|
||||||
loop1_FLAG_IN = 1;
|
loop1_FLAG_IN = 1;
|
||||||
@@ -600,19 +598,23 @@ void vd1_task(void)
|
|||||||
|
|
||||||
loop1_ORG_CNT = 0;
|
loop1_ORG_CNT = 0;
|
||||||
loop1_ORG_SUM = 0;
|
loop1_ORG_SUM = 0;
|
||||||
|
loop1_cnt_release = 0; // 重置离开防抖
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*================================================================
|
/*================================================================
|
||||||
* 有车状态
|
* 有车状态
|
||||||
*================================================================*/
|
*================================================================*/
|
||||||
|
|
||||||
/*--- 离开检测(滞回阈值 SensTable_1 ≈ SensTable 的 50%) ---*/
|
/*--- 离开检测(滞回阈值 SensTable_1 ≈ SensTable 的 50%)
|
||||||
|
* 增加 cnt_release >= 3 防抖:连续 3 次恢复到阈值以上才释放
|
||||||
|
* 避免因瞬间噪声导致误落杆 ---*/
|
||||||
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable_1[loop1_SensLevel]) >> 16;
|
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable_1[loop1_SensLevel]) >> 16;
|
||||||
|
|
||||||
if ((loop1_Origin - loop1_dlt_ORG) < loop1_CAPVD) {
|
if ((loop1_Origin - loop1_dlt_ORG) < loop1_CAPVD) {
|
||||||
PRINT("Car_OFF, Value:%d, CAPVD:%d, Origin:%d, dlt:%d, freq:%d\n",
|
loop1_cnt_release++;
|
||||||
tmp_value, loop1_CAPVD, loop1_Origin,
|
if (loop1_cnt_release >= 3) {
|
||||||
loop1_dlt_ORG, g_crm_clocks_freq_struct.sclk_freq);
|
PRINT("Car_OFF, Value:%d, CAPVD:%d, Origin:%d, dlt:%d\n",
|
||||||
|
loop1_Value, loop1_CAPVD, loop1_Origin, loop1_dlt_ORG);
|
||||||
|
|
||||||
loop1_VD_FLAG = 0;
|
loop1_VD_FLAG = 0;
|
||||||
loop1_FLAG_OUT = 1;
|
loop1_FLAG_OUT = 1;
|
||||||
@@ -623,6 +625,13 @@ void vd1_task(void)
|
|||||||
loop1_ORG_CNT = 0;
|
loop1_ORG_CNT = 0;
|
||||||
loop1_ORG_SUM = 0;
|
loop1_ORG_SUM = 0;
|
||||||
Hold_CNT = 0;
|
Hold_CNT = 0;
|
||||||
|
loop1_cnt_release = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* CAPVD 又掉回阈值以下 → 重置防抖,车还在 */
|
||||||
|
if (loop1_cnt_release > 0) {
|
||||||
|
loop1_cnt_release = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -693,7 +702,7 @@ void loop_task_function(void *pvParameters)
|
|||||||
_dbg_cnt++;
|
_dbg_cnt++;
|
||||||
if (_dbg_cnt >= 200) { // 200 × 10ms = 2s
|
if (_dbg_cnt >= 200) { // 200 × 10ms = 2s
|
||||||
_dbg_cnt = 0;
|
_dbg_cnt = 0;
|
||||||
PRINT("SET_DLY:%d, SET_SAFE:%d, Xn:%d, LPCNT:%d, "
|
PRINT("SET_DLY:%d, SAFE:%d, Xn:%d, LPCNT:%d, "
|
||||||
"CAPVD:%d, Origin:%d, VD:%d\n",
|
"CAPVD:%d, Origin:%d, VD:%d\n",
|
||||||
SET_DLY, SET_SAFE, loop1_Xn, loop1_LPCNT,
|
SET_DLY, SET_SAFE, loop1_Xn, loop1_LPCNT,
|
||||||
loop1_CAPVD, loop1_Origin, loop1_VD_FLAG);
|
loop1_CAPVD, loop1_Origin, loop1_VD_FLAG);
|
||||||
|
|||||||
Reference in New Issue
Block a user