本人在网上看了很多关于汇编语言写的音乐程序,发现不容易理解,经过一天的尝试终于完成了汇编语言写的音乐程序,以两只老虎为例,方便大家学习,希望大神们提出宝贵的建议,第一次发代码,挺紧张的,希望大家喜欢。
/**********输出p2.4********/
org 0000h
ajmp main
org 000bh
ajmp timer0
org 001bh
ajmp timer1
org 0030h
main:
mov tmod,#11h
mov th1,#3ch
mov tl1,#0b0h
mov IE,#8ah
mov r0,#0 //音阶和节拍的初始地址
mov r7,#0 //保存节拍初值
mov 20h,r0 //用20h保存音阶地址避免和节拍地址冲突
setb tr1
setb tf0
sjmp $
timer0:
mov dptr,#time
mov a,20h //送音阶地址
movc a,@a+dptr
rl a //地址*2确定音阶定时初值
mov b,a //暂存
mov dptr,#freq //查频率表给T0赋值
movc a,@a+dptr //取高8位初值
mov th0,a
mov a,b
inc a //地址加一,取低8位初值
movc a,@a+dptr
mov tl0,a
setb tr0
cpl p2.4 //输出脉冲
reti
timer1:
mov th1,#3ch //定时50ms
mov tl1,#0b0h
cjne r7,#0,nequ //r7用于中断次数,决定每个音节的长短
mov dptr,#time
inc r0 //取节拍时地址加一
mov a,r0
movc a,@a+dptr
rl a //节拍加倍,决定歌曲播放的快慢
mov r7,a
ajmp exit
nequ: djnz r7,exit //判断一个音阶是否结束
inc r0 //取下一个音阶地址加一
mov 20h,r0 //暂存20h中
mov a,r0 //判断是否为歌曲结束标志
mov dptr,#time
movc a,@a+dptr
cjne a,#0ffh,exit
clr tr0
clr tr1
clr ea
exit:
reti
/****音阶对应初始值*****/
freq:dw 0,63628,63835,64021,64103,64260,64399,64523 //低音1,2,3,4,5,6,7
dw 64579,64684,64777,64819,64898,64968,65030 //中音
dw 65058,65110,65157,65178,65217,65252,65282 //高音
/*************************/
/****音阶和节拍值*****/
time: db 8,4,9,4,10,4,8,4
db 8,4,9,4,10,4,8,4
db 10,4,11,4,12,8
db 10,4,11,4,12,8
db 12,3,13,1,12,3,11,1,10,4,8,4
db 12,3,13,1,12,3,11,1,10,4,8,4
db 9,4,5,4,8,8
db 9,4,5,4,8,8,0xff
end