目录
随着最近孤勇者成为小朋友们的接头暗号之后,于是产生了利用单片机去播放孤勇者的想法,接下来我们来看看具体的实现以及效果展示吧!
硬件部分
蜂鸣器介绍
首先我们使用的是51单片机的蜂鸣器来实现的,所以先来介绍一下蜂鸣器吧,如下图所示!
- 蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号
- 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器
- 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定
- 无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音
之前在STM32上的那个蜂鸣器是有源蜂鸣器,频率固定,就只能发声,而在我们的51单片机上的这个蜂鸣器是属于无源蜂鸣器,所以需要我们来调整频率,从而来实现发出不同频率的声音。
驱动电路
之前的32是使用三极管进行驱动的,起到放大信号的作用(不清楚的可以去32的笔记看看)。而51单片机使用的是集成电路进行驱动的(ULN2003),接下来我们来简单介绍一下吧!
ULN2003
确实可以简单理解为一个放大电路,因为内部有一个非门,导致给1就有驱动能力(输出0,蜂鸣器才导通,所以才会响),但给0却无驱动能力(高阻态)。
乐理部分
接下来就到了单片机最难的部分了,乐理部分,这部分我不是特别清楚,如有错误还望指出。
首先,每8个一组(C~B),也就是哆唻咪发嗦啦西,分为4组,每一组比上一组高8度。黑键与白键相差半个音调,白色与白色相差一个音调。简谱对应相应的音调也在图中有对应关系,就不一一举出了。但是要介绍一下升音符号(#)以及降音符号(b),比如“#1”就是中央C升高半音,就是右上角的黑键。
音符
音符是用来记录不同长短的音的进行符号。全音符、二分音符、四分音符、八分音符、十六分音符是最常见的音符,具体的内容大家可以点击超链接去康康。其中四分音符一般是一个时间基准(500毫秒),后面加一个横线就是二分音符,下面加一个横线就是八分音符,以此类推。
音符与频率对照
计算周期以及重装载值
周期:12/11.0592/B2*1000000(因为我是11.0592HZ的晶振,所以是这样)
重装载值:65536-D2(65536-周期一半)
如下图所示:
代码部分
接下来就是按照我们计算之后的重装载值来进行编码了,在此过程中,还需要我们去了解音乐的简谱,在此我就给出一份简谱,感兴趣的同学可以自己去找相应的简谱来编写代码。
-
// Buzzer.c
-
#include <REGX52.H>
-
#include <INTRINS.H>
-
-
//蜂鸣器端口:
-
sbit Buzzer=P1^
5;
-
-
/**
-
* @brief 蜂鸣器私有延时函数,延时500us
-
* @param 无
-
* @retval 无
-
*/
-
void Buzzer_Delay500us() //@11.0592MHz
-
{
-
unsigned
char i;
-
-
_nop_();
-
i =
227;
-
while (--i);
-
}
-
-
-
/**
-
* @brief 蜂鸣器发声
-
* @param ms 发声的时长,范围:0~32767
-
* @retval 无
-
*/
-
void Buzzer_Time(unsigned int ms)
-
{
-
unsigned
int i;
-
for(i=
0;i<ms*
2;i++)
-
{
-
Buzzer=!Buzzer;
-
Buzzer_Delay500us();
-
}
-
}
-
// main.c
-
#include <REGX52.H>
-
#include "Delay.h"
-
#include "Time0.h"
-
#include "Buzzer.h"
-
-
//蜂鸣器端口:
-
sbit Buzzer=P1^
5;
-
-
#define SPEED 460
-
//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
-
#define P 0
-
#define L1 1
-
#define L1_ 2
-
#define L2 3
-
#define L2_ 4
-
#define L3 5
-
#define L4 6
-
#define L4_ 7
-
#define L5 8
-
#define L5_ 9
-
#define L6 10
-
#define L6_ 11
-
#define L7 12
-
#define M1 13
-
#define M1_ 14
-
#define M2 15
-
#define M2_ 16
-
#define M3 17
-
#define M4 18
-
#define M4_ 19
-
#define M5 20
-
#define M5_ 21
-
#define M6 22
-
#define M6_ 23
-
#define M7 24
-
#define H1 25
-
#define H1_ 26
-
#define H2 27
-
#define H2_ 28
-
#define H3 29
-
#define H4 30
-
#define H4_ 31
-
#define H5 32
-
#define H5_ 33
-
#define H6 34
-
#define H6_ 35
-
#define H7 36
-
unsigned
int FreqTable[] = {
0,
-
64303 ,
63577 ,
63691 ,
63792 ,
63892 ,
63981 ,
64070 ,
64152 ,
64229 ,
64303 ,
64372 ,
64437 ,
-
64499 ,
64557 ,
64612 ,
64664 ,
64713 ,
64759 ,
64803 ,
64844 ,
64883 ,
64919 ,
64954 ,
64987 ,
-
65018 ,
65047 ,
65074 ,
65100 ,
65125 ,
65148 ,
65169 ,
65190 ,
65209 ,
65228 ,
65245 ,
65261
-
};
-
-
-
// 第一个H2意思是频率;第二个4,代表一个4分音符;code是把代码放到Flash里面。
-
unsigned
char code Music[]={
-
H2,
4,
-
M7,
4,
-
H1,
4,
-
M6,
4,
-
-
H2,
4,
-
M7,
4,
-
H1,
4,
-
M6,
4,
-
// // 注释部分是高潮的前面部分
-
// M3,4+4+4+4,
-
// P,4+4,
-
// P,2,
-
// M1,2,
-
// M2,2,
-
// M1,2,
-
// M3,4+4+4+4,
-
// P,4+2,
-
// M1,2,
-
// M2,2,
-
// M1,2,
-
// M2,2,
-
// M3,2,
-
// //
-
// L6,4+2,
-
// M1,2,
-
// L6,4+2,
-
// M1,2,
-
//
-
// L6,4+2,
-
// M1,2,
-
// M2,4,
-
// M1,4,
-
//
-
// L7,4+4+4+4,
-
// P,4+4+4+4,
-
//
-
// //
-
// M3,4+4+4+4,
-
// P,4+4,
-
// P,2,
-
// M1,2,
-
// M2,2,
-
// M1,2,
-
// M3,4+4+4+4,
-
// P,4+2,
-
// M1,2,
-
// M2,2,
-
// M1,2,
-
// M2,2,
-
// M3,2,
-
// //
-
// L6,4+2,
-
// M1,2,
-
// L6,4+2,
-
// M1,2,
-
//
-
// L6,4+2,
-
// M1,2,
-
// M3,4,
-
// M1,2,
-
// M2,2,
-
//
-
// L7,4+4+4+4,
-
// P,4+4+4+4,
-
//
-
// H6,2,
-
// M1,2,
-
// M6,4+2+2+2,
-
// M5, 2,
-
//
-
// M6,4+2,
-
// M5,2,
-
// M6,2,
-
// M5,2,
-
// M6,2,
-
//
-
// M5,2+2,
-
// M3,2+2+4+4,
-
// P,4+4+4,
-
// H6,2,
-
// M1,2,
-
//
-
// M6,4+2+2,
-
// M5,2,
-
// M6,2,
-
// M5,2,
-
-
// M7,4+2+2,
-
// M6,2,
-
// M7,2+2,
-
// M6,4,
-
// M3,2+2+4,
-
//
-
// P,4+4+2,
-
// M3,2,
-
// M5,2,
-
// M3,2,
-
//
-
// M2,4+2,
-
// M3,2,
-
// M2,4+2,
-
// M3,2,
-
-
// M2,4+2,
-
// M3,2,
-
// M5,2,
-
// M3,2,
-
// M5,2,
-
// M3,2,
-
//
-
// M2,4+2,
-
// M3,2,
-
// M2,4+2,
-
// M3,2,
-
//
-
// M2,4+4+4,
-
// M1,2,
-
// M2,2,
-
// //
-
// M3,4,
-
// M6,4,
-
// M1,4,
-
// M3,2,
-
-
// M2,4+2,
-
// M3,2,
-
// M2,4,
-
// M1,4,
-
-
// M6,4+4+4+4,
-
-
-
-
-
-
// 高潮部分
-
P,
4+
4+
4,
-
M6,
2,
-
M7,
2,
-
//
-
M1,
2,
-
M2,
2,
-
M7,
2,
-
M1,
2+
4+
2,
-
M7,
2,
-
-
M1,
2,
-
M2,
2,
-
M7,
2,
-
M1,
2+
4+
2,
-
M2,
2,
-
-
M3,
2,
-
M2,
2,
-
M3,
2,
-
M2,
2,
-
M3,
4+
2,
-
M2,
2,
-
-
M3,
4,
-
M5,
4,
-
M3,
4,
-
M6,
2,
-
M7,
2,
-
//
-
M1,
2,
-
M2,
2,
-
M7,
2,
-
M1,
2+
4+
2,
-
M7,
2,
-
-
M1,
2,
-
M2,
2,
-
M7,
2,
-
M1,
2+
4+
2,
-
M2,
2,
-
-
M3,
2,
-
M2,
2,
-
M3,
2,
-
M2,
2,
-
M3,
4+
2,
-
M2,
2,
-
-
M3,
4,
-
M5,
4,
-
M3,
4,
-
M5,
4,
-
//
-
M3,
2+
4,
-
M5,
2,
-
M3,
2+
4,
-
M5,
2,
-
-
M3,
2,
-
M5,
2,
-
M6,
2,
-
M3,
2,
-
M5,
4,
-
M5,
4,
-
-
M3,
2+
4,
-
M5,
2,
-
M3,
2+
4,
-
M5,
2,
-
//
-
M3,
2,
-
M5,
2,
-
M6,
2,
-
M3,
2,
-
M5,
4,
-
M5,
2+
2,
-
//
-
M3,
4,
-
M2,
4,
-
M2,
4,
-
M1,
2,
-
M3,
2,
-
-
M3,
4,
-
M2,
4,
-
M2,
4,
-
M1,
2,
-
M1,
2,
-
-
L6,
4+
4+
4+
4,
-
P,
4+
4+
4,
-
M5,
2+
2,
-
-
//
-
M3,
4,
-
M2,
4,
-
M2,
4,
-
M1,
2,
-
M3,
2,
-
-
M3,
4,
-
M2,
4,
-
M2,
4,
-
M1,
2,
-
M1,
2,
-
-
L6,
4+
4+
4+
4,
-
P,
4+
4+
4+
4,
-
-
0xFF
-
};
-
-
-
-
-
unsigned
char FreqSelect,MusicSelect;
-
void main(){
-
// 初始化定时器
-
Timer0Init();
-
while(
1){
-
// 判断是否是休止符
-
if(Music[MusicSelect] !=
0xFF){
-
//发声
-
FreqSelect = Music[MusicSelect];
-
MusicSelect++;
-
//持续时长
-
Delay(SPEED/
4*Music[MusicSelect]);
-
MusicSelect++;
-
TR0 =
0;
-
Delay(
5);
-
TR0 =
1;
-
}
else{
-
TR0 =
0;
-
while(
1);
-
}
-
}
-
-
}
-
-
-
void Timer0_Routine() interrupt 1
-
{
-
if(FreqTable[FreqSelect]){
-
TL0 = FreqTable[FreqSelect] %
256;
//设置定时初始值
-
TH0 = FreqTable[FreqSelect] /
256;
-
Buzzer =! Buzzer;
// 响
-
}
-
-
}
运行结果
蜂鸣器《孤勇者》
好了,对于蜂鸣器的知识就介绍到这了,如有错误还望及时指出。
转载:https://blog.csdn.net/weixin_66578482/article/details/125715157