利用單片機(jī)演奏音樂(lè)大概是單片機(jī)愛(ài)好者感興趣的問(wèn)題之一。這里我們用網(wǎng)站提供的實(shí)驗(yàn)板來(lái)做這個(gè)實(shí)驗(yàn),并且了解單片機(jī)演奏音樂(lè)的基本原理,和相關(guān)的源程序。
首先來(lái)完成必要的硬件部分,硬件部分比較簡(jiǎn)單,如下圖: AT89C51單片機(jī)的P2.5口控制一個(gè)8550的三極管,三極管控制電磁蜂鳴器的電源通斷。 我們知道,聲音的頻譜范圍約在幾十到幾千赫茲,若能利用程序來(lái)控制單處機(jī)某個(gè)口線的高電平或低電平,則在該口線上就能產(chǎn)生一定頻率的矩形波,接上喇叭就能發(fā)出一定頻率的聲音,若再利用延時(shí)程序控制“高”“低”電平的持續(xù)時(shí)間,就能改變輸出頻率,從而改變音調(diào)。 例如,要產(chǎn)生200HZ的音頻信號(hào),200HZ音頻的變化周期為1/200秒,即5ms。這樣,當(dāng)P2.5的高電平或低電平的持續(xù)時(shí)間為2.5ms時(shí)就能發(fā)出200HZ的音調(diào)。
樂(lè)曲中,每一音符對(duì)應(yīng)著確定的頻率,我們將每一音符的時(shí)間常數(shù)和其相應(yīng)的節(jié)拍常數(shù)作為一組,按順序?qū)?lè)曲中的所有常數(shù)排列成一個(gè)表,然后由查表程序依次取出,產(chǎn)生音符并控制節(jié)奏,就可以實(shí)現(xiàn)演奏效果。
此外,結(jié)束符和體止符可以分別用代碼00H和FFH來(lái)表示,若查表結(jié)果為00H,則表示曲子終了;若查表結(jié)果為FFH,則產(chǎn)生相應(yīng)的停頓效果。
為了產(chǎn)生手彈的節(jié)奏感,在某些音符(例如兩個(gè)相同音符)音插入一個(gè)時(shí)間單位的頻率略有不同的音符。
程序框圖如圖2所示。

