diff --git a/云台/Application/Task/Src/monitor_task.c b/云台/Application/Task/Src/monitor_task.c index bdb07f0..8e51245 100644 --- a/云台/Application/Task/Src/monitor_task.c +++ b/云台/Application/Task/Src/monitor_task.c @@ -8,6 +8,8 @@ * 连接音效 = 遥控器上线瞬间两声上扬(M3->H3) * CAN 掉线蜂鸣(legacy 语义): 按设备序号 n 响 n 下,2s 一轮,每次只报 * 最先掉线的设备,设备序号表见 linkcheck_first_offline() + * 调试模式(DEBUG_BUZZER_MELODY=1,见 robot_param.h): 上述蜂鸣改为循环 + * 播放旋律,避免台架调试时连续滴滴声;红灯常亮等灯语不受影响 * 看门狗: IWDG 约 2.5s;上电 5s 宽限期无条件喂,之后仅当全部任务心跳正常 * 才喂——任何任务卡死都会复位,不会整车失控 * ========================================================================== */ @@ -170,10 +172,24 @@ void LED_Task(void const * argument) if (can_alarm) { led_set_red(1); - int8_t id = linkcheck_first_offline(); - if (id >= 0) + + /* 掉线设备序号(0 起)。旋律模式下不用它的返回值,仍保留调用: + * 一是调试时可直接在调试器里看 linkcheck 结果,二是避免该静态 + * 函数在 DEBUG_BUZZER_MELODY=1 时被判为未使用而报警告 */ + int8_t first_offline = linkcheck_first_offline(); + +#if DEBUG_BUZZER_MELODY + /* 调试模式:警告音替换为循环旋律(见 modules/BUZZER/buzzer.h)。 + * 红灯常亮与其它灯语不变,"哪台设备掉线"这一信息不会丢。 + * 步进用本任务自身的 100ms 节拍,不靠 HAL_GetTick 采样,避免周期 + * 抖动漏掉或重复某个音符 */ + static uint16_t melody_step = 0; + (void)first_offline; + buzzer_play_melody(melody_step++); +#else + if (first_offline >= 0) { - uint8_t n = (uint8_t)(id + 1); + uint8_t n = (uint8_t)(first_offline + 1); uint8_t w = counter % 20; // 2s 窗口 /* 第 j 声:占 w=[2j,2j+1],响 100ms 停 100ms */ if ((w / 2) < n && (w % 2) == 0) @@ -183,6 +199,7 @@ void LED_Task(void const * argument) } else buzzer_off(); +#endif } else { diff --git a/云台/Application/robot_param.h b/云台/Application/robot_param.h index 4123ea8..92fc320 100644 --- a/云台/Application/robot_param.h +++ b/云台/Application/robot_param.h @@ -125,6 +125,11 @@ #define DEBUG_SHOOT_WITHOUT_REFEREE 1 // 1=无裁判系统时也允许开摩擦轮(台架调试用),比赛请改 0 #define GIMBAL_RAMMER_INSTALLED 0 // 1=拨弹 M2006 已安装;0=暂缺,不参与掉线判定 +/* 1=调试模式:把 CAN 掉线警告音替换成循环播放的旋律(台架调试时避免连续滴滴声 + * 干扰)。红灯常亮与其它灯语完全不变,仍能看出是哪台设备掉线;比赛请改 0。 + * 旋律音符表见 modules/BUZZER/buzzer.c 的 buzzer_melody[] */ +#define DEBUG_BUZZER_MELODY 1 + /* ============================ 掉线检测 ============================ */ #define DEVICE_OFFLINE_TIME_MS 100 // CAN 设备/裁判系统掉线判定时间 #define CTOC_OFFLINE_TIME_MS 100 // 板间通讯掉线判定时间 diff --git a/云台/modules/BUZZER/buzzer.c b/云台/modules/BUZZER/buzzer.c index ab89931..59d82f6 100644 --- a/云台/modules/BUZZER/buzzer.c +++ b/云台/modules/BUZZER/buzzer.c @@ -42,3 +42,23 @@ void buzzer_off(void) { __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, 0); } + +/* ========================================================================== + * 调试用旋律(见 buzzer.h):每步 100ms,空拍 BUZZER_P 为静音。 + * 无源蜂鸣器只有单音,这里用"上行分解和弦 + 回落"拼成一句短旋律;选音限定 + * 在中音 3 ~ 高音 2,避免刺耳。循环播放不会漏掉"有设备掉线"这一事实, + * 因为红灯常亮由 monitor_task 独立控制,与该旋律无关。 + * 改旋律:直接增删这里的音符即可,长度会自动生效。 + * ========================================================================== */ +static const buzzer_tone_e buzzer_melody[] = { + BUZZER_M3, BUZZER_M5, BUZZER_M6, BUZZER_H1, BUZZER_P, + BUZZER_M6, BUZZER_H1, BUZZER_H2, BUZZER_P, + BUZZER_H1, BUZZER_M6, BUZZER_M5, BUZZER_M3, BUZZER_P, +}; + +void buzzer_play_melody(uint16_t step) +{ + const uint16_t steps = + (uint16_t)(sizeof(buzzer_melody) / sizeof(buzzer_melody[0])); + buzzer_on(buzzer_melody[step % steps]); +} diff --git a/云台/modules/BUZZER/buzzer.h b/云台/modules/BUZZER/buzzer.h index 33a4e07..a95b213 100644 --- a/云台/modules/BUZZER/buzzer.h +++ b/云台/modules/BUZZER/buzzer.h @@ -16,4 +16,10 @@ typedef enum extern void buzzer_init(void); extern void buzzer_on(buzzer_tone_e tone); extern void buzzer_off(void); + +/* ---- 调试用旋律 ---- + * 按固定 100ms/步 推进的短旋律(音符表见 buzzer.c),用于把掉线警告音换成 + * 音乐。step 由调用方每 100ms 递增 1,内部对旋律总步数取模自动循环; + * 旋律中的空拍 BUZZER_P 由 buzzer_on() 解释为静音,用来断音。 */ +extern void buzzer_play_melody(uint16_t step); #endif diff --git a/底盘/Application/Task/Src/monitor_task.c b/底盘/Application/Task/Src/monitor_task.c index bdb07f0..8e51245 100644 --- a/底盘/Application/Task/Src/monitor_task.c +++ b/底盘/Application/Task/Src/monitor_task.c @@ -8,6 +8,8 @@ * 连接音效 = 遥控器上线瞬间两声上扬(M3->H3) * CAN 掉线蜂鸣(legacy 语义): 按设备序号 n 响 n 下,2s 一轮,每次只报 * 最先掉线的设备,设备序号表见 linkcheck_first_offline() + * 调试模式(DEBUG_BUZZER_MELODY=1,见 robot_param.h): 上述蜂鸣改为循环 + * 播放旋律,避免台架调试时连续滴滴声;红灯常亮等灯语不受影响 * 看门狗: IWDG 约 2.5s;上电 5s 宽限期无条件喂,之后仅当全部任务心跳正常 * 才喂——任何任务卡死都会复位,不会整车失控 * ========================================================================== */ @@ -170,10 +172,24 @@ void LED_Task(void const * argument) if (can_alarm) { led_set_red(1); - int8_t id = linkcheck_first_offline(); - if (id >= 0) + + /* 掉线设备序号(0 起)。旋律模式下不用它的返回值,仍保留调用: + * 一是调试时可直接在调试器里看 linkcheck 结果,二是避免该静态 + * 函数在 DEBUG_BUZZER_MELODY=1 时被判为未使用而报警告 */ + int8_t first_offline = linkcheck_first_offline(); + +#if DEBUG_BUZZER_MELODY + /* 调试模式:警告音替换为循环旋律(见 modules/BUZZER/buzzer.h)。 + * 红灯常亮与其它灯语不变,"哪台设备掉线"这一信息不会丢。 + * 步进用本任务自身的 100ms 节拍,不靠 HAL_GetTick 采样,避免周期 + * 抖动漏掉或重复某个音符 */ + static uint16_t melody_step = 0; + (void)first_offline; + buzzer_play_melody(melody_step++); +#else + if (first_offline >= 0) { - uint8_t n = (uint8_t)(id + 1); + uint8_t n = (uint8_t)(first_offline + 1); uint8_t w = counter % 20; // 2s 窗口 /* 第 j 声:占 w=[2j,2j+1],响 100ms 停 100ms */ if ((w / 2) < n && (w % 2) == 0) @@ -183,6 +199,7 @@ void LED_Task(void const * argument) } else buzzer_off(); +#endif } else { diff --git a/底盘/Application/robot_param.h b/底盘/Application/robot_param.h index 4123ea8..92fc320 100644 --- a/底盘/Application/robot_param.h +++ b/底盘/Application/robot_param.h @@ -125,6 +125,11 @@ #define DEBUG_SHOOT_WITHOUT_REFEREE 1 // 1=无裁判系统时也允许开摩擦轮(台架调试用),比赛请改 0 #define GIMBAL_RAMMER_INSTALLED 0 // 1=拨弹 M2006 已安装;0=暂缺,不参与掉线判定 +/* 1=调试模式:把 CAN 掉线警告音替换成循环播放的旋律(台架调试时避免连续滴滴声 + * 干扰)。红灯常亮与其它灯语完全不变,仍能看出是哪台设备掉线;比赛请改 0。 + * 旋律音符表见 modules/BUZZER/buzzer.c 的 buzzer_melody[] */ +#define DEBUG_BUZZER_MELODY 1 + /* ============================ 掉线检测 ============================ */ #define DEVICE_OFFLINE_TIME_MS 100 // CAN 设备/裁判系统掉线判定时间 #define CTOC_OFFLINE_TIME_MS 100 // 板间通讯掉线判定时间 diff --git a/底盘/modules/BUZZER/buzzer.c b/底盘/modules/BUZZER/buzzer.c index ab89931..59d82f6 100644 --- a/底盘/modules/BUZZER/buzzer.c +++ b/底盘/modules/BUZZER/buzzer.c @@ -42,3 +42,23 @@ void buzzer_off(void) { __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, 0); } + +/* ========================================================================== + * 调试用旋律(见 buzzer.h):每步 100ms,空拍 BUZZER_P 为静音。 + * 无源蜂鸣器只有单音,这里用"上行分解和弦 + 回落"拼成一句短旋律;选音限定 + * 在中音 3 ~ 高音 2,避免刺耳。循环播放不会漏掉"有设备掉线"这一事实, + * 因为红灯常亮由 monitor_task 独立控制,与该旋律无关。 + * 改旋律:直接增删这里的音符即可,长度会自动生效。 + * ========================================================================== */ +static const buzzer_tone_e buzzer_melody[] = { + BUZZER_M3, BUZZER_M5, BUZZER_M6, BUZZER_H1, BUZZER_P, + BUZZER_M6, BUZZER_H1, BUZZER_H2, BUZZER_P, + BUZZER_H1, BUZZER_M6, BUZZER_M5, BUZZER_M3, BUZZER_P, +}; + +void buzzer_play_melody(uint16_t step) +{ + const uint16_t steps = + (uint16_t)(sizeof(buzzer_melody) / sizeof(buzzer_melody[0])); + buzzer_on(buzzer_melody[step % steps]); +} diff --git a/底盘/modules/BUZZER/buzzer.h b/底盘/modules/BUZZER/buzzer.h index 33a4e07..a95b213 100644 --- a/底盘/modules/BUZZER/buzzer.h +++ b/底盘/modules/BUZZER/buzzer.h @@ -16,4 +16,10 @@ typedef enum extern void buzzer_init(void); extern void buzzer_on(buzzer_tone_e tone); extern void buzzer_off(void); + +/* ---- 调试用旋律 ---- + * 按固定 100ms/步 推进的短旋律(音符表见 buzzer.c),用于把掉线警告音换成 + * 音乐。step 由调用方每 100ms 递增 1,内部对旋律总步数取模自动循环; + * 旋律中的空拍 BUZZER_P 由 buzzer_on() 解释为静音,用来断音。 */ +extern void buzzer_play_melody(uint16_t step); #endif