?? 6muisc.asm
字號:
;六首唱歌的音樂程序按p3.4循環
;***************************************************************************
;* sxj1974@163.com (51c51 test web) www.8951.com *
;* Create by :石學軍 www.51c51.com 更多例程請登陸網站 *
;***************************************************************************
;
org 00h ;主程序起始地址
jmp start ;跳動主程序
org 0bh ;timer0中斷起始地址
jmp tim0 ;跳至timer0在mode1
start: mov tmod,#00000001b ;設timer0在mode1
mov ie,#10000010b ;中斷使能
jb p3.4,$ ;第一次按to?
call delay1 ;消除抖動
jnb p3.4,$ ;to放開?
mov 31h,#00 ;按to次數計數指針初值為00h
start0:
mov 30h,#low song ;取簡譜碼指針(第1首)
next: mov a,30h
mov dptr,#table
movc a,@a+dptr ;至相關頁碼,高4位為音符的高低
mov r2,a ;低4位為音符的節拍
jz end0 ;檢查簡譜碼是否已結束(有無00?)
anl a,#0fh ;取節拍(低4位)
mov r5,a ;存入r5,節拍的時間
mov a,r2
swap a
anl a,#0fh ;取音頻值(高4位)
jnz sing ;是否為0,是0則不發音
clr tr0
jmp d1
sing: dec a ;因0不列入
mov 22h,a ;存入(22h)
rl a ;乘2
mov dptr,#table
movc a,@a+dptr ;至table取碼,取t的值
mov th0,a ;取到的高位字節存入th0
mov 21h,a ;取到的高位字節存入(21h)
mov a,22h ;再載入取到的音符碼
rl a ;乘2
inc a ;加1
movc a,@a+dptr ;至table取相對的低位字節計數值
mov tl0,a ;取到的低位字節存入tl0
mov 20h,a ;取到的低位字節存入(20h)
setb tr0 ;啟動timer0
d1: call delay
inc 30h ;取簡譜碼指針加1
jmp next
end0: clr tr0 ;停止計數器
mov a,31h ;載入計次指針
xrl a,#00h ;是否按第1次?
jnz end1 ;不是則跳至end1
jb p3.4,$ ;按第2次?
call delay1 ;消除抖動
jnb p3.4,$ ;放開否?
inc 31h ;計次地址(31h)加1
mov 30h,#low song1 ;第2首歌指針
jmp next
end1:
mov a,31h ;載入計次指針
xrl a,#01h ;是否按第2次?
jnz end2 ;不是則跳至end2
jb p3.4,$ ;按第3次?
call delay1 ;消除抖動
jnb p3.4,$ ;放開否?
inc 31h ;計次地址(31h)加1
mov 30h,#low song2 ;第3首歌指針
jmp next
end2:
mov a,31h ;載入計次指針
xrl a,#02h ;是否按第3次?
jnz end3 ;不是則跳至end3
jb p3.4,$ ;按第4次?
call delay1 ;消除抖動
jnb p3.4,$ ;放開否?
inc 31h ;計次地址(31h)加1
mov 30h,#low song3 ;第4首歌指針
jmp next
end3:
mov a,31h ;載入計次指針
xrl a,#03h ;是否按第4次?
jnz end4 ;不是則跳至end4
jb p3.4,$ ;按第5次?
call delay1 ;消除抖動
jnb p3.4,$ ;放開否?
inc 31h ;計次地址(31h)加1
mov 30h,#low song4 ;第5首歌指針
jmp next
end4:
mov a,31h ;載入計次指針
xrl a,#01h ;是否按第5次?
jnz end5 ;不是則跳至end2
jb p3.4,$ ;按第6次?
call delay1 ;消除抖動
jnb p3.4,$ ;放開否?
inc 31h ;計次地址(31h)加1
mov 30h,#low song5 ;第6首歌指針
jmp next
end5:
jmp start ;回到第1次位置
tim0: push acc ;將a的值暫存于堆棧
push psw ;將psw的值暫存于堆棧
setb rs0 ;設工作寄存器庫1,rs0=1,rs1=0
clr rs1
mov tl0,20h ;重設計數值
mov th0,21h
cpl p3.3 ;將p10位反相
pop psw ;至堆棧取回psw的值
pop acc ;至堆棧取回a的值
reti ;返回主程序
delay: mov r7,#02 ;125秒
d2: mov r4,#125
d3: mov r3,#248
djnz r3,$
djnz r4,d3
djnz r7,d2
djnz r5,delay ;決定節拍
ret
delay1: mov r4,#20
d4: mov r3,#248
djnz r3,$
djnz r4,d4
ret
org 300h
table:
dw 64260,64400,64524,64580
dw 64684,64777,64820,64898
dw 64968,65030,65058,65110
dw 65157,65178,65217
song: ;第一首歌 哈 巴 狗
;1
db 42h,42h,42h,52h,64h,04h
db 62h,62h,62h,72h,84h,04h
db 92h,92h,82h,72h,64h,04h
db 82h,82h,52h,62h,44h,04h
;2
db 42h,42h,42h,52h,62h,04h
db 62h,62h,62h,72h,84h,04h
db 92h,92h,82h,72h,64h,04h
db 82h,82h,52h,62h,44h,04h
db 00h
song1: ;第2首歌 生 日 快 樂
;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
db 00h
song2: ;第3首歌 不 倒 翁
;1
db 84h,94h,88h
db 64h,54h,68h
db 84h,64h,54h,44h
db 52h,42h,52h,62h,48h
db 00h
;2
db 84h,94h,88h
db 64h,54h,68h
db 84h,64h,54h,44h
db 52h,42h,52h,62h,48h
db 00h
song3: ;第4首歌 妹妹背著洋娃娃
;1
db 84h,02h,82h,64h,54h
db 64h,54h,48h
db 64h,02h,52h,44h,24h
db 14h,24h,18h
;2
db 24h,02h,22h,42h,24h
db 44h,54h,68h
db 54h,02h,52h,84h,84h
db 54h,64h,48h
db 00h
song4: ;第5首歌 兩只老虎
;1
db 44h,54h,64h,44h
db 44h,54h,64h,44h
db 64h,74h,88h
db 64h,74h,88h
;2
db 82h,92h,82h,72h,64h,44h
db 82h,92h,82h,72h,64h,44h
db 44h,84h,48h
db 44h,14h,48h
song5: ;第6首歌 三只小貓
;1
db 62h,82h,82h,62h,98h
db 92h,0b2h,0b2h,82h,98h
db 62h,82h,82h,52h,68h
db 92h,0b2h,0b2h,82h,98h
;2
db 62h,82h,82h,62h,92h,92h,94h
db 92h,0b2h,0b2h,92h,84h,94h
db 0b8h,0b4h,04h
db 00h
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -