标题:
单片机按键控制蜂鸣器演奏音乐
[打印本页]
作者:
R0514
时间:
2016-11-20 21:03
标题:
单片机按键控制蜂鸣器演奏音乐
按键控制蜂鸣器演奏音乐
0.png
(9.01 KB, 下载次数: 80)
下载附件
2016-12-5 03:39 上传
下载:
单片机演奏音乐.rar
(44.26 KB, 下载次数: 94)
2016-11-20 21:02 上传
点击文件名下载附件
音乐
下载积分: 黑币 -5
#include<reg52.h>
sbit spek=P3^7; //声音输出端
sbit set=P3^2; //设定及退出键,按奇数次为设定功能;偶数次为退出功能
sbit up=P3^1; //上一曲
sbit down=P3^0; //下一曲
bit flag1,flag2; //按键扫描标志位,新键值标志位
unsigned char f_t,n,i,key,k_max; //音符频率对应的二分之一周期值,节拍常数值,查表用计数器,键值,最大键值
unsigned char *p_music; //指向音乐数据数组的指针
void timer_ms(unsigned char tim); //毫秒级延时函数声明
void timer_us(unsigned char t); //微秒级延时函数
void key_scan(void); //按键扫描函数
void key_manage(); //键值处理函数
//格式为:频率常数,节拍常数,频率常数,节拍常数
unsigned char code music_table1[]={
0x18,0x30,0x1c,0x10,0x20,0x40,0x1c,0x10,0x18,
0x10,0x20,0x10,0x1c,0x10,0x18,0x40,0x1c,0x20,
0x20,0x20,0x1c,0x20,0x18,0x20,0x20,0x80,0xff,
0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,
0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,
0x26,0x20,0x20,0x20,0x30,0x80,0xff,0x20,0x20,
0x1c,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2b,
0x20,0x30,0x20,0x2b,0x40,0x20,0x20,0x1c,0x10,
0x18,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,
0x20,0x2b,0x40,0x20,0x30,0x1c,0x10,0x18,0x20,
0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,
0x20,0x2b,0x20,0x26,0x20,0x20,0x20,0x30,0x80,
0x20,0x30,0x1c,0x10,0x20,0x10,0x1c,0x10,0x20,
0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,
0x20,0x15,0x1f,0x05,0x20,0x10,0x1c,0x10,0x20,
0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,
0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,
0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,
0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1c,
0x10,0x18,0x40,0x1c,0x20,0x20,0x20,0x26,0x40,
0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,
0x80,0x00}; //八月桂花香
unsigned char code music_table2[]={
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,
0x10,0x20,0x80,0x26,0x20,0x30,0x20,0x30,0x20,
0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,
0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,
0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,
0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,
0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,
0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,
0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,
0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,
0x2b,0x20,0x2b,0x40,0x40,0x20,0x20,0x10,0x20,
0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,
0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,
0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
0x20,0x20,0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,
0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,
0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,
0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,
0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,
0x10,0x30,0x20,0x39,0x20,0x26,0x10,0x2b,0x10,
0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,
0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,
0x00}; //祝你平安
unsigned char code music_table3[]={
0x20,40,0x26,20,0x20,20,0x17,80,0x1c,40,0x17,40,
0x20,80,0x20, 40,0x2f,20,0x2a,20,0x26,40,0x2a,20,
0x2f,20,0x2a,80,0xff,0x20,40,0x26,20,0x20,20,0x17,60,
0x19,20, 0x1c,40,0x17,40,0x20,80,0x20,40,0x2a,20,
0x26,20,0x24,60,0x32,20,0x2f,80,0xff,0x1c,40,0x17,40,
0x17, 80,0x19,40,0x1c,20,0x19,20,0x17,80,0x1c,20,
0x19,20,0x17,20,0x1c,20,0x1c,20,0x20,20,0x26,20,0x2f,20,
0x2a,80,0xff,0x20,40,0x26,20,0x20,20,0x17,60,0x19,20,
0x1c,40,0x17,40,0x20,80,0x20,40,0x2a,20,0x26, 20,
0x24,60,0x32,20,0x2f,80,0xff,0x20,40,0x26,20,0x20,20,
0x17,80,0x1c,40,0x17,40,0x20,80,0x20,40, 0x2f,20,0x2a,20,
0x26,40,0x2a,20,0x2f,20,0x2a,80,0xff,0x20,40,0x26,20,
0x20,20,0x17,60,0x19,20,0x1c, 40,0x17,40,0x20,80,0x20,40,
0x2a,20,0x26,20,0x24,60,0x32,20,0x2f,80,0}; //送别
main()
{
spek=0;
P3=0x7f;
TMOD=0x01; //T0工作于方式1,即16位定时器模式
IE=0x82; //开总中断,T0中断
flag2=0; //
flag1=0;
key=1;
k_max=3; //最大键值(取值范围1~254)
n=0;
i=0;
p_music=music_table1; //指针赋初值
while (1)
{
switch (p_music[i])
{
case 0x00: i=0; //歌曲完,则停止0.5S后重新开始
timer_ms(250); //延时0.25ms
timer_ms(250);
break;
case 0xff: i++; //遇到休止符则停止100us
timer_ms(250);
timer_ms(250);
break;
default: f_t=p_music[i++];
n=p_music[i++];
spek=1;
TR0=1;
while (n!=0)
{
spek=~spek;
timer_us(4*f_t); //改变f_t前面的系数可以调整音符频率的高低
}
TR0=0;
spek=0;
if(set==0)
{
key_scan();
key_manage();
}
}
}
}
/**************************************************************
函数名称: 定时器0的中断处理程序 函数功能: 完成10毫秒定时 入口参数:
出口参数: 其 它: **************************************************************/
void timer0() interrupt 1 using 2
{
TH0=(65536-10000)/256; //定时10毫秒
TL0=(65536-10000)%256;
n--; }
/**************************************************************
函数名称: 延时程序 函数功能: 完成微秒级的延时 入口参数:
t为需延时的时间(取值范围1~255;延时时间5~1275us) 出口参数:
其 它: **************************************************************/
void timer_us(unsigned char t)
{
while (--t); //本语句执行一次需5us的时间
}
/**************************************************************
函数名称: 按键扫描函数 函数功能: 完成按键扫描处理 入口参数:
应为在中断函数中被调用,所以不能有参数传递 出口参数: 其 它:
**************************************************************/
void key_scan(void)
{
timer_ms(10); //延时10ms等待按键状态稳定
if (set==0) //再次确认
{
while (set==0); //等待按键松开
flag1=1; //该位为1,表示进入按键扫描处理;为0,表示本次按键扫描处理完成
while (flag1)
{
if (up==0) //加一键
{
timer_ms(10);
if (up==0)
{
while (!up);
key++;
if (key>k_max) key=1;
}
}
if (down==0) //减一键
{
timer_ms(10);
if (down==0)
{
while (!down);
key--;
if (key<1) key=k_max;
}
}
if (set==0) //退出键
{
timer_ms(10);
if (set==0)
{
while (set==0);
flag1=0; //表示本次按键扫描处理完成
flag2=1; //该位置1,表示有新键值要处理
}
}//以上键值处理的范围为1到254个键值
}
}
}
/**************************************************************
函数名称: 键值处理函数 函数功能: 完成按键键值的处理
入口参数: 应为在中断函数中被调用,所以不能有参数传递
出口参数: 其 它:
**************************************************************/
void key_manage()
{
flag2=0;
switch (key)
{
case 1: p_music=music_table1; //键值为1 播放第一首乐曲
goto kh1;
case 2: p_music=&music_table2[0]; //键值为2 播放第2首乐曲
goto kh1;
case 3: p_music=&music_table3[0]; //键值为3 播放第3首乐曲
goto kh1;
default: key=1;
p_music=music_table1;
kh1: TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
break;
}
n=0;
i=0;
}
/*----------------------------------------------------------------------------------------------------
函数名称: timer_ms 函数说明: 1ms延时子程序 入口参数: tim为接收主调传来需延时的毫秒数,取值范围1~256,定时时间1~256ms
出口参数: 其 它: ----------------------------------------------------------------------------------------------------*/
void timer_ms(unsigned char tim)
{
unsigned char j;
while(tim--)
{
for(j=0;j<200;j++); //延时1ms
}
}
复制代码
作者:
liyanchao153
时间:
2016-11-20 22:25
不错。。。。。。。。。。。。。。
作者:
nswy123
时间:
2017-4-18 18:02
按键不管用啊
作者:
北辰
时间:
2017-4-19 20:22
按键怎么接啊
作者:
GUOPK
时间:
2017-4-19 20:26
请问是接有源蜂鸣器还是嗽叭?
作者:
double-naze
时间:
2017-5-25 11:30
按键怎么不管用啊
作者:
雨轩wyx
时间:
2017-7-25 10:23
不错,学习学习
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1