BUZZER EQU P2.4
org 0000h ;主程序起始地址
ajmp main ;跳至主程序
org 000bh ;timer0中断起始地址
jmp tim0 ;跳至timer0中断子程序
org 0030h
main:
MOV tmod,#01h ;设timer0在MODE1
MOV ie,#82h ;中断使能
checkkey:
lcall key ;8ms when no key pressed.
cpl a
jz checkkey
MOV a,34h
cjne a,#0ah,checkkey
ajmp start0
start0:
MOV 30h,#00h ;取简谱码指针
next:
lcall key ;8ms when no key pressed.
cpl a
jz begm
MOV a,34h
cjne a,#0bh,begm
ajmp end0
begm:
MOV a,30h ;简谱码指针载入A
MOV dptr,#table ;至table取简谱码
MOV c a,@a+dptr
MOV r2,a ;取到的简谱码暂存于R2
jz end0 ;是否取到00(结束码)?
anl a,#0fh ;不是,则取低4位(节拍码)
MOV r5,a ;将节拍码存入R5
MOV a,r2 ;将取到的简谱码再载入A
swap a ;高低四位交换
anl a,#0fh ;取低四位(音符码)
jnz sing ;取到的音符码是否为零?
clr tr0 ;是,则不发音
jmp d1
sing: dec a ;取到的音符码减1(不含0).
MOV 22h,a ;存入(22H).
rl a ;乘2
MOV dptr,#table1 ;至table1取相对的高位字节计数值
MOV c a,@a+dptr
MOV th0,a ;取到的高位字节存入TH0
MOV 21h,a ;取到的高位字节存入(21H)
MOV a,22h ;再载入取的的音符码
rl a ;乘2
inc a ;加1
MOV c 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 checkkey ;重复循环
tim0:
push aCC ;将A的值暂存于堆栈
push psw ;将psw的值暂存于堆栈
MOV tl0,20h ;重设计数值
MOV th0,21h
cpl BUZZER ;将蜂鸣器反相
pop psw ;至堆栈取回psw的值
pop acc ;至堆栈取回a的值
reti ;返回主程序
delay: MOV r7,#02h ;187毫秒
d2: MOV r4,#187
d3: MOV r3,#248
djnz r3,$
djnz r4,d3
djnz r7,d2
djnz r5,delay ;决定节拍
ret
KEY: LCALL KS
JNZ K1
ljmp key_exit
K1: LCALL delay4ms
LCALL delay4ms
LCALL KS
JNZ K2
ljmp key_exit
上一篇:超声波测距测温的工作原理