在很多儿童玩具或一些需要音乐提示(如报警仪、定时闹钟、电子宠物等)的场合,需要用到单片机音乐编程的功能。原理就是利用单片机的引脚发出某一定频率的信号驱动外部发声设备发出声音,或者放出美妙的音乐。 在这个例程中,音乐曲调的原始编码已做好,只要按照曲谱给定参数即可实现播放不同的乐曲,使实验生动有趣。参数两个:前一个按照曲谱对照编码表给定,第二个,为节拍数,8->1拍,4->半拍。
Beep equ P2.2 ;板子上的蜂鸣器是接的P2.2
musich equ 40h ;音乐定时高位数据
musicl equ 41h ;音乐定时低位数据
musicstart equ 42h ;音乐开始首地址
; ************************ 预定义结束 *******************
org 00h ;程序开始
jmp main ;跳转到主程序
org 1bh ;定时器T1中断入口地址
jmp timer1 ;定时器服务程序
org 030h ;主程序代码开始
main:mov sp,#30h ;设置堆栈
lcall music ;调用音乐程序
jmp main ;重新开始
musdelay:mov r0,#20 ;短时间延时
d:djnz r0,d ;延时时间 20uS
ret ;返回
; ************ 定时器 服务程序 *******************
timer1:clr tr1 ;停止定时器工作
mov th1,musich ;重新设置定时初值
mov tl1,musicl ;
cpl beep ;从蜂鸣器输出声音
setb tr1 ;开始定时工作
reti ;中断返回
;****************************************************
;************ 音乐播放程序 *********************
music:mov tmod,#10h ;设置定时器T1工作方式1
setb ea ;总的中断
setb et1 ;定时器T1中断允许
mov musicstart,#00h ;音乐开始地址
mov musich,#0ffh ;音乐定时常数高位
mov musicl,#0ffh ;音乐定时常数低位
loopm:mov dptr,#mu_tab ;得到音符表头
mov a,musicstart ;开始查表
movc a,@a+dptr ;获得音乐数据
jz musend ;结束符 00H,返回
rl a ;A*2
mov b,a ;暂存地址
mov dptr,#mustab ;获得音符表头
movc a,@a+dptr ;根据音乐数据查得定时常数
mov musich,a ;保存定时常数高位
mov th1,a ;设置定时器高位常数
mov a,b ;开始找低位数据
inc a ;指向下一个数据
mov dptr,#mustab ;得到音符表头
movc a,@a+dptr ;查得低位数据
mov musicl,a ;保存数据
mov tl1,a ;设置定时低位常数
setb tr1 ;定时器T1开始工作
mov dptr,#mu_tab ;得到音乐表
inc musicstart ;指向下一个单元(音符节拍)
mov a,musicstart ;开始查找
movc a,@a+dptr ;找到数据
lcall delay1 ;根据参数延时,发出持续音乐
inc musicstart ;指向下一个音
clr tr1 ;停止发声
lcall delay
jmp loopm ;重复,直到遇到结束符号 00H.
musend:clr tr1 ;乐曲播放完毕,关闭定时器
clr ea ;禁止中断
clr et1 ;关闭定时器T1中断
clr beep ;禁止蜂鸣器
mov a,#20
lcall delay1
ret
;*********************
;************ 节拍发生器 ,产生音乐节拍 *********************************
delay1:mov r0,#00h ;节拍发生器,用来发生节拍
mov r1,#00h ;
mov r2,a ;这是节拍发生器的参数,当它为8
dlay1:djnz r0,dlay1 ;表示1拍
mov r0,#00h
djnz r1,dlay1
mov r0,#00h
mov r1,#00h
djnz r2,dlay1
ret
; ????????????????????
; ******** 延时 产生休止符 *****************
delay:mov r0,#00h ;延时 10ms
mov r1,#100
dlay:djnz r0,dlay
mov r0,#100
djnz r1,dlay
ret
; ************************
; ************************曲谱编码,这是定义的曲谱表,对应如下 **************************************************
; 1 低音 DO 2 低音 RE 3 低音ME 4 低音 FA 5 低音 SO 6 低音LA 7 低音SI
mustab: db 'h','j', 0f8h,8bh, 0f9h,5bh, 0fah,14h, 0fah,0ch, 0fbh,03h, 0fbh,8fh, 0fch,0bh
; 8 中音 DO 9 中音 RE 0ah 中音ME 0bh 中音 FA 0ch 中音 SO 0dh 中音LA 0eh 中音SI
db 0fch,43h, 0fch,0abh, 0fdh,08h, 0fdh,33h, 0fdh,81h, 0fdh,0c7h, 0feh,05h
; 0fh 高音 DO 10h 高音 RE 11h 高音ME 12h 高音 FA 13h 高音 SO 14h 高音LA 15h 高音SI
db 0feh,21h, 0feh,55h, 0feh,84h, 0fdh,99h, 0feh,0c0h, 0feh,0e3h, 0ffh,02h
;以下为音乐乐谱代码,前两位表示曲谱,后一位表示节拍
;8为 1 拍,4 ->半拍
mu_tab: db 6,4,8,4,10,4,1,4, 9,8,8,4,7,4,10,8,9,8,6,16
db 8,4,10,4,12,4,12,4, 13,8,12,4,11,4,10,16
db 00h
end
[此贴子已经被作者于2010-6-26 2:14:01编辑过]
|