;本程序实现蜂鸣器演奏歌曲功能
;乐曲名称:生日快乐
;///////////////////////////////////////////
    BUZZER EQU P2.3
    org    0000h        ;主程序起始地址
    ajmp    main        ;跳至主程序
    org    000bh        ;timer0中断起始地址
    jmp    tim0        ;跳至timer0中断子程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    org    0030h
main:
    mov    tmod,#01h    ;设timer0在MODE1
    mov    ie,#82h        ;中断使能
start0:
    mov    30h,#00h    ;取简谱码指针
next:    mov    a,30h        ;简谱码指针载入A
    mov    dptr,#table    ;至table取简谱码
    movc    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取相对的高位字节计数值
    movc    a,@a+dptr
    mov    th0,a        ;取到的高位字节存入TH0
    mov    21h,a        ;取到的高位字节存入(21H)
    mov    a,22h        ;再载入取的的音符码
    rl    a        ;乘2
    inc    a        ;加1
    movc    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    start0        ;重复循环
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;time0中断服务子程序用来产生相应的音调脉冲频率。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
table1:
    dw    64260,64400,64524,64580生日快乐mp3
    dw    64684,64777,64820,64898
    dw    64968,65030,65058,65110
    dw    65157,65178,65217
table:
    ;1
    db    82h,01h,81h,94h,84h,0b4h,0a4h,04h,82h,01h,81h,94h,84h,0c4h,0b4h,04h
    ;2
    db    82h,01h,81h,0f4h,0d4h,0b4h,0a4h,94h,0e2h,01h,0e1h,0d4h,0b4h,0c4h,0b4h,04h
    ;3
    db    82h,01h,81h,94h,84h,0b4h,0a4h,04h,82h,01h,81h,94h,84h,0c4h,0b4h,04h
    ;4
    db    82h,01h,81h,0f4h,0d4h,0b4h,0a4h,94h,0e2h,01h,0e1h,0d4h,0b4h,0c4h,0b4h,04h,00
    end