KEY_Mode BIT P3.3 ;模式
KEY_PLAY_STOP BIT P3.4 ;播放/暂停 KEY_Back_one BIT P3.5 ;上一首 KEY_Next_one BIT P3.6 ;下一首
LCE_piano BIT P3.0 ;电子琴模式指示灯 LED_Music BIT P3.1 ;音乐播放模式指示灯 LED_Rec BIT P3.2 ;录音模式指示灯
BUZZTR BIT P3.7 ;音频输出
LED_7 EQU P0 ;显示的段码
Position_1 BIT P2.7 ;第一个数码管的位码 Position_2 BIT P2.6 ;第二个数码管的位码
;******************************************************************************
ORG 0000H SJMP START ORG 000BH LJMP T0 ORG 001BH LJMP T1 ORG 0030H START:
MOV SP,#70H
MOV TMOD,#11H ;设定时器T0/T1的工作方式都设置为方式一
MOV TH1,#0CFH MOV TL1,#2CH SETB EA SETB ET0 SETB ET1 SETB PT0 CLR TR0 CLR TR1 CLR BUZZTR
CLR PLAY_STOP_Mark MAIN:
;**********************************电子琴************************************
;****************************************************************************
9
Electric_piano: LCALL DELAY_KEY
JNB KEY_Mode,Electric_piano CLR TR0 CLR TR1
CLR LCE_piano SETB LED_Music SETB LED_Rec
MOV DIS_DATA,#10 ;灭数码管 LCALL DISPLAY
Electric_piano_LOOP: LCALL DISPLAY
JNB KEY_Mode,KEY_Mode1 ;放模式
JNB KEY_DO,DO JNB KEY_RE,RE JNB KEY_MI,MI JNB KEY_FA,FA JNB KEY_SO,SO JNB KEY_LA,LA JNB KEY_SI,SI JNB KEY_DO_H,DO_H CLR TR0
LJMP Electric_piano_LOOP KEY_Mode1:
LJMP Play_Music
DO: ; MOV Music_Temp_TH0,#0FCH MOV Music_Temp_TL0,#44H MOV DIS_DATA,#1 SETB TR0
LJMP Electric_piano_LOOP
RE: ; MOV Music_Temp_TH0,#0FCH MOV Music_Temp_TL0,#0ACH MOV DIS_DATA,#2 SETB TR0
LJMP Electric_piano_LOOP
MI: ; MOV Music_Temp_TH0,#0FDH MOV Music_Temp_TL0,#09H MOV DIS_DATA,#3
模式按键被按下,则跳转到音乐播音调 中DO 音调 中RE 音调 中MI 10
SETB TR0
LJMP Electric_piano_LOOP
FA: ;音调 中FA MOV Music_Temp_TH0,#0FDH MOV Music_Temp_TL0,#34H MOV DIS_DATA,#4 SETB TR0
LJMP Electric_piano_LOOP
SO: ;音调 中SO MOV Music_Temp_TH0,#0FDH MOV Music_Temp_TL0,#82H MOV DIS_DATA,#5 SETB TR0
LJMP Electric_piano_LOOP
LA: ;音调 中LA MOV Music_Temp_TH0,#0FDH MOV Music_Temp_TL0,#0C8H MOV DIS_DATA,#6 SETB TR0
LJMP Electric_piano_LOOP
SI: ;音调 中SI MOV Music_Temp_TH0,#0FEH MOV Music_Temp_TL0,#06H MOV DIS_DATA,#7 SETB TR0
LJMP Electric_piano_LOOP
DO_H: ;音调 高DO MOV Music_Temp_TH0,#0FEH MOV Music_Temp_TL0,#22H MOV DIS_DATA,#8 SETB TR0
LJMP Electric_piano_LOOP
;*******************************************************************************
;***********************************播放音乐************************************
;*******************************************************************************
Play_Music:
LCALL DELAY_KEY
JNB KEY_Mode,Play_Music
11
SETB LCE_piano CLR LED_Music SETB LED_Rec MOV Track,#0
MOV DIS_DATA,Track
LCALL SET_Music ;设置哪一首音乐? CLR PLAY_STOP_Mark
Play_Music_LOOP: MOV DIS_DATA,Track LCALL DISPLAY
MOV Music_Pointer,#00H ;Musi_LOOP:
LCALL KEY_Musi
JB END_Mark,Music_END_NEXT ; JB PLAY_STOP_Mark,Musi_NEXT CLR TR0
LJMP Musi_LOOP Music_END_NEXT: LJMP Music_END1 Musi_NEXT:
MOV A,Music_Pointer ; MOVC A,@A+DPTR
MOV Music_notation,A Music_notation
JZ Music_END ; MOV A,Music_notation
ANL A,#0FH ; MOV Beat_code,A ; MOV A,Music_notation ; SWAP A ; ANL A,#0FH ; MOV Note_code,A ; JNZ Music_NEXT0 ; CLR TR0 ; LJMP Music_NEXT1 Music_NEXT0:
MOV Note_code,A
RL A ; ;所以要取到相应的音符频率需X2
;地址+2,表头地址+3)
PUSH DPH
12
取简谱码指针 是否为结束标志? 简谱码指针载入A ;取到的简谱码暂存于是否取到00(结束码)? 不是,则取低4位(节拍码) 将节拍码存入Beat_code 将取到的简谱码再载入A 高低四位交换 取低四位(音符码) 音符码暂存
取到的音符码是否为零? 是,则不发音 左移一位相当于乘2
因音符频率的存储型式为双字节,如1(DO)对应的存储地址为:(表头
PUSH DPL
MOV DPTR,#FreTab ;载入音符频率表 MOVC A,@A+DPTR
MOV TH0,A ;取到的高位字节存入TH0 MOV Music_Temp_TH0,A
MOV A,Note_code ;再载入取的的音符码 RL A ;乘2
INC A ;加1,取音符码的第二个字节 MOVC A,@A+DPTR
MOV TL0,A ;取到的低位字节存入TL0
MOV Music_Temp_TL0,A ;取到的低位字节暂存于Music_Temp_TL0
POP DPL POP DPH
SETB TR0 ;启动T0,产生所需的频率 Music_NEXT1: SETB TR1 Musi_LOOP1:
JB END_Mark,Music_END1 ;是否为结束标志? JB Beat_END_Mark,Music_NEXT2 LCALL KEY_Musi
JB PLAY_STOP_Mark,Musi_LOOP1 CLR TR0
LJMP Musi_LOOP1 Music_NEXT2: CLR TR1 CLR TR0
CLR Beat_END_Mark ;清除节拍标志 INC Music_Pointer ;取简谱码指针加1 LJMP Musi_LOOP ;取下一个码
Music_END1: CLR END_Mark Music_END: CLR TR0
CLR TR1 ;停止TIMTR0 LJMP Play_Music_LOOP
;--------------------------------选择音乐
--------------------------------------
;
;作用:根据所提供的音乐编号(Track)得出对应歌曲的简谱码表首地址 ;------------------------------------------------------------------------------
13