1.原理
(1)定义音符和节拍:音符根据表格。
节拍根据12,25,50存入,根据公式计算脉冲和持续时间。
(2)通过不断变换端口61h第一位的值,控制开关电路发出一串脉冲。
2.代码
datas segment
;定义音频表
freq dw 2 dup(262,294,330,262)
dw 2 dup(330,349,392)
dw 2 dup(392,440,392,349,330,262)
dw 2 dup(294,196,262)
;定义节拍表 一个数字为一拍(25),56加下划线为每一个数字半个节拍(12) 5 ——为两个节拍(50)
beat dw 10 dup(25),50
dw 2 dup(25),50,4 dup(12),25,25,4 dup(12),25,25
dw 25,25,50,25,25,50
datas ends
codes segment
main proc far
assume cs:codes,ds:datas
org 100h
start:
mov ax,datas
mov ds,ax
mov cx,32d
lea si,freq
lea di,beat
play:
push cx
call player
add si,2d
add di,2d
pop cx
loop play
mov al,48h
out 61h,al
mov ah,4ch
int 21h
main endp
;播放一个字符
player proc near
;将音符的频率转化为控制脉冲宽度的计数值 75页 脉宽 = 2801 * 50 / freq
mov ax,2801
mov bx,50
mul bx
mov bx,[si] ;取出在freq中的对应的音符的频率
div bx;计算脉宽
mov dx,ax ;存放脉宽
push dx ;16位的乘法,结果放在ax dx中
;计算节拍 节拍决定了各音频持续的时间
mov bx,[di]
mov ax,120 ; 8太快
mul bx ;16位的乘法,结果放在ax bx中
mov bx,ax
;位触发模式发声
in al,61h
mov ah,al
and al,11111100b
pop dx
silent:
xor al,2
out 61h,al
mov cx,dx
wait1:
loop wait1
dec bx
jnz silent
mov al,ah
out 61h,al
ret
player endp
codes ends
end start