#include "device/buzzer.h" #include "bsp/time.h" #include /* USER INCLUDE BEGIN */ /* USER INCLUDE END */ /* USER DEFINE BEGIN */ /* USER DEFINE END */ #define MUSIC_DEFAULT_VOLUME 0.5f #define MUSIC_A4_FREQ 440.0f // A4音符频率 /* USER MUSIC MENU BEGIN */ // RM音乐 const Tone_t RM[] = { {NOTE_B, 5, 200}, {NOTE_G, 4, 200}, {NOTE_B, 5, 400}, {NOTE_G, 4, 200}, {NOTE_B, 5, 400}, {NOTE_G, 4, 200}, {NOTE_D, 5, 400}, {NOTE_G, 4, 200}, {NOTE_C, 5, 200}, {NOTE_C, 5, 200}, {NOTE_G, 4, 200}, {NOTE_B, 5, 200}, {NOTE_C, 5, 200} }; // Nokia 经典铃声音符 const Tone_t NOKIA[] = { {NOTE_E, 5, 125}, {NOTE_D, 5, 125}, {NOTE_FS, 4, 250}, {NOTE_GS, 4, 250}, {NOTE_CS, 5, 125}, {NOTE_B, 4, 125}, {NOTE_D, 4, 250}, {NOTE_E, 4, 250}, {NOTE_B, 4, 125}, {NOTE_A, 4, 125}, {NOTE_CS, 4, 250}, {NOTE_E, 4, 250}, {NOTE_A, 4, 500} }; /* USER MUSIC MENU END */ static void BUZZER_Update(BUZZER_t *buzzer){ buzzer->header.online = true; buzzer->header.last_online_time = BSP_TIME_Get_ms(); } // 根据音符和八度计算频率的辅助函数 static float BUZZER_CalcFreq(NOTE_t note, uint8_t octave) { if (note == NOTE_REST) { return 0.0f; // 休止符返回0频率 } // 将音符和八度转换为MIDI音符编号 int midi_num = (int)note + (int)((octave + 1) * 12); // 使用A4 (440Hz) 作为参考,计算频率 // 公式: freq = 440 * 2^((midi_num - 69)/12) float freq = 440.0f * powf(2.0f, ((float)midi_num - 69.0f) / 12.0f); return freq; } // 播放单个音符 static int8_t BUZZER_PlayTone(BUZZER_t *buzzer, NOTE_t note, uint8_t octave, uint16_t duration_ms) { if (buzzer == NULL || !buzzer->header.online) return DEVICE_ERR; float freq = BUZZER_CalcFreq(note, octave); if (freq > 0.0f) { // 播放音符 if (BUZZER_Set(buzzer, freq, MUSIC_DEFAULT_VOLUME) != DEVICE_OK) return DEVICE_ERR; if (BUZZER_Start(buzzer) != DEVICE_OK) return DEVICE_ERR; } else { // 休止符,停止播放 BUZZER_Stop(buzzer); } // 等待指定时间 BSP_TIME_Delay_ms(duration_ms); // 停止当前音符,为下一个音符做准备 BUZZER_Stop(buzzer); BSP_TIME_Delay_ms(20); // 短暂间隔 return DEVICE_OK; } int8_t BUZZER_Init(BUZZER_t *buzzer, BSP_PWM_Channel_t channel) { if (buzzer == NULL) return DEVICE_ERR; buzzer->channel = channel; buzzer->header.online = true; BUZZER_Stop(buzzer); return DEVICE_OK ; } int8_t BUZZER_Start(BUZZER_t *buzzer) { if (buzzer == NULL || !buzzer->header.online) return DEVICE_ERR; BUZZER_Update(buzzer); return (BSP_PWM_Start(buzzer->channel) == BSP_OK) ? DEVICE_OK : DEVICE_ERR; } int8_t BUZZER_Stop(BUZZER_t *buzzer) { if (buzzer == NULL || !buzzer->header.online) return DEVICE_ERR; BUZZER_Update(buzzer); return (BSP_PWM_Stop(buzzer->channel) == BSP_OK) ? DEVICE_OK : DEVICE_ERR; } int8_t BUZZER_Set(BUZZER_t *buzzer, float freq, float duty_cycle) { if (buzzer == NULL || !buzzer->header.online) return DEVICE_ERR; int result = DEVICE_OK ; BUZZER_Update(buzzer); if (BSP_PWM_SetFreq(buzzer->channel, freq) != BSP_OK) result = DEVICE_ERR; if (BSP_PWM_SetComp(buzzer->channel, duty_cycle) != BSP_OK) result = DEVICE_ERR; return result; } int8_t BUZZER_PlayMusic(BUZZER_t *buzzer, MUSIC_t music) { if (buzzer == NULL || !buzzer->header.online) return DEVICE_ERR; const Tone_t *melody = NULL; size_t melody_length = 0; // 根据音乐类型选择对应的音符数组 switch (music) { case MUSIC_RM: melody = RM; melody_length = sizeof(RM) / sizeof(Tone_t); break; case MUSIC_NOKIA: melody = NOKIA; melody_length = sizeof(NOKIA) / sizeof(Tone_t); break; default: return DEVICE_ERR; } // 播放整首音乐 for (size_t i = 0; i < melody_length; i++) { if (BUZZER_PlayTone(buzzer, melody[i].note, melody[i].octave, melody[i].duration_ms) != DEVICE_OK) { BUZZER_Stop(buzzer); // 出错时停止播放 return DEVICE_ERR; } } // 音乐播放完成后停止 BUZZER_Stop(buzzer); return DEVICE_OK; } /* USER FUNCTION BEGIN */ /* USER FUNCTION END */