胡bbs4
08-24 22:18
這是本人一個(gè)產(chǎn)品中的音樂(lè)單元,很完整,供參考.
中央c組里的A=440Hz
12個(gè)半音階相鄰關(guān)系是12√2 (2開(kāi)12次方≈1.0594631)
例如 A=440Hz
? ???bB=440Hz x 1.0594631 = 466.16Hz? ?
? ?? ?B=466.16Hz??x 1.0594631 = 493.88Hz
? ?? ?C=493.88Hz x 1.0594631 = 523.25Hz
這是本人一個(gè)產(chǎn)品中的音樂(lè)單元,單音演奏的,多重和音不宜用這方法,一般用硬件的音源加單片機(jī)控制方法完成,有興趣可去合泰網(wǎng)站http://www.holtek.com.cn/docum/consumer/8950.htm看看.ht8950提供了一個(gè)產(chǎn)生樂(lè)音包絡(luò)用的硬件平臺(tái)(a/d,d/a等),用軟波表數(shù)據(jù)來(lái)完成音階及包絡(luò),單片機(jī)只是進(jìn)行控制,以前8bit聲卡中ym3812與此差不多功能.
中央C的A音為440Hz,半音價(jià)之間關(guān)系為2開(kāi)12次方(12√2=1.05946)
中央C的#A音為440Hz*1.05946=466.163Hz
中央C的B音為440Hz*1.05946*1.05946=493.883Hz
用定時(shí)器來(lái)模擬這個(gè)頻率,精度取決于時(shí)鐘快慢,一般小數(shù)點(diǎn)后保留一位,音準(zhǔn)已可忍受了,生日快樂(lè)芯片是小數(shù)點(diǎn)前一位的,耳朵容易聽(tīng)壞的拉.
cpu用89c51,p1.7輸出樂(lè)音,接無(wú)源蜂鳴器的驅(qū)動(dòng)三極管基極
? ?? ???ORG? ???0000H
? ?? ???AJMP? ? CSH? ?? ?? ?? ? ;主程序進(jìn)入點(diǎn)
? ?? ???ORG? ???000BH
? ?? ???LJMP? ? TIM0? ?? ?? ?? ?;定時(shí)中斷T0入口
;
;**********
;* 初始化 *
;**********
;
? ?? ???ORG? ???0020H
CSH:? ? MOV? ???R0,#7FH? ?? ?? ?;內(nèi)部RAM(00H~7FH)清零
CSH1:? ?MOV? ???@R0,#00H
? ?? ???DJNZ? ? R0,CSH1
? ?? ???MOV? ???SP,#60H? ?? ?? ?;堆棧60H~7FH,【使用89C51】
? ?? ???MOV? ???TMOD,#01H? ?? ? ;TMOD=11H,T0作16位計(jì)數(shù)器(4M晶振)
? ?? ???CLR? ???TCON.4? ?? ?? ? ;T0禁止動(dòng)作
? ?? ???SETB? ? IE.1? ?? ?? ?? ?;T0允許中斷
? ?? ???SETB? ? PT0? ?? ?? ?? ? ;T0中斷優(yōu)先
? ?? ???SETB? ? IE.7? ?? ?? ?? ?;系統(tǒng)允許中斷
;
;**********
;* 主程序 *
;**********
;
MAIN:? ?MOV? ???5CH,#00? ?? ?? ?;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???MOV? ???5CH,#49? ?? ?? ?;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???MOV? ???5CH,#66? ?? ?? ?;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???MOV? ???5CH,#100? ?? ???;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???MOV? ???5CH,#108? ?? ???;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???MOV? ???5CH,#136? ?? ???;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???MOV? ???5CH,#174? ?? ???;取簡(jiǎn)碼譜指針
? ?? ???LCALL? ?MUSIC
? ?? ???AJMP? ? MAIN
;
;*************************
;* 音樂(lè)子程序 MUSIC? ?? ?*
;* 入口: 5CH←簡(jiǎn)碼譜指針 *
;*************************
;
MUSIC:??MOV? ???A,5CH? ?? ?? ???;簡(jiǎn)碼譜指針裝入A
? ?? ???MOV? ???DPTR,#TABLE? ???;至TABLE取簡(jiǎn)碼
? ?? ???MOVC? ? A,@A+DPTR
? ?? ???MOV? ???R2,A? ?? ?? ?? ?;取到的簡(jiǎn)碼暫存于R2
? ?? ???JZ? ?? ?END1? ?? ?? ?? ?;是否取到00(結(jié)束碼)?
? ?? ???ANL? ???A,#0FH? ?? ?? ? ;不是,則取低四位(節(jié)拍碼)
? ?? ???MOV? ???R6,A? ?? ?? ?? ?;將節(jié)拍碼存入R6
? ?? ???MOV? ???A,R2? ?? ?? ?? ?;將取到的簡(jiǎn)碼再裝入R2
? ?? ???SWAP? ? A? ?? ?? ?? ?? ?;高低四位交換
? ?? ???ANL? ???A,#0FH? ?? ?? ? ;取低四位(音符碼)
? ?? ???JNZ? ???SING? ?? ?? ?? ?;取到的音符碼是否為0?
? ?? ???CLR? ???TR0? ?? ?? ?? ? ;是,則不發(fā)音
? ?? ???AJMP? ? D1? ?? ?? ?? ???;跳到D1
;
SING:? ?DEC? ???A? ?? ?? ?? ?? ?;取到的音符碼減1
? ?? ???MOV? ???4BH,A? ?? ?? ???;存入(4BH)
? ?? ???RL? ?? ?A? ?? ?? ?? ?? ?;乘2
? ?? ???MOV? ???DPTR,#TABLE1? ? ;至TABLE1取相對(duì)的高字節(jié)計(jì)數(shù)值
? ?? ???MOVC? ? A,@A+DPTR
? ?? ???MOV? ???TH0,A? ?? ?? ???;取到的高字節(jié)存入TH0
? ?? ???MOV? ???4AH,A? ?? ?? ???;取到的高字節(jié)存入(4AH)
? ?? ???MOV? ???A,4BH? ?? ?? ???;再裝入取到的音符碼
? ?? ???RL? ?? ?A? ?? ?? ?? ?? ?;乘2
? ?? ???INC? ???A? ?? ?? ?? ?? ?;加1
? ?? ???MOVC? ? A,@A+DPTR? ?? ? ;至TABLE1取相對(duì)的低位
? ?? ???MOV? ???TL0,A? ?? ?? ???;取到的低字節(jié)存入TL0
? ?? ???MOV? ???49H,A? ?? ?? ???;取到的低字節(jié)存入(49H)
? ?? ???SETB? ? TR0? ?? ?? ?? ? ;啟動(dòng)TIMER0
D1:? ???CALL? ? DELAY? ?? ?? ???;基本單位時(shí)間1/4拍187毫秒
? ?? ???INC? ???5CH? ?? ?? ?? ? ;取簡(jiǎn)碼譜指針加1
? ?? ???AJMP? ? MUSIC? ?? ?? ???;取下一個(gè)碼
DD1:? ? RET
;
STOP:? ?NOP
;? ?? ? JB? ?? ?P3.7,STOP1? ?? ?;在軟件延時(shí)中摻插做其他動(dòng)作
;? ?? ? SETB? ? P2.7? ?? ?? ?? ?;P2.7←"1"
? ?? ???NOP
? ?? ???NOP
STOP0:??NOP
? ?? ???RET
STOP1:??NOP
;? ?? ? JB? ?? ?P3.6,STOP0? ? ;在軟件延時(shí)中摻插做其他動(dòng)作
;? ?? ? SETB? ? P2.6? ?? ?? ?? ?;P2.6←"1"
? ?? ???RET
;
END1:? ?CLR? ???TR0? ?? ?? ?? ? ;停止TIMER0
? ?? ???RET
;
TIM0:? ?PUSH? ? A? ?? ?? ?? ?? ?;將A的值暫存于堆棧區(qū)
? ?? ???PUSH? ? PSW? ?? ?? ?? ? ;將PSW的值暫存于堆棧區(qū)
? ?? ???MOV? ???TL0,49H? ?? ?? ?;重設(shè)計(jì)數(shù)值
? ?? ???MOV? ???TH0,4AH
? ?? ???CPL? ???P1.7? ?? ?? ?? ?;將輸出端P1.7取反(P1.7接至無(wú)源蜂鳴器)
? ?? ???POP? ???PSW? ?? ?? ?? ? ;至堆棧區(qū)取回PSW的值
? ?? ???POP? ???A? ?? ?? ?? ?? ?;至堆棧區(qū)取回A的值
? ?? ???RETI? ?? ?? ?? ?? ?? ???;返回主程序
;
DELAY:??MOV? ???R7,#02? ?? ?? ? ;187毫秒
D2:? ???MOV? ???R4,#24
D3:? ???MOV? ???R3,#48
? ?? ???DJNZ? ? R3,$
? ?? ???ACALL? ?STOP? ?? ?? ?? ?;在軟件延時(shí)中摻插做其他動(dòng)作
? ?? ???DJNZ? ? R4,D3
? ?? ???DJNZ? ? R7,D2
? ?? ???DJNZ? ? R6,DELAY? ?? ???;決定節(jié)拍
? ?? ???RET
;? ?? ?? ?? ?? ???.5? ?.6? ???.7? ? 1
TABLE1: DW? ?? ?65111,65150,65199,65217? ?;4M晶振時(shí)的定時(shí)中斷時(shí)間常數(shù)
;? ?? ?? ?? ?? ?? ?2? ? 3? ???4? ???5? ???;若采用其它頻率,則要根據(jù)樂(lè)音的
? ?? ???DW? ?? ?65252,65283,65297,65323? ?;頻率計(jì)算,例中央C的A音為440Hz,
;? ?? ?? ?? ?? ?? ?6? ? 7? ???1`? ? 2`? ? ;440Hz=2.273ms,把T0設(shè)置為2.273ms
? ?? ???DW? ?? ?65347,65367,65377,65394? ?;中斷即可發(fā)出A音.
;? ?? ?? ?? ?? ???3`? ? 4`? ? #6
? ?? ???DW? ?? ?65410,65417,65357
;
;***************************************************************
;* 音符代碼??1??2??3??4??5??6??7??8??9??A??B??C??D??E??F? ?0? ?*
;* 音高? ???.5 .6 .7??1??2??3??4??5??6??7??1` 2` 3` 4` 5` 休止 *
;*-------------------------------------------------------------*
;* 節(jié)拍代碼??1? ?2? ?3??4? ?5? ?? ?6? ? 8? ?A? ? C? ?F? ?? ?? ?*
;* 節(jié)拍? ???1/4 2/4 3/4 1 1(1/4) 1(1/2) 2 2(1/2) 3 3(3/4)? ?? ?*
;*-------------------------------------------------------------*
;* 結(jié)束代碼 00H? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*-------------------------------------------------------------*
;* 樂(lè)譜格式??每字節(jié)的高字節(jié)為音符代碼,低字節(jié)為節(jié)拍代碼? ?? ?? ?*
;*-------------------------------------------------------------*
;* 例子:? ?? ???⑴??⑵??⑶??⑷??⑸??⑹??⑺??⑻??⑼??⑽??⑾? ???*
;*? ?? ?DB? ?? ?A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H,00H? ? *
;*? ?? ?⑴ A→唱"7" , 4→ 1 拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑵ 0→休止??, 2→2/4拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑶ 8→唱"5" , 4→ 1 拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑷ 0→休止??, 2→2/4拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑸ A→唱"7" , 4→ 1 拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑹ 0→休止??, 2→2/4拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑺ 8→唱"5" , 4→ 1 拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑻ 0→休止??, 2→2/4拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑼ D→唱"3`", 8→ 2 拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑽ 0→休止??, 4→ 1 拍? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;*? ?? ?⑾ 00H→樂(lè)曲結(jié)束? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?*
;***************************************************************
;
TABLE:
;【00】
? ?? ???DB? ?? ?98H,02H,B4H,01H,94H,01H,68H,02H,94H,01H
? ?? ???DB? ?? ?64H,01H,48H,02H,64H,01H,44H,01H,28H,02H
? ?? ???DB? ?? ?64H,01H,94H,01H,B4H,01H,94H,01H,B4H,01H
? ?? ???DB? ?? ?94H,01H,B4H,01H,D4H,01H,94H,01H,64H,01H
? ?? ???DB? ?? ?44H,01H,64H,01H,98H,02H,01H,01H,00H
;【49】
? ?? ???DB? ?? ?A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H
? ?? ???DB? ?? ?C8H,01H,01H,01H,01H,01H,00H
;【66】
? ?? ???DB? ?? ?42H,52H,62H,72H,82H,92H,A2H,B2H,42H,52H
? ?? ???DB? ?? ?62H,72H,82H,92H,A2H,B2H,00H
;【100】
? ?? ???DB? ?? ?61H,81H,B1H,D1H,B1H,81H,61H,00H
;【108】
? ?? ???DB? ?? ?11H,41H,61H,81H,61H,41H,11H,00H
;【136】
? ?? ???DB? ?? ?24H,04H,34H,04H,44H,04H,54H,04H,64H,04H,44H,04H,64H,04H,94H,04H
? ?? ???DB? ?? ?83H,01H,93H,01H,83H,01H,63H,01H,46H,02H,66H,02H
? ?? ???DB? ?? ?91H,21H,91H,21H,91H,21H,91H,21H,94H,00H
;【174】
? ?? ???DB? ?? ?94H,04H,A4H,04H,B4H,04H,C4H,04H,D4H,04H
? ?? ???DB? ?? ?B4H,04H,D8H,08H,C4H,04H,F4H,04H,CCH,00H
;
? ? END