1.概述
使用NUCLEO-L412开发板驱动无源蜂鸣器播放音乐,来掌握硬件PWM的配置、频率调节、占空比调节等操作。另外我们也了解了一下关于无源蜂鸣器的知识,关于音乐中的一些术语。
1.1.音符与频率的对应关系如下图所示,PWM输出某一频率到无源蜂鸣器后就产生了相对应的音调了
1.2.节拍是播放音调的时间占用比例,是乐曲中表示固定单位时值和强弱规律的组织形式。例如,2/4表示以4分音符为1拍 ,每小节有 2 拍。拍号中时值的实际时间,应视乐曲所标速度而定。
1.3.播放速度由单个节拍播放占用的时间所决定的,本程序中以125ms为一个基准,它的倍数关系做为一个节拍;可以通过调节这个时间基准来控制歌曲的播放速度。
2.硬件连接
说明:
使用的无源蜂鸣器模块,连接到NUCLEO-L412KB开发板上,使用3.3V供电,PWM引脚使用TIM1的CHANNEL2输出引脚PA9。
3.STM32CubeMX配置
3.1.配置TIM1及GPIO
3.2.配置PWM
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.一闪一闪亮晶晶