基于51单片机-蜂鸣器演奏《飞雪玉花》
1.曲谱
2.代码
//2025.6.27
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"//声明引脚
sbit Buzzer=P2^5;//设置一个宏,修改演奏速度,越小越快
//默认一般不修改, 500代表500ms,四分音符的持续时间-->正常音乐时间
#define SPEED 500//音符与索引对应表,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//下述频率为C大调(仅包括白色键盘,没有黑色键盘)
//将低、中、高36组音调对应的高电平持续时间(即定时器初始值)写成列表
unsigned int FreqTable[] = {0,63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};//
//风花雪月曲谱
//对应音调的选取索引顺序 ,以及每个音调对应的时长(以1/16音符的为基准作为一个时长)
unsigned char code Music[] = {//音符,时值//1//1-1M6, 2,M5, 2,M2, 4+2,H1, 2,M7, 2,M5, 2,//1-2M3, 2,M2, 2,M3, 4+4+4,//1-3M6, 2,M5, 2,M2, 4+2,H1, 2,M7, 2,M5, 2,//1-4M3, 2,M2, 2,M3, 4+4+4,//2//2-1H1, 2+1,M7, 1,M6, 4+2,M7, 2,M6, 2,M7, 1,M6, 1,//2-2M5, 2,M2, 2,M3, 2,M5, 2, M2, 2,M1, 2,L6, 4,//2-3M6, 2,M3, 2,M2, 2,M3, 2,M2, 2,L6, 2,M2, 4,//2-4M3, 4,L6, 4+4+4,//3//3-1M6, 2,M5, 2,M2, 4+2,H1, 2,M7, 2,M5, 2,//3-2M3, 2,M2, 2,M3, 4+4+4,//3-3M6, 2,M5, 2,M2, 4+2,H1, 2,M7, 2,M5, 2,//3-4M3, 2,M2, 2,M3, 4+4+4,//4//4-1H1, 2+1,M7, 1,M6, 4+2,M7, 2,M6, 2,M7, 1,M6, 1,//4-2M5, 2,M2, 2,M3, 2,M5, 2,M2, 2,M1, 2,L6, 4,//4-3M6, 2,M3, 2,M2, 2,M3, 2,M2, 2,L6, 2,M2, 4,//4-4M3, 4,L6, 4+4+4,//5//5-1M6, 2,M5, 2,M3, 2,M2, 2,M5, 2,M3, 2,M2, 4,//5-2M6, 2,M5, 2,M2, 2,M1, 2,M5, 2,M2, 2,M1, 4,//5-3M2, 2,M1, 2,L6, 2,M6, 2,M5, 2,M3, 2,M2, 4,//5-4M3, 2,M5, 2,M3, 4+4+4,//6//6-1M6, 2,M5, 2,M3, 2,M2, 2,M5, 2,M3, 2,M2, 4,//6-2H1, 2+1,M7, 1,M3, 2,M2, 2,M6, 2,M5, 2,M1, 4,//6-3L6, 2,M3, 2,M2, 2,M3, 2,M2, 2,L6, 2,M3, 4,//6-4L6, 2,M2, 2,M3, 4+4+4,//7//7-1M6, 2,M5, 2,M3, 2,M2, 2,M5, 2,M3, 2,M2, 4,//7-2H1, 2+1,M7, 1,M3, 2,M2, 2,M6, 2,M5, 2,M1, 4,//7-3M2, 2,M1, 2,L6, 2,M6, 2,M5, 2,M3, 2,M2, 4,//8//8-1M3, 2,M5, 2,M6, 4+4+4,//8-2M6, 4+4,P, 4,P, 4,0xFF, //终止符,表示音乐播放结束};unsigned char FreqSelect,MusicSelect;void main()
{ Timer0Init();while(1){ if (Music[MusicSelect]!=0xFF) //当索引为0xFF,表示音乐结束,停止播放{FreqSelect = Music[MusicSelect]; MusicSelect++;Delay(SPEED/4*Music[MusicSelect]);//将Delay(500)换为上述的延时方法,则可以灵活指定每个音符的持续时间//个人:好像使用二维数组会比较好看MusicSelect++;TR0=0;Delay(5);TR0=1;}else //若为终止符,则死循环{TR0=0; //关闭定时器while(1);}}
}void Timer0_Routine() interrupt 1
{ if (FreqTable[FreqSelect]) //如果选择的音符不是0,才执行下面语句,若为0,则为休止符,不发出声音{TL0 = FreqTable[FreqSelect]%256; //设置定时初值TH0 = FreqTable[FreqSelect]/256; //设置定时初值Buzzer=!Buzzer; }}
效果:
感觉还行
说明:
由于使用的音调频率是C调,因此会有有些误差,后续有机会改为G调
参考资料
1.江科大
[11-2] 蜂鸣器播放提示音&音乐_哔哩哔哩_bilibili
2.【飞雪玉花】秦时明月配乐动态谱_哔哩哔哩_bilibili