下面給出程序序請(qǐng)單,可直接在51實(shí)驗(yàn)板上進(jìn)行演奏。本程序演奏的是民歌“八月桂花遍地開(kāi)”,C調(diào),節(jié)奏為94拍/分。網(wǎng)友也可以自行找出一首歌,將樂(lè)曲翻譯成碼表輸入機(jī)器,而程序不變。本實(shí)驗(yàn)方法簡(jiǎn)便,即使不懂音樂(lè)的人,將一首陌生的曲子翻譯成代碼也是易事,和著機(jī)器的演奏學(xué)唱一首歌曲,其趣味無(wú)窮。
;標(biāo)題 '八月桂花香'發(fā)聲程序
- ORG 0000H
- LJMP START
- ORG 000BH
- INC 20H ;中斷服務(wù),中斷計(jì)數(shù)器加1
- MOV TH0,#0D8H
- MOV TL0,#0EFH ;12M晶振,形成10毫秒中斷
- RETI
- START:
- MOV SP,#50H
- MOV TH0,#0D8H
- MOV TL0,#0EFH
- MOV TMOD,#01H
- MOV IE,#82H
- MUSIC0:
- NOP
- MOV DPTR,#DAT ;表頭地址送DPTR
- MOV 20H,#00H ;中斷計(jì)數(shù)器清0
- MUSIC1:
- NOP
- CLR A ;A清零
- MOVC A,@A+DPTR ;查表取代碼
- JZ END0 ;是00H,則結(jié)束
- CJNE A,#0FFH,MUSIC5 ;如果是休止符,往下執(zhí)行
- LJMP MUSIC3
- MUSIC5:
- NOP
- MOV R6,A ;R6=18H音符的頻率
- INC DPTR DPTR加一
- MOV A,#0
- MOVC A,@A+DPTR ;取節(jié)拍代碼送R7
- MOV R7,A ;R7=30H音符發(fā)音的時(shí)間
- SETB TR0 ;啟動(dòng)計(jì)數(shù)
- MUSIC2:
- NOP
- CPL P2.5 ;P2.5是音樂(lè)輸出引腳
- MOV A,R6
- MOV R3,A ;R3=R6=18H
- LCALL DEL
- MOV A,R7
- CJNE A,20H,MUSIC2 ;中斷計(jì)數(shù)器(20H)=R7否?
- ;不等,則繼續(xù)循環(huán)
- MOV 20H,#00H ;等于,則取下一代碼
- INC DPTR
- LJMP MUSIC1
- MUSIC3:
- NOP ;休止100毫秒
- CLR TR0
- MOV R2,#0DH ;R2=13
- MUSIC4:
- NOP
- MOV R3,#0FFH ;R3=255
- LCALL DEL
- DJNZ R2,MUSIC4
- INC DPTR
- LJMP MUSIC1
- END0:
- NOP
- MOV R2,#0FFH ;歌曲結(jié)束,延時(shí)1秒后繼續(xù)
- MUSIC6:
- MOV R3,#00H
- LCALL DEL
- DJNZ R2,MUSIC6
- LJMP MUSIC0
- DEL:
- NOP
- DEL3:
- MOV R4,#02H
- DEL4:
- NOP
- DJNZ R4,DEL4
- NOP
- DJNZ R3,DEL3
- RET
- NOP
- DAT:
- DB 18H, 30H, 1CH, 10H
- DB 20H, 40H, 1CH, 10H
- DB 18H, 10H, 20H, 10H
- DB 1CH, 10H, 18H, 40H
- DB 1CH, 20H, 20H, 20H
- DB 1CH, 20H, 18H, 20H
- DB 20H, 80H, 0FFH, 20H
- DB 30H, 1CH, 10H , 18H
- DB 20H, 15H, 20H , 1CH
- DB 20H, 20H, 20H , 26H
- DB 40H, 20H , 20H , 2BH
- DB 20H, 26H, 20H , 20H
- DB 20H, 30H , 80H , 0FFH
- DB 20H, 20H, 1CH , 10H
- DB 18H, 10H, 20H , 20H
- DB 26H, 20H , 2BH , 20H
- DB 30H, 20H , 2BH , 40H
- DB 20H, 20H , 1CH , 10H
- DB 18H, 10H, 20H, 20H
- DB 26H, 20H , 2BH, 20H
- DB 30H, 20H, 2BH , 40H
- DB 20H, 30H, 1CH , 10H
- DB 18H, 20H , 15H , 20H
- DB 1CH, 20H , 20H , 20H
- DB 26H, 40H, 20H , 20H
- DB 2BH, 20H, 26H , 20H
- DB 20H, 20H, 30H , 80H
- DB 20H, 30H, 1CH , 10H
- DB 20H, 10H, 1CH , 10H
- DB 20H, 20H, 26H , 20H
- DB 2BH, 20H, 30H , 20H
- DB 2BH, 40H, 20H , 15H
- DB 1FH, 05H, 20H , 10H
- DB 1CH, 10H, 20H , 20H
- DB 26H, 20H, 2BH , 20H
- DB 30H, 20H, 2BH , 40H
- DB 20H, 30H, 1CH , 10H
- DB 18H, 20H , 15H , 20H
- DB 1CH, 20H , 20H , 20H
- DB 26H, 40H, 20H , 20H
- DB 2BH, 20H, 26H , 20H
- DB 20H, 20H, 30H, 30H
- DB 20H, 30H, 1CH, 10H
- DB 18H, 40H, 1CH, 20H
- DB 20H, 20H, 26H, 40H
- DB 13H, 60H, 18H , 20H
- DB 15H, 40H, 13H , 40H
- DB 18H, 80H, 00H
- end
復(fù)制代碼
|