51单片机程序设计——电子音乐盒

写在前面:想要做电子音乐盒首先要保证单片机上的蜂鸣器为无源蜂鸣器,有源蜂鸣器是不能放歌的,因为有源蜂鸣器只要通电就发出声音,没有起伏。

一、设计思路

电子音乐盒说难也难,说简单也简单,只要知道如何编制音乐代码就可以,其余的东西也就一个连接蜂鸣器,有点新意还可以结合按键做出选择播放,退出播放,下一首,上一首的功能,还可以结合LCD显示当前播放的音乐。本篇文章中介绍的程序只有选择播放和退出当前播放的的功能,至于其他的功能看以后会不会做这方面的程序吧。

二、编制音乐代码

简单介绍一下如何编制音乐代码,可以快速阅读,有个印象就好,后面会提供两个音乐的音乐代码和一个乐谱编辑的应用。
首先一首歌创建一个单独的数组,数组中每两个元素为一组,分别为频率常数和节拍常数,频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍; 休止符为0xff,结束符为0x00.
乐谱编辑的软件打开后的界面如下:
在这里插入图片描述
这个软件是普中科技开发板光盘里自带的,文末我会添加两个音乐的乐谱代码和这个软件的百度网盘链接。

三、按键控制

首先定义要控制的按键连接的I/O口:

sbit k1=P3^5;	 //定义P35口是k1

下面是检测k1是否按下的函数,包含去抖动,如果按下返回值为1,反之为0。

unsigned char keypros1()
{
  key=0;
	if(k1==0)		  //检测按键K1是否按下
	{	
		delay(100);   //消除抖动 一般大约10ms
		if(k1==0)	 //再次判断按键是否按下
		{	
			key=1;		
		}
		while(!k1);	 //检测按键是否松开
	}
	if(key==1)
			return 1;
	else return 0;
}

我设计的这个程序里需要用到四个按键,也就是说要定义四个这样的函数,我目前没找到如何能够只用一个函数并只改变实参就能控制四个按键的方法(有想过直接判断P3整个8位I/O口的电位情况,但是P3^6连接蜂鸣器,放音乐时电位一直在变化)。

四、音乐播放原理

以下为播放音乐的函数:

unsigned char p,m;   //m为频率常数变量    
  unsigned char i=0;   
  TMOD&=0x0f;   
  TMOD|=0x01;   
  TH0=0xd8;TL0=0xef;   
  IE=0x82;   
play:   
   while(1)   
    {   
    a: p=music_tab[i];   
       if(p==0x00)       { i=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍    
       else if(p==0xff)  { i=i+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符    
            else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数    
             TR0=1;                                             //开定时器1    
           while(n!=0) Beep=~Beep,delay(m);                         //等待节拍完成, 输出音频(可多声道哦!)    
       TR0=0;                                             //关定时器1    
    } 

下面是中断函数:

void int0()  interrupt 1   //采用中断0 控制节拍    
{  
	 TH0=0xd8;   
   TL0=0xef;   
   n--;   
} 

前面有提到0x00代表结束符,0xff代表休止符,选择定时器并赋初值后进入播放音乐的程序,遍历乐谱代码的数组,每次频率常数赋值给m,节拍常数赋值给n,打开定时器,按照频率常数和节拍常数启动蜂鸣器;若遇到0xff,延时100ms再返回遍历数组,再遍历数组的下一位;若遇到0x00则代表已经播放完毕,将遍历的指针i取零并返回重新播放。

五、按键选择音乐和退出音乐

1)按键选择音乐

首先将主函数选择定时器模式和赋初值后的内容改成如下循环,每一步我都在旁边加了注释,不难理解。

while(1)
{
	Beep=1;//无源蜂鸣器Beep=1不会发出声音,只有循环Beep=1和Beep=0才会发出声音
	if(keypros1())检测按键k1是否按下,若按下会返回1,进入music1()函数
		music1();进入播放祝你平安的函数
	if(keypros2())检测按键k2是否按下,若按下会返回1,进入music2()函数
		music2();进入播放八月桂花的函数
}		

2)按键退出音乐,返回主函数等待重新进入某个音乐函数

原理很简单,在播放音乐的函数里正常播放,遇到休止符和遇到结束符的程序内容中都加入如下内容:

if(k4==0)//检测k4是否按下
	key=4;//若是,键值为4
if(key==4)//如果键值为4
{
	TR0=0;//关闭定时器
	i=0//遍历音乐代码的数组指针i归零
	break;//退出循环
}

PS:《祝你平安》乐谱代码:

//祝你平安
unsigned char code music_tab1[] =
{   
  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_tab2[] =
{   
  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  
};

乐谱编辑软件百度网盘链接:
链接:https://pan.baidu.com/s/1L3KIg2Jesh22AqyS7yWodQ
提取码:u7ls

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值