;###########################################
;*******************************************
;程序名称: MIDI音乐播放器.
;主控芯片: 89C51.
;编者心得: 此程序采用新编码使得单片机可以存放多首歌曲,并且应用更加简单.优化的 编码规则对提高,
; 单片机极为重要.
;移用核心: 只需把原曲普按规则编码放在Y-TAB编码表下面即可.
;编码规则: D7是有无升半调标志位,1表示有,0表示无;D6D5D4对应表示简谱码1,2,3,4,5,6,7;_
; D3D2是音调标志,0(00)表示低音,1(01)表示中音,2(10)标示高音;
; D1D0是节拍标志,0(00)表示1/8节拍,1(01)表示1/4节拍,2(10)表示1/2节拍,3(11)表示1/16.
; eg:25H→00100101即为(0)无升半调,(010)简谱2(re),(01)中音,(01)1/4节拍.
;版本:CFL→music1.1.
;设计编写: buyixin(不亦心).
;编写时间: 2009年7月30日. 22:09.
;*******************************************
;###########################################
;//////变量地址申明./////////////////////////////
SHENG DATA 30H ;有无升半调标志存储单元.
YIN_JIE DATA 31H ;简谱码1,2,3,4,5,6,7存储单元.
YIN_DIAO DATA 32H ;低中高音标志存储单元.
YIN_CHANG DATA 33H ;节拍标志存储单元.
BELL BIT P2.0 ;扬声器.
;//////主程序开始.///////////////////////////////
ORG 0000H
LJMP START
ORG 000BH
LJMP TIME0
ORG 0030H
START: MOV SP,#60H ;初始化.
MOV TMOD,#01H
SETB EA
SETB ET0
MOV DPTR,#Y_TAB ;取简谱码表.
AGAIN: MOV A,#00H
MOVC A,@A+DPTR
JZ START ;一首歌曲以00H结束,重头播放.
MOV R0,A ;简谱码暂存R0中.
RL A
ANL A,#01H ;得到有无升半调标志.
MOV B,#2AH
MUL AB ;把升半调标志与2A相乘,以便得到对应频率表.
MOV SHENG,A
MOV A,R0
SWAP A
ANL A,#07H ;得到简谱.
SUBB A,#01H
MOV B,#02H ;(简谱-1)*2,以便得到对应的频率表.
MUL AB
MOV YIN_JIE,A
MOV A,R0
RR A
RR A
ANL A,#03H ;得到低中高音标志.
MOV B,#0EH ;低中高音标志*0EH,以便得到对应的频率表.
MUL AB
MOV YIN_DIAO,A
MOV A,R0
ANL A,#03H ;得到节拍时间标志.
MOV YIN_CHANG,A
MOV A,SHENG ;升半调标志*2AH+(简谱-1)*2+低中高音标志*0EH=频率表位置,即定时器初值表.
ADD A,YIN_DIAO
ADD A,YIN_JIE
MOV R3,A ;将位置暂存于R3中.
INC DPTR ;取下一个简谱码.
PUSH DPH ;保护.
PUSH DPL
MOV DPTR,#F_TAB ;根据解码结果取定时器初值.
MOVC A,@A+DPTR
MOV TH0,A
MOV R1,A
INC DPTR
MOV A,R3
MOVC A,@A+DPTR
MOV TL0,A
MOV R2,A
MOV A,YIN_CHANG
SETB TR0
JB ACC.1,DEL2 ;判断节拍.
JB ACC.0,DEL1
ACALL DELAY0
SJMP OVER
DEL1: ACALL DELAY1
SJMP OVER
DEL2: JB ACC.0,DEL3
ACALL DELAY2
SJMP OVER
DEL3: ACALL DELAY3
OVER: CLR TR0
POP DPL
POP DPH
LJMP AGAIN ;继续解码下一个简谱.
;//////定时器0中断服务子程序.//////////////////////
TIME0:
MOV TH0,R1 ;重装初值.
MOV TL0,R2
CPL BELL
RETI
;//////1/8节拍延时子程序.//////////////////////////
DELAY0:
ACALL DELAY3
ACALL DELAY3
RET
;//////1/4节拍延时子程序.//////////////////////////
DELAY1:
ACALL DELAY0
ACALL DELAY0
RET
;//////1/2节拍延时子程序.//////////////////////////
DELAY2:
ACALL DELAY1
ACALL DELAY1
RET
;//////1/16节拍延时子程序.////////////////////////
DELAY3:
MOV R5,#02H
DL1: MOV R6,#0C4H
DL0: MOV R7,#0FFH
DJNZ R7,$
DJNZ R6,DL0
DJNZ R5,DL1
RET
;//////定时器初值表(频率表).////////////////////
F_TAB:
DW 63628,63835,64021,64103,64260,64400,64524 ;低音:1,2,3,4,5,6,7.
DW 64580,64684,64777,64820,64898,64968,65030 ;中音:1,2,3,4,5,6,7.
DW 65058,65110,65157,65178,65217,65252,65283 ;高音:1,2,3,4,5,6,7.
DW 63731,63928,00000,64185,64331,64463,00000 ;低音升半调:#1,#2,#4,#5,#6.
DW 64633,64732,00000,64860,64934,64994,00000 ;中音升半调:#1,#2,#4,#5,#6.
DW 65085,65134,00000,65198,65235,65268,00000 ;高音升半调:#1,#2,#4,#5,#6.
;//////歌曲简谱编码表.///////////////////////////////
Y_TAB:
DB 50H,50H,61H,51H,15H,72H,50H,50H,61H,51H,25H,16H,50H,50H
DB 55H,35H,15H,72H,64H,44H,44H,35H,15H,25H,36H,50H,50H,62H
DB 30H,30H,41H,31H,15H,72H,30H,30H,41H,31H,25H,16H,50H,50H
DB 35H,35H,15H,72H,60H,60H,60H,50H,60H,70H,16H,30H,30H,16H
DB 00H ;一首歌曲结束标志.
;//////程序到此结束.//////////////////////////////////
END |