📄 乐曲t.asm
字号:
ORG 0000H ;通用音乐程序,适用所有仿真器,配OK-02/03实验器
;及SL-K51L实验板
LJMP L0300 ;为适用SST89F5X单片机而跳转
ORG 0003H ; INT0中断入口地址
LJMP L0303 ; 转INT0中断
ORG 000BH ; T0中断入口地址
LJMP L030B ; 转T0中断
ORG 0013H ; INT1中断入口地址
LJMP L0313 ; 转INT1中断
ORG 0300H ;SST89F5X用户程序首址
L0300: SJMP L0330 ;转主程序
ORG 0303H ;INT0中断入口地址
L0303: LJMP L03F0 ;转INT0中断服务子程序
ORG 030BH ;T0中断入口地址
L030B: LJMP L03A0 ; 转T0中断服务子程序
ORG 0313H ; INT1中断入口地址
L0313: LJMP L0480 ; 转INT1中断服务子程序
ORG 031BH ; T1中断入口地址
RETI ;抗干扰用
ORG 0323H ;串行中断入口地址
RETI ; 抗干扰用
ORG 032BH ; T2中断入口地址
RETI ; 抗干扰用
ORG 0330H ;主程序
L0330: MOV 31H,#8DH ;第一首曲节拍速度值
MOV SP,#60H ;设堆栈
MOV TMOD,#01H ;T0方式1
MOV IE,#87H ;开中断
MOV IP,#04H ;INT1为优先中断
MOV 41H,#06H ;
MOV 40H,#00H ;乐曲首地址为0600H
L0342: MOV 32H,#00H ;曲组编号
L0345: MOV 24H,#01H ;反复放音次数,01H为放l次
NOP
NOP
NOP
MOV 34H,#04H ;
MOV 33H,#51H ;音符表首址,第一首曲音符表为0451H
L0351: MOV 30H,#00H ;取曲指针,00H为第一首乐曲
L0354: MOV A,30H
MOV DPL,40H ;取曲码首址
MOV DPH,41H
MOVC A,@A+DPTR
MOV R2,A ;简码暂存于R2
JZ L038A ;结束则转
ANL A,#0FH ;取节拍码
MOV R5,A ; 节拍码存于R5
MOV A,R2
SWAP A
ANL A,#0FH ;取音符码
JNZ L036D
CLR TR0 ;为0不发音
SJMP L0384 ;延时
L036D: DEC A
MOV 22H,A ;音符码存于22H
RL A
MOV DPTR,#0451H ;取音符码高位字节
MOVC A,@A+DPTR
MOV TH0,A ; 音符码高位字节存于TH0
MOV 21H,A ; 音符码高位字节存于TH0
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR ; 取音符码低位值
MOV TL0,A ; 音符码低位值存于TL0
MOV 20H,A ; 音符码低位值存于20H
SETB TR0 ;启动T0
L0384: ACALL S03B1 ;延时
AJMP L03D1 ;查A超过FFH吗
L0388: SJMP L0354 ;取一个码
L038A: CLR TR0 ;停T0
AJMP L03E0 ;重复
L038E: INC 30H ;曲指针加1
CLR C
MOV A,40H ;查A超过FFH
ADD A,30H
MOV 40H,A
JBC CY,L039C ;超过DPH加1
SJMP L039E ;不超过转
L039C: INC 41H
L039E: AJMP L0420 ;继续
L03A0: PUSH ACC ;T0溢出产生中断,T0中断服务子程序,保护ACC,PSW数据
PUSH PSW
MOV TL0,20H ;T0取数
MOV TH0,21H ;
CPL P1.7 ;P1.7取反,即该脚输出乐曲
POP PSW ;出栈
POP ACC
RETI ;中断返回
S03B1: MOV R7,#02H ;延时子程序
L03B3: MOV R4,31H
L03B5: MOV R3,#0F1H
L03B7: DJNZ R3,$
DJNZ R4,L03B5
DJNZ R7,L03B3
DJNZ R5,S03B1
RET
L03C0: INC 30H ;判是否全部曲结束
MOV A,30H ;一 个单元为00H,表示一首曲结束
MOV DPL,40H ;连续二个单元为00H,表示全部曲结束
MOV DPH,41H
MOVC A,@A+DPTR
JZ L03CF ;全部曲结束转
AJMP L0430 ;转下一首曲
L03CF: AJMP L0300 ;从头开始
L03D1: INC 30H
MOV A,30H
JZ L03D9 ;A超过FFH吗?
AJMP L0388
L03D9: INC 41H ;超过,DPH加1
AJMP L0388 ;继续
ORG 03E3H ;判一首曲反复唱几次
L03E0: DEC 24H
MOV A,24H
CJNE A,#00H,L03EC ;曲间延时
ACALL S0443
AJMP L03C0 ;转下一首曲
NOP
L03EC: ACALL S0443
AJMP L0351
L03F0: PUSH ACC ;快速跳过十首曲中断服务子程序,如P3.2为低电平,表示
;要求跳过十首曲,则INT0中断响应
PUSH DPH ;进载保护数据
PUSH DPL
CLR TR0
MOV R0,#0FFH
L03FA: DJNZ R0,$ ;延时去抖动
MOV A,32H ;跳到第几组(十首为一组)
RL A
MOV 36H,A ;存现在选的曲组
MOV DPTR,#0500H ;取曲组首址
L0404: JNB INT0,$ ;等P3.2升高
MOVC A,@A+DPTR ;取高位地址
MOV 41H,A
INC 36H
MOV A,36H
MOVC A,@A+DPTR ; 取低位地址
MOV 40H,A
INC 32H
SETB TR0 ;开T0
POP DPL ;出栈
POP DPH
POP ACC
RETI ;中断返回
ORG 0420H ;判P3.0为0,反复放该首曲
L0420: JB RXD,L042B ;为1继续放音
MOV 41H,DPH
MOV 40H,DPL
AJMP L0342 ;继续放音
L042B: AJMP L0345 ;反复放音
ORG 0430H ;取曲初始化节拍子程序
L0430: MOV 31H,A
INC 30H
MOV A,30H
MOVC A,@A+DPTR ;取音符高位地址
MOV 34H,A ;
INC 30H
MOV A,30H
MOVC A,@A+DPTR ; 取音符低位地址
MOV 33H,A
LJMP L038E
S0443: PUSH 31H ;延时
MOV 31H,#02H
ACALL S03B1
POP 31H
RET
ORG 0451H ;音符表首地址
DW 0E446H ;低八度音1
DW 0FCAEH ; 低八度音2
DW 0FD0BH ; 低八度音3
DW 0FD34H ; 低八度音4
DW 0FD82H ; 低八度音5
DW 0FDC8H ; 低八度音6
DW 0FE06H ; 低八度音7
DW 0FE22H ;中音1
DW 0FE4FH ; 中音2
DW 0FE85H ; 中音3
DW 0FE9AH ; 中音4
DW 0FEC1H ; 中音5
DW 0FEE4H ; 中音6
DW 0FF03H ; 中音7
DW 0FF11H ; 高八度音1
DW 0FF2BH ; 高八度音2
DW 0FF42H ; 高八度音3
DW 0FF4DH ; 高八度音4
DW 0FF61H ; 高八度音5
DW 0FF72H ; 高八度音6
DW 0FF81H ; 高八度音7
ORG 0480H ;找下一首曲中断服务子程序,由于P3.3低电平
;INT1响应中断
L0480: PUSH ACC ;进栈保护
CLR TR0 ;关T0
MOV R0,#0FFH ;送延时常数
L0486: DJNZ R0,$ ;延时
MOV DPH,41H
MOV DPL,40H
L048E: INC DPTR
MOV A,#00H
MOVC A,@A+DPTR ;找一首曲结束单元
JZ L0496 ;找到转取曲
SJMP L048E ;找不到继续找
L0496: INC DPTR ;
MOV A,#00H
MOVC A,@A+DPTR ;取节拍速度值
MOV 31H,A
INC DPTR
MOV A,#00H
MOVC A,@A+DPTR ;取高符低位值
MOV 34H,A
INC DPTR
MOV A,#00H
MOVC A,@A+DPTR ; 取音符低位值
MOV 33H,A ;保存有关数据
MOV 41H,DPH
MOV 40H,DPL
L04AE: JNB INT1,$ ;等升P3.3高,关中断
SETB TR0 ;开T0
POP ACC ;出栈
RETI ;中断返回
ORG 0500H ;曲组首址
DW 0C64H ;第10首曲地址
DW 1762H ; 第20首曲地址
DW 2076H ; 第30首曲地址
DW 2AF3H ; 第40首曲地址
DW 3571H ; 第50首曲地址
DW 4342H ; 第60首曲地址
DW 4CB2H ; 第70首曲地址
DW 568AH ; 第80首曲地址
DW 5E4CH ; 第90首曲地址
DW 6139H ; 第100首曲地址
DW 6487H ; 第110首曲地址
DW 692BH ; 第120首曲地址
DW 6D65H ; 第130首曲地址
DW 7472H ; 第140首曲地址
DW 79D2H ; 第150首曲地址
ORG 0600H ;乐曲首址
DW 8381H ;第1首曲
DW 9484H
DW 0B4A8H
DW 8381H
DW 9484H
DW 0C4B8H
DW 8381H
DW 0F4D4H
DW 0B4A4H
DW 94E3H
DW 0E1D4H
DW 0B4C4H
DW 0B883H
DW 8194H
DW 84B4H
DW 0A883H
DW 8194H
DW 84C4H
DW 0B883H
DW 81F4H
DW 0D4B4H
DW 0A494H
DW 0E3E1H
DW 0D4B4H
DW 0C4B8H
DW 005DH ; 第2首曲速度值
DW 0159H ; 第2首曲曲码表为0159H开始
DW 0B1C1H ; 第2首曲开始
DW 0B1C1H
DW 0DC92H
DW 0B2CCH
DW 0B1C1H
DW 0B1C1H
DW 0DC82H
DW 92BFH
DW 4652H
DW 6284H
DW 6251H
DW 4146H
DW 4866H
DW 8292H
DW 0B492H
DW 9181H
DW 8688H
DW 96B2H
DW 0B2C4H
DW 0B1C1H
DW 0B191H
DW 9694H
DW 8292H
DW 8282H
DW 0262H
DW 6341H
DW 5261H
DW 5152H
DW 5658H
DW 4244H
DW 5262H
DW 8462H
DW 5141H
DW 4648H
DW 6264H
DW 8292H
DW 0B492H
DW 9181H
DW 8688H
DW 9294H
DW 0B2B2H
DW 0C4B1H
DW 0C1B1H
DW 9196H
DW 9482H
DW 9282H
DW 8202H
DW 6263H
DW 4151H
DW 6151H
DW 414FH
DW 44B2H
DW 0C2D2H
DW 0C1D6H
DW 0D8D4H
DW 0B2C2H
DW 0D2D4H
DW 0A291H
DW 92A1H
DW 9282H
DW 9492H
DW 0B2C2H
DW 0C4A2H
DW 9192H
DW 0A192H
DW 6281H
DW 918CH
DW 0B2C2H
DW 0D2C1H
DW 0D6D8H
DW 0D4B2H
DW 0C2D2H
DW 0D4A2H
DW 9192H
DW 0A192H
DW 8294H
DW 92B2H
DW 0C2C4H
DW 0A292H
DW 9161H
DW 8292H
DW 0B1C1H
DW 0BCB1H
DW 0C1B1H
DW 0C1DCH
DW 92B2H
DW 0CCB1H
DW 0C1B1H
DW 0C1DCH
DW 8292H
DW 0BF46H
DW 5262H
DW 8462H
DW 5141H
DW 4648H
DW 6682H
DW 92B4H
DW 9291H
DW 8186H
DW 8896H
DW 0B2B2H
DW 0C4B1H
DW 0C1B1H
DW 9196H
DW 9482H
DW 9282H
DW 8202H
DW 6263H
DW 4152H
DW 6151H
DW 5256H
DW 5842H
DW 4452H
DW 6284H
DW 6251H
DW 4146H
DW 4862H
DW 6482H
DW 92B4H
DW 9291H
DW 8186H
DW 8892H
DW 94B2H
DW 0B2C4H
DW 0B1C1H
DW 0B191H
DW 9694H
DW 8292H
DW 8282H
DW 0262H
DW 6341H
DW 5161H
DW 5141H
DW 4F44H
DW 0B2C2H
DW 0D2C1H
DW 0D6D8H
DW 0D4B2H
DW 0C2D2H
DW 0D4A2H
DW 9192H
DW 0A192H
DW 8294H
DW 92B2H
DW 0C2C4H
DW 0A291H
DW 92A1H
DW 9262H
DW 8191H
DW 8CB2H
DW 0C2D2H
DW 0C1D6H
DW 0D8D4H
DW 0B2C2H
DW 0D2D4H
DW 0A291H
DW 92A1H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -