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_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
|
||||
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);
|
||||
for(i = 0; i< _div; i++){
|
||||
g_input_div *= 2;
|
||||
|
||||
@@ -33,10 +33,11 @@
|
||||
|
||||
/*===========================================================================
|
||||
* 频率测量参数
|
||||
* XNSUM_FOR_ORIGIN_FACTOR: Value/LPCNT 的归一化右移量
|
||||
* 使 Origin 保持在合理的 uint32 范围内
|
||||
* MEASUREMENT_BASE: 自适应测量窗口目标值 (≈131072)
|
||||
* 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
|
||||
@@ -81,6 +82,9 @@ extern uint8_t loop1_FLAG_OUT; // 离开延时中
|
||||
extern uint8_t loop1_FLAG_PLUSE; // 脉冲输出中
|
||||
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_PLUSE;
|
||||
uint8_t loop1_SensLevel;
|
||||
uint8_t loop1_cnt_release;
|
||||
|
||||
/*===========================================================================
|
||||
* 全局状态变量 — 计数器
|
||||
@@ -288,6 +289,7 @@ void INIT_VD(void)
|
||||
loop1_FLAG_IN = 0;
|
||||
loop1_FLAG_OUT = 0;
|
||||
loop1_FLAG_PLUSE = 0;
|
||||
loop1_cnt_release = 0;
|
||||
|
||||
loop1_LC_HOLD = 0;
|
||||
loop1_LC_Reset = 0;
|
||||
@@ -360,15 +362,14 @@ void TMR3_GLOBAL_IRQHandler(void)
|
||||
if (loop1_LPCNT == 0) {
|
||||
if (loop1_CapCnt > 10) {
|
||||
/*
|
||||
* 修复: 先乘后除,避免截断为 0
|
||||
* 原代码: loop1_LPCNT = (32768 / Xn) << 6 ← 小 Xn 时溢出
|
||||
* 新代码: (32768UL << 6) / Xn = 2097152 / Xn
|
||||
* 自适应测量窗口: MEASUREMENT_BASE / Xn
|
||||
* 使归一化 Value ≈ 131072,无需后续 >>6
|
||||
*/
|
||||
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",
|
||||
loop1_LPCNT, loop1_Xn);
|
||||
if (loop1_LPCNT == 0) {
|
||||
loop1_LPCNT = 1000;
|
||||
loop1_LPCNT = 100;
|
||||
}
|
||||
loop1_CAPVD = 0;
|
||||
loop1_CapSum = 0;
|
||||
@@ -379,7 +380,7 @@ void TMR3_GLOBAL_IRQHandler(void)
|
||||
loop1_CapSum += loop1_Xn;
|
||||
if (loop1_CapCnt >= loop1_LPCNT) {
|
||||
loop1_CAPVD = loop1_CapSum;
|
||||
loop1_Origin = loop1_CAPVD >> XNSUM_FOR_ORIGIN_FACTOR;
|
||||
loop1_Origin = loop1_CAPVD; // 不再 >>6
|
||||
PRINT("First_capSum:%d, Origin:%d\n",
|
||||
loop1_CapSum, loop1_Origin);
|
||||
loop1_INI_LOOP = 0;
|
||||
@@ -560,13 +561,11 @@ void TMR15_GLOBAL_IRQHandler(void)
|
||||
*===========================================================================*/
|
||||
void vd1_task(void)
|
||||
{
|
||||
uint32_t tmp_value;
|
||||
|
||||
if (loop1_Origin == 0) return;
|
||||
|
||||
/*--- 1. IIR 一阶低通滤波(对齐 M1H 公式) ---*/
|
||||
tmp_value = loop1_Value >> XNSUM_FOR_ORIGIN_FACTOR;
|
||||
loop1_CAPVD = get_flt_value(tmp_value, loop1_CAPVD);
|
||||
/* Value 已经是 MEASUREMENT_BASE 级别的原始值,不再右移 */
|
||||
loop1_CAPVD = get_flt_value(loop1_Value, loop1_CAPVD);
|
||||
|
||||
if (!loop1_VD_FLAG) {
|
||||
/*================================================================
|
||||
@@ -581,9 +580,8 @@ void vd1_task(void)
|
||||
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable[loop1_SensLevel]) >> 16;
|
||||
|
||||
if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG)) {
|
||||
PRINT("Car_In, Value:%d, CAPVD:%d, Origin:%d, dlt:%d, freq:%d\n",
|
||||
tmp_value, loop1_CAPVD, loop1_Origin,
|
||||
loop1_dlt_ORG, g_crm_clocks_freq_struct.sclk_freq);
|
||||
PRINT("Car_In, Value:%d, CAPVD:%d, Origin:%d, dlt:%d\n",
|
||||
loop1_Value, loop1_CAPVD, loop1_Origin, loop1_dlt_ORG);
|
||||
|
||||
loop1_VD_FLAG = 1;
|
||||
loop1_FLAG_IN = 1;
|
||||
@@ -600,19 +598,23 @@ void vd1_task(void)
|
||||
|
||||
loop1_ORG_CNT = 0;
|
||||
loop1_ORG_SUM = 0;
|
||||
loop1_cnt_release = 0; // 重置离开防抖
|
||||
}
|
||||
} 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;
|
||||
|
||||
if ((loop1_Origin - loop1_dlt_ORG) < loop1_CAPVD) {
|
||||
PRINT("Car_OFF, Value:%d, CAPVD:%d, Origin:%d, dlt:%d, freq:%d\n",
|
||||
tmp_value, loop1_CAPVD, loop1_Origin,
|
||||
loop1_dlt_ORG, g_crm_clocks_freq_struct.sclk_freq);
|
||||
loop1_cnt_release++;
|
||||
if (loop1_cnt_release >= 3) {
|
||||
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_FLAG_OUT = 1;
|
||||
@@ -623,6 +625,13 @@ void vd1_task(void)
|
||||
loop1_ORG_CNT = 0;
|
||||
loop1_ORG_SUM = 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++;
|
||||
if (_dbg_cnt >= 200) { // 200 × 10ms = 2s
|
||||
_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",
|
||||
SET_DLY, SET_SAFE, loop1_Xn, loop1_LPCNT,
|
||||
loop1_CAPVD, loop1_Origin, loop1_VD_FLAG);
|
||||
|
||||
Reference in New Issue
Block a user