實現簡易播放旋律音樂
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (156.03 KB, 下載次數: 57)
下載附件
2021-12-14 01:06 上傳
簡易音樂播放器的工作原理
簡易音樂播放器是通過MCU產生特定頻率的信號,以達到控制蜂鳴器發出不同的聲音的目的。因此,簡易交通燈包括MCU最小系統電路,蜂鳴器驅動電路,按鍵控制電路。基本原理如圖2.1所示。
圖2.1 簡易音樂播放器原理框架
由圖2.1可以看出,按鍵控制電路向MCU最小系統發送控制信號,MCU最小系統發出不同頻率的信號控制蜂鳴器驅動電路發出聲音,達到播放音樂的目的。
2.3 蜂鳴器的的選擇
51hei.png (20.49 KB, 下載次數: 51)
下載附件
2021-12-14 01:17 上傳
圖2.4 無源蜂鳴器
蜂鳴器分為有源蜂鳴器和無源蜂鳴器兩種,有源和無源指的是“震蕩源”而不是“電源”,有源蜂鳴器的內部含有震蕩源,兩個引腳接入電源就會直接發出聲音,使用起來簡單方便,但由于內部震蕩源確定,只能發出單一的聲音,所以我們這里選用無源振蕩器;無緣振蕩器內部不含震蕩源,使用的時候必須在引腳上加入震蕩的方波,驅動起來比較復雜,但是無源蜂鳴器可以根據方波頻率的變化發出不同的聲音,非常適合我們做簡易音樂播放器的發聲裝置。
2.4 三極管驅動蜂鳴器
51hei.png (12.05 KB, 下載次數: 58)
下載附件
2021-12-14 01:18 上傳
圖2.5 NPN三極管
無源蜂鳴器的驅動方式有很多種,常見的有使用PNP三極管驅動、NPN三極管驅動、ULN2003D芯片驅動。總而言之,單片機自身的驅動電流無法驅動蜂鳴器發聲,需要一個放大器件進行驅動。
這里選用NPN三極管進行驅動,因為NPN三極管常見,成本低、穩定性好,相對于ULN2003D來說性價比更好,更符合工程實際。
2.5 LCD1602顯示電路
LCD1602的8根數據線和3根控制線E,RS和R/W與單片機相連后即可正常工作。一般應用中只須往LCD1602中寫入命令和數據,因此,可將LCD1602的R/W讀/寫選擇控制端直接接地,這樣可節省1根數據線。VO引腳是液晶對比度調試端,通常連接一個10kΩ的電位器即可實現對比度的調整;也可采用將一個適當大小的電阻從該引腳接地的方法進行調整,不過電阻的大小應通過調試決定。
第三章 電路分析與參數計算
圖3.1 STC89C52單片機復位電路
8051系列單片機的ALE及/PSEN兩引腳輸出高電平,RST引腳高電平到時,單片機復位。若直接由啟動瞬間產生,則為啟動復位,若通過按動按鈕產生高電平復位稱手動復位。如圖3.1所示,上電時,接通電源,電容器C相當于瞬間短路,+5V加到了RST/VPD端,該高電平使8051全機復位。
3.2 蜂鳴器驅動電路
51hei.png (96.36 KB, 下載次數: 42)
下載附件
2021-12-14 01:14 上傳
圖3.2 蜂鳴器驅動電路
蜂鳴器的驅動電路,如圖3.2所示。由于單片機1/0口的驅動電流僅有100~200
uA,遠遠小于驅動蜂鳴器的電流,故用三極管來擴流,這里用的是2 N3417(NPN)。由原理圖可知,單片機的P2.6端口出現高電平時,三極管導通,從而電流由VCC經三極管再經蜂鳴器到達GND,這樣蜂鳴器就會發聲;相反,若D5為低電平,則三極管截止,蜂鳴器中沒有電流,那么肯定就不發聲。
3.3 按鍵控制電路
51hei.png (62.73 KB, 下載次數: 25)
下載附件
2021-12-14 01:14 上傳
圖3.3 按鍵控制電路
簡易音樂播放器的按鍵控制電路由三個按鍵組成,分別接在單片機的P1.0-P1.2口,單片機IO口在默認情況下為高電平,當按鍵按下后引腳接地,單片機IO口變為低電平。單片機由此判斷哪個按鍵按下。
MUSIC1:音樂一播放按鍵,按鍵按下后,簡易音樂播放器播放第一首音樂。
MUSIC2:音樂二播放按鍵,按鍵按下后,簡易音樂播放器播放第二首音樂。
PAUSE/CONTINUE:音樂暫停/播放按鍵,在音樂播放時,可以通過此按鍵控制音樂的播放與暫停。
第四章 程序設計與仿真調試
4.1 程序設計
4.1.1 簡易音樂播放器總體流程
1.系統上電后,等待音樂選擇。
2.音樂播放時可以暫停和切換歌曲。
51hei.png (48.98 KB, 下載次數: 56)
下載附件
2021-12-14 01:15 上傳
仿真中遇到的問題
1.簡易音樂播放器仿真時,無源蜂鳴器元件BUZZTON無法發出聲音。
排查過程:首先檢查了蜂鳴器驅動電路,元件是否選擇正確,電路是否連接正確。然后檢查其他硬件電路是否正常,最后檢查程序是否正確。
原因與改進辦法:在Proteus8.6版本中元件無源蜂鳴器BUZZTON不支持仿真,無論如何都是無法發出聲音的,故使用無源蜂鳴器SOUNDER代替。
簡易音樂播放器共有三個部分組成。第一個部分為STC89C52最小系統。最小系統控制引腳輸出頻率變化的方波,驅動無源蜂鳴器播放音樂。
第二部分是無源蜂鳴器驅動電路,因為單片機IO口本身驅動電流及其微小,無法直接驅動無源蜂鳴器,所以使用了一個NPN三極管放大電流,此部分也可以使用PNP型三極管或者ULN2003D驅動芯片。
第三部分是按鍵控制電路,三個按鍵分別控制播放兩首音樂和控制音樂的播放和暫停。
單片機源程序如下:
- #include "reg52.h"
- #include "string.h"
- #define uint8 unsigned char
- #define uint16 unsigned short int
- #define SETMODE 0x38 //16*2顯示,5*7點陣,8位數據接口
- #define DISOPEN 0x0C //顯示開,不顯示光標,光標不閃爍
- #define DISMODE 0x06 //讀寫字符后地址加1,屏顯不移動
- #define SETADDR 0x80 //設置數據地址指針初始值
- #define CLEAR 0x01 //清屏,數據指針清零
- #define RET 0x02 //回車,數據指針清零
- #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;//記錄當前音樂曲目
- uint8 flag_music = 1;//音樂曲目標志
- uint8 flag_stop=1;//音樂播放/暫停標志
- unsigned char p,m; //m為頻率常數變量
- unsigned char i=0;
- unsigned char n=0; //n為節拍常數變量
- 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) //控制頻率延時
- {
- unsigned i=3*m;
- while(--i);
- }
- void delaymsms(unsigned char a) //豪秒延時子程序
- {
- while(--a);
- }
- void Write1602_Com(uint8 com)
- {
- E=0;
- RS=0; //命令
- delayms(50); //延時
- RW=0; //寫
- delayms(50);
- PORT=com; //端口賦值
- delayms(50);
- E=1; //高脈沖
- delayms(50);
- E=0;
- }
- void Write1602_Dat(uint8 dat)
- {
- E=0;
- RS=1; //數據
- delayms(50); //延時
- RW=0; //寫
- delayms(50);
- PORT=dat; //端口賦值
- delayms(50);
- E=1; //高脈沖
- delayms(50);
- E=0;
- }
- void Init1602(void)
- {
- Write1602_Com(SETMODE); //模式設置
- delayms(500);
- Write1602_Com(DISOPEN); //顯示設置
- 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循環切歌
- 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)//音樂暫停
- {
- if(flag_music != music_cacah)//如果播放途中切換了曲目,跳出當前播放
- {
- flag_stop=1;
- break;
- }
- else
- {
- Write1602_Str(0x80+0x40,strlen(string_stop),string_stop); //"stoping..."
- while(1)//等待音樂播放
- {
- scanf();
- if(key_play==0||flag_music != music_cacah)//按下播放鍵
- {
- flag_stop=1;
- break;
- }
- }
- if(flag_music != music_cacah)//如果暫停途中切換了曲目,跳出當前播放
- {
- flag_stop=1;
- break;
- }
- }
- }
- p=ur[i];
- if(p==0x00) { i=0, delaymsms(1000); goto play;} //如果碰到結束符,延時1秒,回到開始再來一遍
- else if(p==0xff) { i=i+1;delaymsms(100),TR0=0; goto a;} //若碰到休止符,延時100ms,繼續取下一音符
- else {m=ur[i++], n=ur[i++];} //取頻率常數 和 節拍常數
- TR0=1; //開定時器1
- while(n!=0) Beep=~Beep,delayms(m); //等待節拍完成
- TR0=0; //關定時器1
- }
- }
- void main()
- {
- Int1Init();//定時器中斷1初始化
- Init1602(); //初始化1602
- Write1602_Str(0x80+0x40,strlen(string_stop),string_stop); //"stop"
- while(1)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
仿真代碼與word資料51hei附件下載:
音樂播放器-3首lcd1602顯示歌詞.zip
(507.25 KB, 下載次數: 81)
2021-12-13 20:04 上傳
點擊文件名下載附件
2 下載積分: 黑幣 -5
|