STM32无源蜂鸣器播放音乐

目录

 

 

1.STM32产生PWM波驱动无源蜂鸣器使其发声

2.音乐播放原理 

3.音乐文件制作(播放自己喜欢的音乐)

4.用蜂鸣器播放音乐

 

 

 

 


1.STM32产生PWM波驱动无源蜂鸣器使其发声

1)查看原理图,找到对应引脚(我这里时PA1)

2)打开CubeMax,输入自己芯片的类型确定后,配置好系统时钟RCC,我这里是80Mhz,找到相应引脚PA1设置为GPIO_Output模式(用来切换引脚状态,使蜂鸣器发声),

3)设置定时器我这里用TM2

 

2.音乐播放原理 

原理:给无源蜂鸣器输入不同频率的PWM波(构成不同音调)  让PWM波持续不同长度的时间(构成节拍)

3.音乐文件制作(播放自己喜欢的音乐)

 

 

  (1)1=F,表示这首曲子是F调的。

          3/4,是表示这首曲子是34拍。

(2)音符下面有一条横线,这个表示的是节拍

             下面没有线的音符,叫做四分音符,也就是一拍,如果用数组来表示节拍时一般用4来表示一拍(当然可根据自己喜好来定)

             下面有一根横线的音符,叫八分音符,是半拍,如果用数组来表示节拍时一般用2来表示半拍(当然可根据自己喜好来定)

(3)音符上面有一个点。上面有点的是高音下面有点的是低音没有点的是中音。(对应的音区,我们称之为低音区,中音区,高音区,看图更易懂)

 

  查看百度文库文库:歌谱中所有音调对应的频率

(4)音符后面有一根短横线。这个叫做延音线,意思就是唱到这里得拖长音。
             延音线在节拍数组中一般省略不写
(5)0。叫做休止符,就是停顿不唱,等待下一段节奏再唱。如果用数组来表示节拍时一般用4来表示休止符,当然可根据自己喜好来定

4.用蜂鸣器播放音乐

play_music.h

#ifndef _PLAY_MUSIC_H
#define _PLAY_MUSIC_H
#include "stdlib.h"	 
typedef unsigned char   u8; 
typedef unsigned short  u16;
typedef unsigned long   u32;
void Sound(u16 frq);
void PlayMusic_birthday(void);
#endif

 play_music.c 

#include "play_music.h"
#include "tim.h"
#include <stdio.h>

void delay_us(uint16_t us)
{
    uint16_t differ = 0xFFFF-us;/*251,669,935*/

    HAL_TIM_Base_Start(&htim2);

    __HAL_TIM_SetCounter(&htim2, differ);

    while( differ < 0xFFFF )
    {
        differ=__HAL_TIM_GetCounter(&htim2);
    }

    HAL_TIM_Base_Stop(&htim2);
}

/*通过STM32的GPIO引脚快速切换高低电平输出就能实现无源蜂鸣器的发声,切换的频率不同,发出的音调就不一样。*/
void Sound(u16 frq)
{           
	u32  n;         
	if(frq  != 1500) //如果频率不为1000则按频率输出,否则只延时        
	{                    
		n  = 500000/((u32)frq);                     
		HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_RESET);		
		delay_us(n);                     
		HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_SET);                
		delay_us(n);      
	}
	else                 
		delay_us(1000);			
}

void PlayMusic_birthday(void)
{	 
		u16  tone[]  = {
				 523, 587, 659, 698, 784, 880, 988, 1046 };
                 /*   	         低5  低6  低7   中1  中2  中3  中4  中5
		  *               0    1    2    3    4    5    6    7   
		  *这里最容易出错的地方是我把数组中的第一个元素当成了1而不是0*/
		u16  music[] = {
				 0,0,1,0,3,2,
				 0,0,1,0,4,3,
				 0,0,7,5,3,2,1,
				 6,6,5,3,4,3
		};
	        u16  time[]  = {
				 2,2,4,4,4,8,
				 2,2,4,4,4,8,
				 2,2,4,4,4,4,4,
				 2,2,4,4,4,8	
		};
		u32  yanshi;
		u16  i,e;           
		yanshi  = 10; 
		
/*1.依次从音调数组中取music[i],
 *2.然后根据music[i]的值在tone数组中得到该音的发声频率(tone[music[i]]),
 *3.调用sound函数控制蜂鸣器发声,
 *4.声音的发声时间有time数组控制
 ***/

		for(i=0;i<sizeof(music)/sizeof(music[0]);i++)
		{                     
			for(e=0;e<((u16)time[i])*tone[music[i]]/yanshi;e++)
			{                              
				Sound((u32)tone[music[i]]);                     
			}                  
		}
}