Files
DLD154V4B/tests/test_coil_range.c
T
wangfq 16eed844a6 feat(V4B): V4.36.20 — 最低工作电感量 COIL_L_MIN_UH=20µH, 低于按线圈断开指示
用户需求: 设定最低电感量工作值(默认 20µH, 43nF 低频档口径, 宏定义);
线圈电感量低于该值 → 黄灯快闪以线圈断开状态指示
- TaskLoop.h: 新增 COIL_L_MIN_UH 20; 频率窗上限 125→171kHz (=L 20.06µH,
  43nF: L=2.533e7/(f²×43)) — 20~38µH 小线圈转为可正常工作(含现场 21/23µH)
- poll_yellow_led 模式1: g_coil_fault==2 归入断开级快闪(!LOOP_OK/reconn_stab 同级)
- 一长一短(模式5)仅保留 coil_fault==1 (L 偏大 f<18kHz)
- coil_monitor 防抖 1s 不变; 继电器/判定逻辑不动(仅指示级)
- test: 171 正常/172(L<20µH) 偏小, L 偏大 17; 全绿
语法0 error, 4测试全绿; spec V2.37 / devlog V2.56
2026-09-07 09:08:37 +08:00

118 lines
3.4 KiB
C

/*
* test_coil_range.c — 线圈电感量合理范围监视 gcc 隔离单测 (DLD154V4B V4.26)
*
* 验证对象: TaskLoop.c coil_monitor() (V4.26 拍板规格)
* 默认低频档口径(43nF 三极管板): 空场频率合理窗 20~125kHz, 出界即判定电感量不合理
* g_coil_fault: 0=正常 1=L偏大(f<18kHz) 2=L偏小(f>125kHz)
* 防抖: 越界/恢复均连续 100tick(=1s) 才置位/清除 (调用点=稳定无车空闲)
*
* 镜像宏与固件一致 (改 COIL_* 时同步此处!)
*/
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#define COIL_F_OK_MIN_KHZ 18
#define COIL_F_OK_MAX_KHZ 171
#define COIL_DEF_C_NF 66
static uint8_t g_coil_fault = 0;
static uint16_t g_coil_bad_cnt = 0;
/* coil_monitor() 纯逻辑镜像 (不含 Origin==0 守卫, 由调用点保证) */
static void coil_step(uint32_t f_khz)
{
uint8_t want = 0;
if (f_khz < COIL_F_OK_MIN_KHZ)
want = 1;
else if (f_khz > COIL_F_OK_MAX_KHZ)
want = 2;
if (want == g_coil_fault) {
g_coil_bad_cnt = 0;
} else {
g_coil_bad_cnt++;
if (g_coil_bad_cnt >= 100) {
g_coil_fault = want;
g_coil_bad_cnt = 0;
}
}
}
static void run_ticks(uint32_t f_khz, int n)
{
int i;
for (i = 0; i < n; i++)
coil_step(f_khz);
}
static void test_too_large(void)
{
g_coil_fault = 0; g_coil_bad_cnt = 0;
/* f=16.3kHz(实测超限线圈) 持续 <1s 不置位 */
run_ticks(16, 99);
assert(g_coil_fault == 0);
/* 满 1s → L 偏大 */
coil_step(16);
assert(g_coil_fault == 1);
/* 保持 → 状态稳定不抖 */
run_ticks(16, 1000);
assert(g_coil_fault == 1);
printf("1. L偏大 (f=16kHz, 1s 防抖置位, 保持稳定) OK\n");
}
static void test_too_small(void)
{
g_coil_fault = 0; g_coil_bad_cnt = 0;
run_ticks(200, 100);
assert(g_coil_fault == 2);
printf("2. L偏小 (f=200kHz, 1s 防抖置位) OK\n");
}
static void test_recover(void)
{
g_coil_fault = 1; g_coil_bad_cnt = 0;
run_ticks(62, 99);
assert(g_coil_fault == 1); /* 恢复防抖 <1s 不清除 */
coil_step(62);
assert(g_coil_fault == 0); /* 满 1s 恢复正常 */
printf("3. 恢复正常 (1s 防抖清除) OK\n");
}
static void test_boundaries(void)
{
g_coil_fault = 0; g_coil_bad_cnt = 0;
run_ticks(17, 100); assert(g_coil_fault == 1); /* 19 → 偏大 */
run_ticks(62, 100); assert(g_coil_fault == 0); /* 20~125 正常 */
run_ticks(18, 100); assert(g_coil_fault == 0); /* 边界 20 正常 */
run_ticks(125, 100); assert(g_coil_fault == 0); /* 中间 125 正常 (V4.36.20 窗内) */
run_ticks(171, 100); assert(g_coil_fault == 0); /* 边界 171 (=L 20.15µH) 正常 */
run_ticks(172, 100); assert(g_coil_fault == 2); /* 172 → L<20µH 偏小(断开级) */
printf("4. 边界 19/20/171/172 OK\n");
}
static void test_jitter_no_alarm(void)
{
/* 抖动: 16 与 62 交替 (每 50tick) → 计数永远到不了 100 → 不误报 */
int i;
g_coil_fault = 0; g_coil_bad_cnt = 0;
for (i = 0; i < 2000; i++)
coil_step((i & 1) ? 62 : 16);
assert(g_coil_fault == 0);
printf("5. 频率抖动不误报 OK\n");
}
int main(void)
{
test_too_large();
test_too_small();
test_recover();
test_boundaries();
test_jitter_no_alarm();
printf("\nALL PASS (窗口 18~171kHz=L 20µH, 防抖 1s)\n");
return 0;
}