1 现象
利用蜂鸣器实现音乐播放功能,播放《天空之城》。
2 原理
(1)天空之城的乐谱
3 参考程序
3.1 主程序
#include
#include "delayms.h"
#include "timer0.h"
//蜂鸣器端口定义
sbit buzzer = P2^5;
//播放速度,值为四分音符的时长
#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,
63472,63584,63697,63797,63897,63987,64074,64156,64233,64307,64376,64441,
64502,64560,64615,64667,64715,64761,64805,64846,64885,64921,64956,64989,
65020,65048,65076,65102,65126,65149,65171,65191,65210,65229,65246,65262
};
//乐谱,天空之城,频率,音长
unsigned char code Music[]={
//第1行
P, 4, P, 4, P, 4, M6, 2, M7, 2,
H1, 4+2,M7, 2, H1, 4, H3, 4,
M7, 4+4+4, M3, 2, M3, 2,
//第2行
M6, 4+2,M5, 2, M6, 4, H1, 4,
M5, 4+4+4, M3, 4,
M4, 4+2,M3, 2, M4, 4, H1, 4,
//第3行
M3, 4+2,P, 2, H1, 2, H1, 2, H1, 2,
M7, 4+2,M4_,2, M4_,4, M7, 4,
M7, 4+4,P, 4, M6, 2, M7, 2,
//第4行
H1, 4+2,M7, 2, H1, 4, H3, 4,
M7, 4+4+4, M3, 2, M3, 2,
M6, 4+2, M5, 2, M6, 4, H1, 4,
//第5行
M5, 4+4+4, M2, 2, M3, 2,
M4, 4, H1, 2, M7, 2+2, H1, 2+4,
H2, 2, H2, 2, H3, 2, H1, 2+4+4,
//第6行
H1, 2, M7, 2, M6, 2, M6, 2, M7, 4, M5_,4,
M6, 4+4+4, H1, 2, H2, 2,
H3, 4+2,H2, 2, H3, 4, H5, 4,
//第7行
H2, 4+4+4, M5, 2, M5, 2,
H1, 4+2, M7, 2, H1, 4, H3, 4,
H3, 4+4+4+4,
//第8行
M6, 2, M7, 2, H1, 4, M7, 4, H2, 2, H2, 2,
H1, 4+2,M5, 2+4+4,
H4, 4, H3, 4, H2, 4, H1, 4,
//第9行
H3, 4+4+4, H3, 4,
H6, 4+4, H5, 4, H5, 4,
H3, 2, H2, 2, H1, 4+4, P, 2, H1, 2,
//第10行
H2, 4, H1, 2, H2, 2, H2, 4, H5, 4,
H3, 4+4+4, H3, 4,
H6, 4+4, H5, 4+4,
//第11行
H3, 2, H2, 2, H1, 4+4, P, 2, H1, 2,
H2, 4, H1, 2, H2, 2+4, M7, 4,
M6, 4+4+4, M6, 2, M7, 2,
0xFF //终止符号
};
unsigned char FreqSelect,MusicSelect;
void main()
{
timer0_init();
while(1)
{
if(Music[MusicSelect]!=0xFF) //如果不是停止标志位
{
FreqSelect = Music[MusicSelect]; //选择音符对应的频率
MusicSelect++;
delayms(SPEED/4*Music[MusicSelect]); //选择音符对应的时值
MusicSelect++;
TR0 = 0;
delayms(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口
}
}
3.2 延时函数
#ifndef _delayms_h_
#define _delayms_h_
delayms(unsigned int xms);
#endif
#include
void delayms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
3.3 定时器函数
#ifndef _timer0_h_
#define _timer0_h_
void timer0_init(void);
#endif
#include
/**
* @brief 定时器0初始化,1毫秒@11.0592MHz
* @param 无
* @retval 无
*/
void timer0_init(void) //1毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式,1111_0000,&,高四位保留,低四位清零
TMOD |= 0x01; //设置定时器模式,0000_0001,|,高四位保留,设置模式为T0
TL0 = 0x66; //设置定时初始值,1ms,@11.0592MHz
TH0 = 0xFC; //设置定时初始值,1ms,@11.0592MHz
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1; //打开定时器T0中断开关
EA=1; //打开中断系统总开关
PT0=0; //设置T0中断优先级,低
}