📄 yinyue.asm
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;生日快乐歌汇编源程序《摘自8051单片机实践与应用》(吴金戌著);;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;简谱见光盘;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 00H ;主程序起始地址
JMP START ;跳至主程序
ORG 0BH ;Timer0中断起始地址
JMP TIM0 ;跳至Timer0中断子程序
START: ;主程序
MOV TMOD,#01H ;设置Timer0工作在MODE1
MOV IE,#82H ;Timer0中断使能
START0:
MOV 30H,#00H ;取简谱码指针,30H为寄存器
NEXT:
MOV A,30H ;简谱码指针载入累加器A
MOV DPTR,#TABLE ;去TABLE取简谱码
MOVC A,@A+DPTR
MOV R2,A ;取到的简谱码暂存于R2
JZ END0 ;是否取到00(结束码)?
ANL A,#0FH ;不是,则取低四位(节拍码)
MOV R5,A ;将节拍码存入R5
MOV A,R2 ;将取到的简谱码再载入A
SWAP A ;高低4位交换
ANL A,#0FH ;取低4位(音符码)
JNZ SING ;取到的音符码是否为0?
CLR TR0 ;是则不发音
JMP D1 ;跳至D1
SING: ;演奏子程序
DEC A ;取到的音符码减1(不含0)
MOV 22H,A ;存入22H(寄存器)
RL A ;乘2
MOV DPTR,#TABLE1 ;至TABLE1取相对高位字节计数值
MOVC A,@A+DPTR
MOV TH0,A ;取到的高位字节存入TH0
MOV 21H,A ;取到的高位字节存入21H
MOV A,22H ;再载入取到的音符码
RL A ;乘2
INC A ;加1
MOVC A,@A+DPTR ;至TABLE1取相对低位字节计数值
MOV TL0,A ;取到的低位字节存入TL0
MOV 20H,A ;取到的低位字节存入20H
SETB TR0 ;启动定时器Timer0
D1:
CALL DELAY ;基本单位时间1/4拍187毫秒
INC 30H ;取简谱码指针加1
JMP NEXT ;取下一个码
END0:
CLR TR0 ;停止Timer0
JMP START0 ;重复循环
TIM0: ;Timer0中断子程序
PUSH ACC ;将A的值暂存于堆栈
PUSH PSW ;将PSW的值暂存于堆栈
MOV TL0,20H ;重设计数值
MOV TH0,21H
CPL P3.3 ;将P3.3反相以产生方波
POP PSW ;去堆栈取回PSW的值
POP ACC ;去堆栈取回A的值
RETI ;中断返回
DELAY: ;延时187毫秒
MOV R7,#02
D2:
MOV R4,#187
D3:
MOV R3,#248
DJNZ R3,$
DJNZ R4,D3
DJNZ R7,D2
DJNZ R5,DELAY ;决定节拍
RET
TABLE1: ;音频表
DW 64260,64400,64524,64580
DW 64684,64777,64820,64898
DW 64968,65030,65058,65110
DW 65157,65178,65217
TABLE: ;简谱码
;1
DB 82H,01H,81H,94H,84H
DB 0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H
DB 0C4H,0B4H,04H
;2
DB 82H,01H,81H,0F4H,0D4H
DB 0B4H,0A4H,94H
DB 82H,01H,81H,94H,84H
DB 0C4H,0B4H,04H
;3
DB 82H,01H,81H,94H,84H
DB 0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H
DB 0C4H,0B4H,04H
;4
DB 82H,01H,81H,0F4H,0D4H
DB 0B4H,0A4H,94H
DB 82H,01H,81H,94H,84H
DB 0C4H,0B4H,04H
;Over
DB 00
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -