/* * test_red_breath.c — 红灯呼吸节奏回归 (V4.23, 对齐 vd960Loop 效果) * * 复刻 main.c poll_red_pwm (V4.23) 逻辑, mock tmr_channel_value_set 记录写值: * - PWM 满量程 665, 60ms/步 (12×5ms) * - 期望: 每写值 ∈ [0, 665]; 峰值保持 ≥3 步; * - 全周期(两次最暗之间) ≈ 43 步 × 60ms ≈ 2.58s ∈ [2.4, 2.8]s * * 编译: gcc -Wall -o test_red_breath test_red_breath.c && ./test_red_breath *===========================================================================*/ #include #include #include #define RED_BREATH_ARR 665 #define RED_STEP_BIG 39 #define RED_STEP_SMALL 10 #define RED_SPLIT 585 #define RED_HOLD_LEVEL 660 #define RED_HOLD_TICKS 3 #define RED_STEP_TICKS 12 #define TICK_MS 5 static uint16_t pulse; static uint8_t g_pulse_counter; static uint8_t g_flag_pulse; static uint8_t g_cnt_pwm_red_low_timeout; static uint16_t last_written = 0xFFFF; static unsigned write_cnt = 0; static void tmr_channel_value_set_mock(uint16_t v) { last_written = v; write_cnt++; } /* 与 main.c 相同的实现 */ static void poll_red_pwm(void) { g_pulse_counter++; if (g_pulse_counter >= RED_STEP_TICKS) { g_pulse_counter = 0; if (g_flag_pulse) { if (pulse < RED_SPLIT) pulse += RED_STEP_BIG; else pulse += RED_STEP_SMALL; if (pulse >= RED_BREATH_ARR) { g_cnt_pwm_red_low_timeout++; if (g_cnt_pwm_red_low_timeout >= RED_HOLD_TICKS) { g_flag_pulse = 0; g_cnt_pwm_red_low_timeout = 0; } pulse = RED_HOLD_LEVEL; } } else { if (pulse <= RED_STEP_BIG) { pulse = 0; g_flag_pulse = 1; } else { pulse -= RED_STEP_BIG; } } tmr_channel_value_set_mock(pulse); } } int main(void) { unsigned calls, steps; unsigned dark_events[8], di = 0; unsigned hold_cnt_max = 0, hold_cnt = 0; pulse = 0; g_pulse_counter = 0; g_flag_pulse = 1; g_cnt_pwm_red_low_timeout = 0; write_cnt = 0; /* 跑约 5 个完整周期; 每个写值事件后置回哨兵, 只在写值步统计 */ for (calls = 1; calls <= 2600; calls++) { poll_red_pwm(); if (last_written != 0xFFFF) { assert(last_written <= RED_BREATH_ARR); if (last_written >= 640) { /* 峰值区保持观测(按写值步) */ hold_cnt++; if (hold_cnt > hold_cnt_max) hold_cnt_max = hold_cnt; } else { hold_cnt = 0; } if (last_written == 0 && di < 8) { dark_events[di++] = calls; /* 最暗写值时刻 */ if (di >= 2) break; } last_written = 0xFFFF; /* 事件已消费 */ } } assert(di >= 2); steps = (dark_events[1] - dark_events[0]) / RED_STEP_TICKS; double cycle_ms = (double)(dark_events[1] - dark_events[0]) * TICK_MS; printf("周期步数=%u (≈43), 周期时长=%.0fms (期望 2400~2800ms)\n", steps, cycle_ms); printf("峰值连续保持写值步数(≥3 步, 含下降第一步)≈%u\n", hold_cnt_max); assert(cycle_ms >= 2400 && cycle_ms <= 2800); assert(steps >= 40 && steps <= 46); assert(hold_cnt_max >= 3); printf("ALL PASS (test_red_breath), write_cnt=%u\n", write_cnt); return 0; }