ORG 0000H
AJMP LOOOOP
ORG 000BH
AJMP TIM0
ORG 001BH
RETI
ORG 0023H
LOOOOP:
MOV
A,#01H
LOOOP: MOV P2,#0F3H
MOV P1,A
RL A
MOV R2,#0FFH
DELAY0:MOV R3,#0FFH
DJNZ R3,$
MOV R4,#0FFH
DJNZ R4,$
DJNZ R2,DELAY0
JNB
P3.3,START
LJMP LOOOP
START: MOV P2,#06H
MOV TMOD,#00010001B
MOV IE,#10101010B
MOV DPTR,#TAB2 ;装第一首歌
MOV 30H,DPL ;DPTR低8位送30H暂存
MOV 31H,DPH ;DPTR高8位送31H暂存
START1: INC R4 ;产生8位随机数
MOV A,#01010101B
MOV B,R4
MUL AB ;8位随机数由P1口输出
MOV P1,A
MOV DPL,30H
MOV DPH,31H
MOV A,#00H
MOVC A,@A+DPTR ;查表
MOV R0,A ;音符数据送R0崭存
MOV A,#00H
INC DPTR
MOVC A,@A+DPTR ;查表
MOV R1,A ;节拍数据送R1崭存
INC DPTR
MOV 30H,DPL
MOV 31H,DPH
CJNE A,#01H,ELECT ;一首歌没结束转ELECT
ELECT: JZ START ;所有歌曲结束转START循环
MOV A,R0
JNZ SING
CLR TR0
SETB P3.7
LOOP1: ACALL DELAY ;调用延时子程序
DJNZ R1,LOOP1
SJMP START1
SING: MOV DPTR,#TAB1 ;音符表首址送DPTR
DEC R0 ;计算音符
MOV A,R0
MOV B,#02H
MUL AB
MOV R0,A
MOVC A,@A+DPTR ;查表
MOV 21H,A
INC DPTR
MOV A,R0
MOVC A,@A+DPTR
MOV 20H,A
MOV TL0,20H
MOV TH0,21H
SETB TR0 ;开T0定时器
LOOP2: ACALL DELAY
DJNZ R1,LOOP2
AJMP START1
TIM0: MOV TL0,20H
MOV TH0,21H
CPL P3.7
RETI ;中断返回
DELAY: MOV R2,#70
DELAY1: MOV R3,#252
DJNZ R3,$
JNB P3.3,AGAIN
;重复正播放的曲子
DJNZ R2,DELAY1
RET
AGAIN: JNB P3.3,$
;等待键释放
;********************(音符表)**********************;
TAB1: DW 63625,63833,64019,64103,64260,64400,64524
DW 64580,64684,64777,64820,64898,64968,65030
DW 65058,65110,65157,65178,65217,65252,65283
;********************(生日歌)**********************;
TAB2: DW 0C08H,0C08H
DW 1310H,1110H,0F10H,0E10H,0D18H,1208H,1208H
DW 1110H,0F10H,1010H,0F18H
DW 0C08H,0C08H,0D10H,0C10H,0F10H,0E18H
DW 0C08H,0C08H,0D10H,0C10H,1010H,0F18H
DW 0C08H,0C08H,1310H,1110H,0F10H,0E10H,0D18H
DW 1208H,1208H,1110H,0F10H,1010H,0F18H
END