|
實(shí)現(xiàn)簡(jiǎn)易播放旋律音樂(lè)
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
簡(jiǎn)易音樂(lè)播放器的工作原理
簡(jiǎn)易音樂(lè)播放器是通過(guò)MCU產(chǎn)生特定頻率的信號(hào),以達(dá)到控制蜂鳴器發(fā)出不同的聲音的目的。因此,簡(jiǎn)易交通燈包括MCU最小系統(tǒng)電路,蜂鳴器驅(qū)動(dòng)電路,按鍵控制電路;驹砣鐖D2.1所示。
圖2.1 簡(jiǎn)易音樂(lè)播放器原理框架
由圖2.1可以看出,按鍵控制電路向MCU最小系統(tǒng)發(fā)送控制信號(hào),MCU最小系統(tǒng)發(fā)出不同頻率的信號(hào)控制蜂鳴器驅(qū)動(dòng)電路發(fā)出聲音,達(dá)到播放音樂(lè)的目的。
2.3 蜂鳴器的的選擇
圖2.4 無(wú)源蜂鳴器
蜂鳴器分為有源蜂鳴器和無(wú)源蜂鳴器兩種,有源和無(wú)源指的是“震蕩源”而不是“電源”,有源蜂鳴器的內(nèi)部含有震蕩源,兩個(gè)引腳接入電源就會(huì)直接發(fā)出聲音,使用起來(lái)簡(jiǎn)單方便,但由于內(nèi)部震蕩源確定,只能發(fā)出單一的聲音,所以我們這里選用無(wú)源振蕩器;無(wú)緣振蕩器內(nèi)部不含震蕩源,使用的時(shí)候必須在引腳上加入震蕩的方波,驅(qū)動(dòng)起來(lái)比較復(fù)雜,但是無(wú)源蜂鳴器可以根據(jù)方波頻率的變化發(fā)出不同的聲音,非常適合我們做簡(jiǎn)易音樂(lè)播放器的發(fā)聲裝置。
2.4 三極管驅(qū)動(dòng)蜂鳴器
圖2.5 NPN三極管
無(wú)源蜂鳴器的驅(qū)動(dòng)方式有很多種,常見(jiàn)的有使用PNP三極管驅(qū)動(dòng)、NPN三極管驅(qū)動(dòng)、ULN2003D芯片驅(qū)動(dòng)。總而言之,單片機(jī)自身的驅(qū)動(dòng)電流無(wú)法驅(qū)動(dòng)蜂鳴器發(fā)聲,需要一個(gè)放大器件進(jìn)行驅(qū)動(dòng)。
這里選用NPN三極管進(jìn)行驅(qū)動(dòng),因?yàn)镹PN三極管常見(jiàn),成本低、穩(wěn)定性好,相對(duì)于ULN2003D來(lái)說(shuō)性價(jià)比更好,更符合工程實(shí)際。
2.5 LCD1602顯示電路
LCD1602的8根數(shù)據(jù)線和3根控制線E,RS和R/W與單片機(jī)相連后即可正常工作。一般應(yīng)用中只須往LCD1602中寫入命令和數(shù)據(jù),因此,可將LCD1602的R/W讀/寫選擇控制端直接接地,這樣可節(jié)省1根數(shù)據(jù)線。VO引腳是液晶對(duì)比度調(diào)試端,通常連接一個(gè)10kΩ的電位器即可實(shí)現(xiàn)對(duì)比度的調(diào)整;也可采用將一個(gè)適當(dāng)大小的電阻從該引腳接地的方法進(jìn)行調(diào)整,不過(guò)電阻的大小應(yīng)通過(guò)調(diào)試決定。
第三章 電路分析與參數(shù)計(jì)算
圖3.1 STC89C52單片機(jī)復(fù)位電路
8051系列單片機(jī)的ALE及/PSEN兩引腳輸出高電平,RST引腳高電平到時(shí),單片機(jī)復(fù)位。若直接由啟動(dòng)瞬間產(chǎn)生,則為啟動(dòng)復(fù)位,若通過(guò)按動(dòng)按鈕產(chǎn)生高電平復(fù)位稱手動(dòng)復(fù)位。如圖3.1所示,上電時(shí),接通電源,電容器C相當(dāng)于瞬間短路,+5V加到了RST/VPD端,該高電平使8051全機(jī)復(fù)位。
3.2 蜂鳴器驅(qū)動(dòng)電路
圖3.2 蜂鳴器驅(qū)動(dòng)電路
蜂鳴器的驅(qū)動(dòng)電路,如圖3.2所示。由于單片機(jī)1/0口的驅(qū)動(dòng)電流僅有100~200
uA,遠(yuǎn)遠(yuǎn)小于驅(qū)動(dòng)蜂鳴器的電流,故用三極管來(lái)擴(kuò)流,這里用的是2 N3417(NPN)。由原理圖可知,單片機(jī)的P2.6端口出現(xiàn)高電平時(shí),三極管導(dǎo)通,從而電流由VCC經(jīng)三極管再經(jīng)蜂鳴器到達(dá)GND,這樣蜂鳴器就會(huì)發(fā)聲;相反,若D5為低電平,則三極管截止,蜂鳴器中沒(méi)有電流,那么肯定就不發(fā)聲。
3.3 按鍵控制電路
圖3.3 按鍵控制電路
簡(jiǎn)易音樂(lè)播放器的按鍵控制電路由三個(gè)按鍵組成,分別接在單片機(jī)的P1.0-P1.2口,單片機(jī)IO口在默認(rèn)情況下為高電平,當(dāng)按鍵按下后引腳接地,單片機(jī)IO口變?yōu)榈碗娖健纹瑱C(jī)由此判斷哪個(gè)按鍵按下。
MUSIC1:音樂(lè)一播放按鍵,按鍵按下后,簡(jiǎn)易音樂(lè)播放器播放第一首音樂(lè)。
MUSIC2:音樂(lè)二播放按鍵,按鍵按下后,簡(jiǎn)易音樂(lè)播放器播放第二首音樂(lè)。
PAUSE/CONTINUE:音樂(lè)暫停/播放按鍵,在音樂(lè)播放時(shí),可以通過(guò)此按鍵控制音樂(lè)的播放與暫停。
第四章 程序設(shè)計(jì)與仿真調(diào)試
4.1 程序設(shè)計(jì)
4.1.1 簡(jiǎn)易音樂(lè)播放器總體流程
1.系統(tǒng)上電后,等待音樂(lè)選擇。
2.音樂(lè)播放時(shí)可以暫停和切換歌曲。
仿真中遇到的問(wèn)題
1.簡(jiǎn)易音樂(lè)播放器仿真時(shí),無(wú)源蜂鳴器元件BUZZTON無(wú)法發(fā)出聲音。
排查過(guò)程:首先檢查了蜂鳴器驅(qū)動(dòng)電路,元件是否選擇正確,電路是否連接正確。然后檢查其他硬件電路是否正常,最后檢查程序是否正確。
原因與改進(jìn)辦法:在Proteus8.6版本中元件無(wú)源蜂鳴器BUZZTON不支持仿真,無(wú)論如何都是無(wú)法發(fā)出聲音的,故使用無(wú)源蜂鳴器SOUNDER代替。
簡(jiǎn)易音樂(lè)播放器共有三個(gè)部分組成。第一個(gè)部分為STC89C52最小系統(tǒng)。最小系統(tǒng)控制引腳輸出頻率變化的方波,驅(qū)動(dòng)無(wú)源蜂鳴器播放音樂(lè)。
第二部分是無(wú)源蜂鳴器驅(qū)動(dòng)電路,因?yàn)閱纹瑱C(jī)IO口本身驅(qū)動(dòng)電流及其微小,無(wú)法直接驅(qū)動(dòng)無(wú)源蜂鳴器,所以使用了一個(gè)NPN三極管放大電流,此部分也可以使用PNP型三極管或者ULN2003D驅(qū)動(dòng)芯片。
第三部分是按鍵控制電路,三個(gè)按鍵分別控制播放兩首音樂(lè)和控制音樂(lè)的播放和暫停。
單片機(jī)源程序如下:
- #include "reg52.h"
- #include "string.h"
- #define uint8 unsigned char
- #define uint16 unsigned short int
- #define SETMODE 0x38 //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
- #define DISOPEN 0x0C //顯示開(kāi),不顯示光標(biāo),光標(biāo)不閃爍
- #define DISMODE 0x06 //讀寫字符后地址加1,屏顯不移動(dòng)
- #define SETADDR 0x80 //設(shè)置數(shù)據(jù)地址指針初始值
- #define CLEAR 0x01 //清屏,數(shù)據(jù)指針清零
- #define RET 0x02 //回車,數(shù)據(jù)指針清零
- #define PORT P0 //I/O口
- sbit RS = P2^6;
- sbit RW = P2^5;
- sbit E = P2^7;
- sbit key_stop = P3^0;//暫停按鍵
- sbit key_play = P3^1;//播放
- sbit key_next = P3^2;//下一首按鍵
- sbit key_last = P3^3;//上一首按鍵
- sbit Beep = P1^5;
- uint8 code MUSIC1_NAME[]="MUSIC1";
- uint8 code MUSIC1_lyric[]="Bells on bob.tail ring";
- uint8 code MUSIC2_NAME[]="MUSIC2";
- uint8 code MUSIC2_lyric[]="Happy birthday to you!";
- uint8 code MUSIC3_NAME[]="MUSIC3";
- uint8 code MUSIC3_lyric[]="Two tigers,Two tigers";
- uint8 code string_stop[]="now stop................";
- uint8 music_cacah=0;//記錄當(dāng)前音樂(lè)曲目
- uint8 flag_music = 1;//音樂(lè)曲目標(biāo)志
- uint8 flag_stop=1;//音樂(lè)播放/暫停標(biāo)志
- unsigned char p,m; //m為頻率常數(shù)變量
- unsigned char i=0;
- unsigned char n=0; //n為節(jié)拍常數(shù)變量
- unsigned char code MUSIC1[] ={0xff,//Jing Bells
- 0x26,0x20,0x18,0x20,0x19,0x20,0x1c,0x20,0x26,0x40,0x60,0x10,0x26,0x20,
- 0x26,0x20,0x18,0x20,0x19,0x20,0x1c,0x20,0x24,0x40,0x60,0x10,0x24,0x20,
- 0x18,0x20,0x19,0x20,0x13,0x20,0x13,0x20,0x13,0x20,0x13,0x20,0x12,0x20,
- 0x13,0x20,0x15,0x20,0x19,0x20,0x1c,0x20,0x00,
- };
- unsigned char code MUSIC2[] ={0xff,//happy birthday
- 0x26,0x20,0x26,0x20,0x24,0x40,0x26,0x40,0x1c,0x40,0x20,0x80,0x26,0x20,
- 0x26,0x20,0x24,0x40,0x26,0x40,0x19,0x40,0x1c,0x80,0x26,0x20,0x26,0x20,
- 0x13,0x40,0x18,0x40,0x1c,0x40,0x20,0x40,0x12,0x40,0x15,0x20,0x15,0x20,
- 0x18,0x40,0x1c,0x40,0x19,0x40,0x18,0x80,0x26,0x20,0x26,0x20,0x18,0x40,
- 0x1c,0x40,0x19,0x40,0x18,0x80,0x26,0x20,0x26,0x20,0x24,0x80,0x00,
- };
- unsigned char code MUSIC3[] ={0xff,//Two tigers
- 0x39,0x40,0x33,0x40,0x30,0x40,0x39,0x40,0x39,0x40,0x33,0x40,0x30,0x40,
- 0x39,0x40,0x30,0x40,0x2b,0x40,0x26,0x80,0x30,0x40,0x2b,0x40,0x26,0x80,
- 0x26,0x10,0x24,0x30,0x26,0x10,0x2b,0x30,0x30,0x40,0x39,0x40,0x26,0x10,
- 0x24,0x30,0x26,0x10,0x24,0x30,0x26,0x10,0x2b,0x30,0x30,0x40,0x39,0x40,
- 0x39,0x40,0x26,0x40,0x39,0x80,0x39,0x40,0x26,0x40,0x39,0x80,0x00,
- };
- void Int1Init()
- {
- TMOD&=0x0f;
- TMOD|=0x01;
- TH0=0xd8;TL0=0xef;
- EA=1;
- ET0=1;
- }
- void delayms (unsigned char m) //控制頻率延時(shí)
- {
- unsigned i=3*m;
- while(--i);
- }
- void delaymsms(unsigned char a) //豪秒延時(shí)子程序
- {
- while(--a);
- }
- void Write1602_Com(uint8 com)
- {
- E=0;
- RS=0; //命令
- delayms(50); //延時(shí)
- RW=0; //寫
- delayms(50);
- PORT=com; //端口賦值
- delayms(50);
- E=1; //高脈沖
- delayms(50);
- E=0;
- }
- void Write1602_Dat(uint8 dat)
- {
- E=0;
- RS=1; //數(shù)據(jù)
- delayms(50); //延時(shí)
- RW=0; //寫
- delayms(50);
- PORT=dat; //端口賦值
- delayms(50);
- E=1; //高脈沖
- delayms(50);
- E=0;
- }
- void Init1602(void)
- {
- Write1602_Com(SETMODE); //模式設(shè)置
- delayms(500);
- Write1602_Com(DISOPEN); //顯示設(shè)置
- delayms(500);
- Write1602_Com(DISMODE); //顯示模式
- delayms(500);
- Write1602_Com(CLEAR); //清屏
- delayms(500);
- }
- void Write1602_Str(uint8 addr,uint8 length,uint8 *pbuf)
- {
- uint8 i;
- Write1602_Com(addr);
- for(i=0;i<length;i++)
- {
- Write1602_Dat(pbuf[i]);
- }
- }
- void scanf()
- {
- if(key_stop == 0)
- {
- delaymsms(10);//消抖
- flag_stop = 0;
- while(key_stop==0);//等待按鍵彈起
- }
- if(key_next == 0)
- {
- delaymsms(10);//消抖
- flag_stop = 0;
- flag_music++;
- while(key_next==0);//等待按鍵彈起
- }
- if(key_last == 0)
- {
- delaymsms(10);//消抖
- flag_stop = 0;
- flag_music--;
- while(key_last==0);//等待按鍵彈起
- }
-
- if(flag_music==0)//1-8循環(huán)切歌
- flag_music=3;
- if(flag_music==4)
- flag_music=1;
- }
- void music_play(uint8 ur[])
- {
- music_cacah = flag_music;
- i = 0;
- play:
- while(1)
- {
- a:
- if(flag_stop==0)//音樂(lè)暫停
- {
- if(flag_music != music_cacah)//如果播放途中切換了曲目,跳出當(dāng)前播放
- {
- flag_stop=1;
- break;
- }
- else
- {
- Write1602_Str(0x80+0x40,strlen(string_stop),string_stop); //"stoping..."
- while(1)//等待音樂(lè)播放
- {
- scanf();
- if(key_play==0||flag_music != music_cacah)//按下播放鍵
- {
- flag_stop=1;
- break;
- }
- }
- if(flag_music != music_cacah)//如果暫停途中切換了曲目,跳出當(dāng)前播放
- {
- flag_stop=1;
- break;
- }
- }
- }
- p=ur[i];
- if(p==0x00) { i=0, delaymsms(1000); goto play;} //如果碰到結(jié)束符,延時(shí)1秒,回到開(kāi)始再來(lái)一遍
- else if(p==0xff) { i=i+1;delaymsms(100),TR0=0; goto a;} //若碰到休止符,延時(shí)100ms,繼續(xù)取下一音符
- else {m=ur[i++], n=ur[i++];} //取頻率常數(shù) 和 節(jié)拍常數(shù)
- TR0=1; //開(kāi)定時(shí)器1
- while(n!=0) Beep=~Beep,delayms(m); //等待節(jié)拍完成
- TR0=0; //關(guān)定時(shí)器1
- }
- }
- void main()
- {
- Int1Init();//定時(shí)器中斷1初始化
- Init1602(); //初始化1602
- Write1602_Str(0x80+0x40,strlen(string_stop),string_stop); //"stop"
- while(1)
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
仿真代碼與word資料51hei附件下載:
音樂(lè)播放器-3首lcd1602顯示歌詞.zip
(507.25 KB, 下載次數(shù): 81)
2021-12-13 20:04 上傳
點(diǎn)擊文件名下載附件
2
|
評(píng)分
-
查看全部評(píng)分
|