diff --git a/utilities/at32f421_freertos_demo/src/TaskLoop.c b/utilities/at32f421_freertos_demo/src/TaskLoop.c index 4d589a9..ec77d25 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -1341,10 +1341,16 @@ void vd1_task(void) /* V4.37(D): 余数累加 —— d/128 整数截断有 ±127 counts 死区 * (|d|<128 步进=0 ⇒ EMA 常驻真空下方 ~127 counts ⇒ vac_ref 被拉低 * ⇒ 进入线偏低 ⇒ 触发高度漂移, 只能断电上电复位; 2026-09-11 单测实测 127) */ - g_vac_frac += _ema_d; - { int32_t _st = g_vac_frac / VACUUM_EMA_ALFA; - g_vac_frac -= _st * VACUUM_EMA_ALFA; - g_vacuum_ema += (uint32_t)_st; + /* V4.36.42(E): EMA 单向 —— 只允许向"真空回升"方向跟随 + * ① 真空真下降由 Origin 块平均承担, vac_ref 取 min 天然选 Origin(EMA 偏高无害) + * ② 若 EMA 跟随近场金属向下, vac_ref 的"min + 1×dlt" 硬开关会被反复扫过 + * (板缓慢接近/悬停时 进入线跳变 ±150 counts ⇒ 判据乱跳; 2026-09-11 仿真 sweep 实测) + * 保留 D 的余数累加 ⇒ 向上收敛无 ±127 counts 死区 */ + if (_ema_d > 0) { + g_vac_frac += _ema_d; + int32_t _st = g_vac_frac / VACUUM_EMA_ALFA; + g_vac_frac -= _st * VACUUM_EMA_ALFA; + g_vacuum_ema += (uint32_t)_st; } } if (((int32_t)loop1_Origin - (int32_t)g_vacuum_ema) > (int32_t)(loop1_Origin >> 2) ||