1.概述
使用NUCLEO-L412开发板驱动无源蜂鸣器播放音乐,来掌握硬件PWM的配置、频率调节、占空比调节等操作。另外我们也了解了一下关于无源蜂鸣器的知识,关于音乐中的一些术语。
1.1.音符与频率的对应关系如下图所示,PWM输出某一频率到无源蜂鸣器后就产生了相对应的音调了
![4.png 4.png](https://static.assets-stash.eet-china.com/forum/201905/19/105253kqgvgl6tag6uas7v.png)
1.2.节拍是播放音调的时间占用比例,是乐曲中表示固定单位时值和强弱规律的组织形式。例如,2/4表示以4分音符为1拍 ,每小节有 2 拍。拍号中时值的实际时间,应视乐曲所标速度而定。
1.3.播放速度由单个节拍播放占用的时间所决定的,本程序中以125ms为一个基准,它的倍数关系做为一个节拍;可以通过调节这个时间基准来控制歌曲的播放速度。
2.硬件连接
![1.jpg 1.jpg](https://static.assets-stash.eet-china.com/forum/201905/19/103414ieitwe1y0hkxehnh.jpg)
说明:
使用的无源蜂鸣器模块,连接到NUCLEO-L412KB开发板上,使用3.3V供电,PWM引脚使用TIM1的CHANNEL2输出引脚PA9。
3.STM32CubeMX配置
3.1.配置TIM1及GPIO
![2.png 2.png](https://static.assets-stash.eet-china.com/forum/201905/19/103429zt8uytpjwqfq2q2u.png)
3.2.配置PWM
![3.png 3.png](https://static.assets-stash.eet-china.com/forum/201905/19/103434qblmtlaoatlhyvt4.png)
4.编写驱动程序
/** ****************************************************************************** * @file buzzer.h * @version V1.00 * @author xld0932 * @brief ****************************************************************************** * @attention * * Copyright (c) 2019. All rights reserved. * ****************************************************************************** */ /* Define to prevent recursive inclusion ------------------------------------*/ #ifndef __BUZZER_H__ #define __BUZZER_H__ #undef EXTERN #ifdef __BUZZER_C__ #define EXTERN #else #define EXTERN extern #endif /* Includes -----------------------------------------------------------------*/ #include "platform.h" /* Exported constants -------------------------------------------------------*/ /* Exported defines ---------------------------------------------------------*/ /* Exported typedef ---------------------------------------------------------*/ typedef struct { uint16_t Do; uint16_t Re; uint16_t Mi; uint16_t Fa; uint16_t So; uint16_t La; uint16_t Si; } sNOTE; /* Exported macro -----------------------------------------------------------*/ /* Exported functions prototypes --------------------------------------------*/ EXTERN void BUZZER_Init(void); #endif /*********************** (C) COPYRIGHT ************************END OF FILE****/
复制代码/** ****************************************************************************** * @file buzzer.c * @version V1.00 * @author xld0932 * @brief ****************************************************************************** * @attention * * Copyright (c) 2019. All rights reserved. * ****************************************************************************** */ /* Define to prevent recursive inclusion ------------------------------------*/ #define __BUZZER_C__ /* Includes -----------------------------------------------------------------*/ #include "BUZZER.h" /* Private constants --------------------------------------------------------*/ /* Private defines ----------------------------------------------------------*/ /* Private typedef ----------------------------------------------------------*/ /* Private macro ------------------------------------------------------------*/ /* Private variables --------------------------------------------------------*/ const sNOTE LoCTune = { 262, 294, 330, 349, 392, 440, 494}; const sNOTE MiCTune = { 523, 587, 659, 698, 784, 880, 988}; const sNOTE HiCTune = {1046, 1175, 1318, 1397, 1568, 1760, 1976}; const uint16_t CTune[] = { 1, //0 262, //1.Do ---Low 294, //2.Re 330, //3.Mi 349, //4.Fa 392, //5.So 440, //6.La 494, //7.Si 0, //8 0, //9 0, //10 523, //11.Do ---Middle 587, //12.Re 659, //13.Mi 698, //14.Fa 784, //15.So 880, //16.La 988, //17.Si 0, //18 0, //19 0, //20 1046, //21.Do ---High 1175, //22.Re 1318, //23.Mi 1397, //24.Fa 1568, //25.So 1760, //26.La 1976, //27.Si }; /** * 《一闪一闪亮晶晶》音符 */ const uint16_t MusicNote1[] = { 1,0,1,0,5,0,5,0,6,0,6,0,5,0, 4,0,4,0,3,0,3,0,2,0,2,0,1,0, 5,0,5,0,4,0,4,0,3,0,3,0,2,0, 5,0,5,0,4,0,4,0,3,0,3,0,2,0, 1,0,1,0,5,0,5,0,6,0,6,0,5,0, 4,0,4,0,3,0,3,0,2,0,2,0,1,0, }; /** * 《一闪一闪亮晶晶》节拍 */ const uint8_t MusicBeat1[] = { 3,1,3,1,3,1,3,1,3,1,3,1,7,1, 3,1,3,1,3,1,3,1,3,1,3,1,7,1, 3,1,3,1,3,1,3,1,3,1,3,1,7,1, 3,1,3,1,3,1,3,1,3,1,3,1,7,1, 3,1,3,1,3,1,3,1,3,1,3,1,7,1, 3,1,3,1,3,1,3,1,3,1,3,1,7,8, }; /** * 《粉刷匠》音符 */ const uint16_t MusicNote2[] = { 5,3,5,3,5,3,1,2,4,3,2,5,0, 5,3,5,3,5,3,1,2,4,3,2,1,0, 2,2,4,4,3,1,5,2,4,3,2,5,0, 5,3,5,3,5,3,1,2,4,3,2,1,0, }; /** * 《粉刷匠》节拍 */ const uint8_t MusicBeat2[] = { 2,2,2,2,2,2,4,2,2,2,2,8,1, 2,2,2,2,2,2,4,2,2,2,2,8,1, 2,2,2,2,2,2,4,2,2,2,2,8,1, 2,2,2,2,2,2,4,2,2,2,2,4,8, }; /** * 《爱是你我》音符 */ const uint16_t MusicNote3[] = { 11,7,0,5,3,3,3,3,3,6,6,6,6,11,5,3,3,3,3,3, 11,7,0,5,6,7,6,6,0,6,2,2,2,2,2,1,6,2,3,3, 3,3,3,11,7,6,13,12,12,6,11,12,7,5,5,6,6,6,13,13, 11,6,13,12,12,12,12,12,6,6,7,12,7,7,7,0,11,6,6,6, 6,0,0,13,16,16,16,16,16,16,16,15,16,16,13,13,13,13,13,13, 13,13,16,16,16,16,16,16,15,16,15,15,15,15,15,15,15,16,13,12, 13,11,16,6,0,3,5,3,5,5,6,11,6,12,13,0,16,16,15,13, 12,13,15,13,13,13,13,0,12,11,12,12,13,11,6,5,6,12,12,12, 12,13,11,6,0,12,13,5,3,3,12,12,13,11,6,6,13,16,15,15, 15,15,15,15,15,12,13,5,3,0,11,6,6,6,6,6,12,13,5,3, 0,11,6,6,6,6,6,0, }; /** * 《爱是你我》节拍 */ const uint8_t MusicBeat3[] = { 4,4,1,2,2,2,4,4,4,2,2,4,2,2,2,2,2,2,2,2, 4,4,2,2,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,2, 4,4,4,4,4,2,4,4,4,2,4,2,4,4,2,4,2,4,2,2, 4,2,4,4,2,2,4,4,2,2,2,4,2,4,4,4,4,4,2,2, 4,4,4,4,2,4,2,2,4,4,4,4,4,4,4,2,2,4,4,4, 2,2,4,4,2,2,4,4,2,2,2,4,2,2,2,4,4,4,4,4, 4,2,2,4,2,2,2,2,4,2,2,4,4,4,2,2,4,4,4,4, 4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,4,4,4,4,4, 2,2,4,4,4,2,2,4,2,2,4,2,2,2,2,4,4,2,2,2, 2,2,2,2,2,2,2,4,4,4,4,2,2,2,2,2,2,2,4,4, 4,4,4,4,4,4,4,8, }; /* Private function prototypes ----------------------------------------------*/ /* Exported variables -------------------------------------------------------*/ extern TIM_HandleTypeDef htim1; /* Exported function prototypes ---------------------------------------------*/ /** * @brief : * @param : * @returns: * @details: */ void BUZZER_SetFrequency(uint16_t freq) { uint32_t Period = 1000000 / freq; uint16_t Pulse = Period / 2; /* Set the Autoreload value , frequency*/ TIM1->ARR = Period; /* Set the Capture Compare Register value , duty */ TIM1->CCR2 = Pulse; } /** * @brief : * @param : * @returns: * @details: */ void BUZZER_Init(void) { uint16_t i = 0; /** * 打开PWM,准备播放音乐 */ HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); /** * 播放《一闪一闪亮晶晶》 */ for(i = 0; i < sizeof(MusicBeat1); i++) { BUZZER_SetFrequency(CTune[MusicNote1[i]]); HAL_Delay(MusicBeat1[i] * 125); } /** * 播放《粉刷匠》 */ for(i = 0; i < sizeof(MusicBeat2); i++) { BUZZER_SetFrequency(CTune[MusicNote2[i]]); HAL_Delay(MusicBeat2[i] * 125); } /** * 播放《爱是你我》 */ for(i = 0; i < sizeof(MusicBeat3); i++) { BUZZER_SetFrequency(CTune[MusicNote3[i]]); HAL_Delay(MusicBeat3[i] * 125); } /** * 关闭PWM,停止播放音乐 */ HAL_TIM_PWM_Stop( &htim1, TIM_CHANNEL_2); } /*********************** (C) COPYRIGHT ************************END OF FILE****/
复制代码5.播放效果
5.1.一闪一闪亮晶晶
![一闪一闪亮晶晶.jpg 一闪一闪亮晶晶.jpg](https://static.assets-stash.eet-china.com/forum/201905/19/104411iu24bxknt4ubhtku.jpg)
![](static/image/filetype/rar.gif)