fix(V4B): V4.27 — 频率测量 4 倍偏差修正 (示波器 30.23k vs 打印 7k)

根因(两处2倍叠加):
1. calc_freq_khz 常数 60000 按 60MHz 假设; 实际 TMR3 计数时钟=sclk=120MHz (HEXT×10, AHB/APB1÷1)
2. 输入捕获 DIV_2 (每2边沿捕获, Xn 翻倍), g_input_div 从未参与换算
→ Xn=2×120M/f_real, f_print=f_real/4 (30.23/4=7.56✓ 36.82/4=9.21✓)

改动: calc 60000→240000 (注释推导); coil_l_uH 改随 f_kHz (25330000/(f²×C66));
      DBG/EVT 用同一 _fk; 版本 V4.27; spec §4.1.2 文字更正 + devlog/design v0.4 标注影响

影响: 旧日志 f/L 需×4 (16.3kHz 假象实为 65.2kHz≈90µH 正常线圈); V4.26 告警窗随真实 f 自洽
This commit is contained in:
wangfq
2026-09-03 11:49:43 +08:00
parent dd14e083fa
commit 6b7d624ff0
5 changed files with 70 additions and 21 deletions
+2 -2
View File
@@ -14,10 +14,10 @@
#define __CMCNG_H__
#define PRODUCT_MODEL "DLD154"
#define FIRMWARE_VER "4.26"
#define FIRMWARE_VER "4.27"
#define HARDWARE_VER "3.00"
#define FIRMWARE_VER_MAIN 4
#define FIRMWARE_VER_SUB 26
#define FIRMWARE_VER_SUB 27
#define HARDWARE_VER_MAIN 3
#define HARDWARE_VER_SUB 0
+19 -12
View File
@@ -755,16 +755,21 @@ void TMR15_GLOBAL_IRQHandler(void)
* 调试打印辅助 — V4.20 debug 打印重组 (2026-09-01)
*
* calc_freq_khz: 由窗口量反算线圈振荡频率
* f = 捕获时钟(60MHz) / Xn_avg, Xn_avg = CAPVD / LPCNT
* → f_kHz = 60000 × LPCNT / CAPVD
* 无车: CAPVD≈131072, LPCNT≈218 → ≈99.8kHz; 有车: Xn↓ → f↑
* 捕获链路: 线圈振荡信号 → PA7(TMR3_CH2) 输入捕获, 捕获分频 ÷2 (DIV_2),
* TMR3 计数时钟 = sclk = 120MHz (HEXT×10, AHB/APB1 ÷1, at32f421_clock.c)
* Xn = 捕获间隔计数 = 2 × 120MHz / f_real → f_kHz = 240000 / Xn
* CAPVD ≈ LPCNT × Xn → 240000 × LPCNT / CAPVD
* → f_kHz = 240000 × LPCNT / CAPVD
* ⚠ V4.27 修正: 原 60000 按 60MHz 假设 + 未计 DIV_2, 少算 4 倍
* (示波器 30.23kHz 打印 7kHz 实测偏差; 旧日志 16.3kHz 实为 ~65.2kHz)
* L 粗估: f=120kHz 边界 @66nF → L≈27µH (仅供参考, 窗口判定以拍板频率窗为准)
*===========================================================================*/
uint32_t g_slope_limit_cnt = 0; // 斜率限幅截断计数 (EMI/干扰线索, 周期打印带出)
static uint32_t calc_freq_khz(uint32_t capvd, uint16_t lp_cnt)
{
if (capvd == 0) return 0;
return (60000UL * lp_cnt) / capvd;
return (240000UL * lp_cnt) / capvd;
}
/*===========================================================================
@@ -801,13 +806,14 @@ static void env_resync_apply(uint32_t new_origin)
env_resync_abort();
}
/*===========================================================================
* V4.26: 线圈电感量粗估 (默认低频档 C=66nF; 拨码 33nF 档结果 ×2)
* f = 60MHz/Xn → L_uH = Xn^2 / (4π^2 × 60MHz^2×1e-9... 化简为 Xn^2/(142×C_nF)
* 例: Xn=3681(f=16.3k) → L≈1445µH; Xn=685(f=87.6k) → L≈50µH
* V4.26/27: 线圈电感量粗估 (默认低频档 C=66nF; 拨码 33nF 档结果 ×2)
* L_uH = 2.533e7 / (f_kHz² × C_nF) [f=1/(2π√(LC)), f_kHz 为修正后真实频率]
* 例: f=30.2kHz → L≈420µH; f=65.2kHz → L≈90µH; f=120kHz → L≈27µH
*===========================================================================*/
static uint32_t coil_l_uH(uint32_t xn)
static uint32_t coil_l_uH(uint32_t f_khz)
{
return (uint32_t)(((uint64_t)xn * xn) / ((uint64_t)COIL_DEF_C_NF * 142u));
if (f_khz == 0) return 0;
return 25330000UL / (f_khz * f_khz * COIL_DEF_C_NF);
}
/*===========================================================================
@@ -838,7 +844,7 @@ static void coil_monitor(void)
if (g_coil_bad_cnt >= 100) {
if (g_coil_fault == 0)
PRINT("EVT|coil_fault f:%d kHz L~%lu uH(C66/×2C33) Xn:%d %s\n",
f_khz, coil_l_uH(loop1_Xn), loop1_Xn,
f_khz, coil_l_uH(f_khz), loop1_Xn,
want == 1 ? "too_large" : "too_small");
else
PRINT("EVT|coil_ok f:%d kHz\n", f_khz);
@@ -1306,11 +1312,12 @@ void loop_task_function(void *pvParameters)
if (_dbg_cnt >= 200) { // 200 × 10ms = 2s
uint32_t _t_ms = _dbg_cnt * 10; // V4.20: 先取时间再归零
_dbg_cnt = 0;
uint32_t _fk = calc_freq_khz(loop1_CAPVD, loop1_LPCNT);
PRINT("DBG|t=%ums f=%dkHz L=%luuH Xn=%d LPCNT=%d Value=%d CAPVD=%d slow=%d "
"Origin=%d dlt=%d SENS=%d VD=%d FRZ=%d/%d LIM=%d LOOP=%d STBL=%d\n",
_t_ms,
calc_freq_khz(loop1_CAPVD, loop1_LPCNT),
coil_l_uH(loop1_Xn),
_fk,
coil_l_uH(_fk),
loop1_Xn, loop1_LPCNT, loop1_Value, loop1_CAPVD, loop1_CAPVD_slow,
loop1_Origin, loop1_dlt_ORG, loop1_SensLevel, loop1_VD_FLAG,
loop1_freeze_cnt, loop1_freeze_ref, g_slope_limit_cnt,