前言
最近我在学习51单片机蜂鸣器模块的相关知识,正值清明节到来之际,我根据所学内容并对照歌曲简谱,成功实现了《清明雨上》的播放,所以把代码分享给大家娱乐一下。
完整代码
这是主函数main.c的代码,延时函数、定时器模块的代码在我定时器部分的博客有。
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
//蜂鸣器端口定义
sbit Buzzer=P2^5;
//播放速度,值为四分音符的时长(ms)
#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
//索引与频率对照表
unsigned int FreqTable[]={
0,
63777,63872,63969,64054,64140,64216,64291,64360,64426,64489,64547,64603,
64655,64704,64751,64795,64837,64876,64913,64948,64981,65012,65042,65070,
65095,65120,65144,65166,65186,65206,65225,65242,65259,65274,65289,65303
};
//乐谱
unsigned char code Music[]={
//音符,时值,
M2, 2,
M3, 2,
M5, 1+1,
M6, 2,
M2, 2,
M3, 2,
M5, 1+1,
M6, 2,
M3, 4,
M2, 4,
M1, 4,
M1, 2,
M1, 2,
M6, 2,
M6, 2,
M6, 2,
M5, 2,
M5, 2,
M3, 2,
M2, 2,
M1, 1,
M3, 1,
M3,4+4,
P,4,
P,4,
M2, 2,
M3, 2,
M5, 1+1,
M6, 2,
M2, 2,
M3, 2,
M5, 1+1,
M6, 2,
M3,2,
M2,2,
M3,2,
M5,2,
M1,4,
P,2,
M1,2,
M6,2,
M6,2,
M6,2,
M5,2,
M5,2,
M3,2,
M2,2,
M3,1,
M2,1,
M1,4+4,
P,4,
P,4,
M3,1,
M5,2,
M3,1,
M5,2,
M3,2,
M6,4,
M3,2,
M2,2,
M1,2,
L6,2,
M1,2,
M5,2,
M3,4+4,
M6, 2,
M6, 2,
M6, 2,
M5, 2,
M6, 2,
M6, 2,
H3, 2,
H1, 2,
H2, 4+4,
P,4,
M5, 2,
M6, 2,
H5,2+1,
H3,1+2,
M6,2,
H2,4,
H2,2,
H1,2,
M7,2,
M5,2,
H2,1,
H3,2,
H1,1+4,
H1,2,
H2,2,
H3,2+1,
H2,1+2,
H1,2,
H2,2,
H1,2,
H5,2,
H6,2+2,
H3,2+4,
P,4,
M5,2,
M6,2,
H5,3,
H3,1+2,
M6,2,
H2,4,
H2,2,
H1,2,
M7,2,
M5,2,
H2,1,
H3,2,
H1,1+4,
P,2,
M6,2,
H3,2,
H1,2,
H1,1,
M6,1,
M6,2,
H3,2,
H1,2,
H1,2,
M6,2+2,
H1,2+4,
H1,4,
M5,2,
M6,2,
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; //翻转蜂鸣器IO口
}
}
简谱如下:
我只完成了歌曲歌词第一部分的曲子代码,后面的感兴趣的同学可以继续编写。