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]]);
}
}
}
目录