📄 ex5-9.asm
字号:
ORG 0000H ;复位地址
LJMP MAIN ;跳转到主程序
ORG 000BH ;T0中断入口
LJMP TIM0 ;跳转到T0中断服务程序
ORG 0030H ;主程序入口地址
MAIN: MOV TMOD,#01H ;写入T0控制字, 16位定时方式
MOV IE,#82H ;开中断
MOV 30H,#00H ;取简谱码指针
NEXT: MOV A,30H ;简谱码指针装入A
MOV DPTR,#TABLE ;从TABLE处取简谱码
MOVC A,@A+DPTR
MOV R2,A ;取得的简谱码暂存于R2
JZ END0 ;是否取到结束码00H?
ANL A,#0FH ;不是,则取节拍码
MOV R5,A ;节拍码存于R5
MOV A,R2 ;将简谱码装入A
SWAP A ;高、低4位交换
ANL A,#0FH ;取音符码
JNZ SING ;取得的音符码是否为0?
CLR TR0 ;是则不发音
lJMP 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和21H单元
MOV 21H,A
MOV A,22H ;再装入取得的音符码
Rl A ;乘2
INC A ;加1
MOVC A,@A+DPTR ;到TABLE1中取相对的低位字节值
MOV TL0,A ;取得的高位字节装入TL0和20H单元
MOV 20H,A
SETB TR0 ;启动T0
D1: LCALL DELAY ;基本单位时间1/4拍,延时187毫秒
INC 30H ;取简谱码指针加1
LJMP NEXT ;取下一个码
END0: CLR TR0 ;停止T0
LJMP MAIN ;重复循环
;定时器T0中断服务程序:
TIM0: PUSH ACC ;保护现场
PUSH PSW
MOV TL0,20H ;重设定时初值
MOV TH0,21H
CPL P1.0 ;P1.0引脚电平取反
POP PSW ;恢复现场
POP ACC
RETI ;中断返回
;基本单位延时子程序:
DELAY: MOV R7,#02H ;fosc=12MHz时延时187毫秒
D2: MOV R4,#187
D3: MOV R3,#248
DJNZ R3,$
DJNZ R4,D3
DJNZ R7,D2
DJNZ R5,DELAY ;决定节拍
RET
;音符对应的定时器初值表:
TABLE1: DW 64260,64400,64521,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 0E2H,01H,0E1H,0D4H,0B4H
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 0E2H,01H,0E1H,0D4H,0B4H
DB 0C4H,0B4H,04H
DB 00H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -