OUT BIT P2.0 ;定義音頻輸出端口,p2.0
N EQU 3 ;歌曲總數
OUT_NUM EQU P1 ;數碼管顯視當前所放歌曲曲數
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP LAST_SONG ;外部中斷0用于接上一曲歌按鍵
ORG 000BH
AJMP F_T0 ;定時器0用于定時,作音符發生器用
ORG 0013H
q4: AJMP NEXT_SONG ;外部中斷1接下一曲歌按鍵
ORG 001BH
AJMP START_PAUSE ;定時器1用計數,這里用作中斷,接開始/暫停鍵,初值為0ffH,方式2
ORG 0030H
MAIN: MOV SP,#60H
MOV DPTR,#TABLE ;DPRT指向每首歌曲的入口地址的地址。
MOV R0,#30H ;R0中存入數據30H,這里在以30H開始的單元存放每首歌曲的入口地址,其中30H,31H存放
;歌曲的節拍入口地址,32H,33H存放歌曲音符入口地址,每首歌占用四個存儲存單元。
MOV R5,#00H ;R5中存放表TABLE中正在執行操作的序號
MOV R6,#1 ;R6存放正在設置入口信息的歌曲數
SET_TAB: MOV A,R5 ;設置每首歌曲的入口信息,存放在以30H開始的存儲單元中。
MOVC A,@A+DPTR
MOV @R0,A
INC R5
INC R0
MOV A,R5
MOVC A,@A+DPTR
MOV @R0,A
INC R5
INC R0
MOV A,R5
MOVC A,@A+DPTR
MOV @R0,A
INC R0
INC R5
MOV A,R5
MOVC A,@A+DPTR
MOV @R0,A
INC R0
INC R5
INC R6 ;設置完一首歌曲后,歌曲數加一
CJNE R6,#N+1,SET_TAB ;是否設置完,沒有便繼續,否則進行下面的操作
;*********************************** 對中斷,計數器的相關參數進行設置
MOV TMOD, #61H ;計數器0工作方式1,計數器1工作方式2
MOV TH1,#0FFH ;給計數器1置初值0FFH,又由于是工作方式2,所以
MOV TL1,#0FFH ;計數器計數為1,相當于一外部中斷。
SETB ET1 ;允許計數器1中斷
SETB ET0 ;允許計數器具0中斷
CLR PT0 ;計數器0為低優先級
SETB PT1 ;計數器1為高優先級
SETB IT0 ;外部中斷0為跳沿觸發
SETB PX0 ;高優先級
SETB IT1 ;外部中斷1為跳沿觸發
SETB PX1 ;高優先級
SETB EX1 ;允許外部中斷1中斷
SETB EX0 ;允許外部中斷定0中斷
SETB EA ;開中斷總開關
SETB TR1 ;定時器1開始工作,作中斷用
SETB OUT ;音頻輸出端口初始化
;*********************************** ;設置結束
CLR F0 ;設置F0=0,用來作暫停/播放的標置位用
MOV 22H,#01H ;22H單元中存放正在播放的歌曲編號
MOV DPTR,#OUT_TAB ;將正在播放的歌曲編號送數碼管顯視
MOV A,22H
MOVC A,@A+DPTR
MOV OUT_NUM,A
MOV R7,#00H ;R7中存放歌曲總信息的入口地址
START0:MOV R4,#00H ;R4存放當前正在播放歌曲的第幾個節拍數
MOV R0,#30H ;30H開始的單元中存放歌曲的入口信息
MOV A,R7 ;將歌曲的節拍表的入口地址送到DPTR
ADD A,R0
MOV R0,A
MOV DPH,@R0
INC R0
MOV DPL,@R0
INC R0
MOV A,R4
INC R4
MOVC A,@A+DPTR ;取出第一節拍數,其實第一個節拍不是歌曲的第一個節拍,而是表示幾分音符
;****************************************************
MOV 26H,A ;將取出的音符數+節拍數保存在職26H單元中
NEXT: MOV R0,#30H ;開始取出歌曲的第一個數據
MOV A,R7
ADD A,R0
MOV R0,A
MOV DPH,@R0
INC R0
MOV DPL,@R0
INC R0
MOV A,R4
INC R4
MOVC A,@A+DPTR ;放在A中
;****************************************************
JZ END0 ;若為0,則表示為休止符,不唱,本次音符不唱,
MOV R1,A ;不為0,取出節拍數
ANL A,#0FH
MOV R2,A
MOV A,R1
SWAP A
ANL A,#0FH
JNZ SING ;音符不為0,唱
CLR TR0 ;為0,不唱,關頻率發生器
SJMP SING1
SING: DEC A ;開始唱,進行相應的數據處理
MOV R3,A
RL A
MOV DPH,@R0
INC R0
MOV DPL,@R0
INC R0
MOVC A,@A+DPTR
MOV 21H,A
MOV TH0,A
MOV A,R3
RL A
INC A
MOVC A,@A+DPTR
MOV 20H,A
MOV TL0,A
SETB TR0 ;開唱
SING1:LCALL DELAY ;每個音符唱多久
JB F0,FOR ;是否暫停,
AJMP NEXT ;沒有暫停,繼續
FOR: CLR TR0 ;暫停,不唱
JB F0,$ ;等待播放
AJMP NEXT ;開始播放
END0: CLR TR0 ;不唱
MOV A,22H ;唱完處理
CJNE A,#N,WW ;是不是全部歌曲都唱完
MOV 22H,#01H ;全部唱完,則從第一首開始再唱
MOV R7,#00H
MOV OUT_NUM,#06H ;數碼管顯視第一首歌曲編號
AJMP WWW
WW: MOV A,R7 ;沒有全部唱完,唱下一首,歌曲的入口信息調整
ADD A,#4
MOV R7,A
INC 22H
CLR EA
PUSH DPH
PUSH DPL
MOV A,22H
MOV DPTR,#OUT_TAB
MOVC A,@A+DPTR
MOV OUT_NUM,A ;數碼管顯視相應的歌曲編號
POP DPL
POP DPH
WWW: SETB EA
AJMP START0 ;開始下一首的演唱
F_T0: MOV TH0,21H ;定時器0置初值
MOV TL0,20H
CPL OUT ;頻率產生
RETI
NEXT_SONG: PUSH ACC ;下一曲中斷程序處理,保護現場
PUSH DPH
PUSH DPL
CLR EA ;關中斷
MOV A,22H
CJNE A,#N,Q ;是最后一首嗎?
MOV R7,#00H ;是最后一首,則R7指向第一首,演唱第一首
MOV 22H,#01H
AJMP BACK
Q: INC 22H ;不是最后一首,唱下一首,R7內容加4,歌曲數加1
MOV A,R7
ADD A,#4
MOV R7,A
BACK: MOV R4,#00H ;數碼管顯視相應的歌曲編號
MOV A,22H
MOV DPTR,#OUT_TAB
MOVC A,@A+DPTR
MOV OUT_NUM,A
;********************************************
MOV B,R0 ;對下首要演唱的歌曲的幾分拍進行調整,同時對R0中的內容進行保護
MOV R4,#00H
MOV R0,#30H
MOV A,R7
ADD A,R0
MOV R0,A
MOV DPH,@R0
INC R0
MOV DPL,@R0
INC R0
MOV A,R4
INC R4
MOVC A,@A+DPTR
MOV 26H,A ;結果存入26H單元中
DEC R4
MOV R0,B ;恢復R0中的內容
;********************************************
POP DPL ;恢復現場
POP DPH
POP ACC
SETB EA
RETI ;中斷返回
LAST_SONG: PUSH ACC ;上一曲中斷程序處理開始,保護現場
PUSH DPH
PUSH DPL
CLR EA ;關中斷
MOV A,22H ;曲目數送A
CJNE A,#1,QQ ;是否是第一首
MOV 22H,#N ;是第一首歌曲
MOV B,#4 ;將R7指向最后一首歌曲
MOV A,#N-1
MUL AB
MOV R7,A
AJMP BACK2 ;處理結束
QQ: DEC 22H
MOV A,R7 ;R7減4
SUBB A,#4
MOV R7,A
BACK2: MOV R4,#00H
MOV A,22H
MOV DPTR,#OUT_TAB
MOVC A,@A+DPTR
MOV OUT_NUM,A ;數碼管顯視相應歌曲的編號
;********************************************
MOV B,R0 ;對下首要演唱的歌曲的幾分拍進行調整,同時對R0中的內容進行保護
MOV R4,#00H
MOV R0,#30H
MOV A,R7
ADD A,R0
MOV R0,A
MOV DPH,@R0
INC R0
MOV DPL,@R0
INC R0
MOV A,R4
INC R4
MOVC A,@A+DPTR
MOV 26H,A ;結果存入26H單元中
DEC R4
MOV R0,B ;R0中的內容恢復
END;
完整版見附件
一個匯編的播放器.zip
(19.48 KB, 下載次數: 11)
2018-12-15 18:41 上傳
點擊文件名下載附件
|