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

發佈了11 篇原創文章 · 獲贊 7 · 訪問量 3989
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章