武汉理工大学《汇编语言程序设计》课程设计
sound:xor al,2 触发61h端口第一位 out 61h,al mov ax,2801 mov bx,50
mul bx
div cx (cx)=freq mov dx,ax
mov cx,dx (dx)=控制脉宽的计数值 wait: loop wait 延时循环
mov ax,8 mul bx
mov bx,ax (bx)=扩大8倍的节拍计数器 dec bx (bx)=脉冲持续的时间
jnz sound
pop ax 恢复寄存器 pop dx
mov al,ah 写回61H口原值,关闭扬声 out 61h,al
ret 子程序结束返回
cfsound endp
2.2 利用定时器产生声音
利用机器硬件即INTEL8253/8254定时器产生声音的一种方法。
CPU通过对定时器的通道2(端口地址为42H)进行编程,使其I/O寄存器接收一个控制声音频率的16位计数值,端口61H的最低位控制通道2门控的开断,以产生特殊的音响。当定时器接收的计数值为533H时,能产生896Hz的声音,因此产生其他频率(Freq)的计数值就可由下式计算出来:
533H*896/Freq=1234DCH/Freq
在送出频率计数值之前,还要给方式寄存器(端口其值为43H)送一个方式值,也称为幻数。这个幻数由8为组成即D7,D6,D5,D4,D3,D2,D1,D0选择计数值的格式,1为BCD码格式,0为二进制格式。D3,D2,D1选择操作模式,它决定了输出脉冲的形状。D5,D4读写指示位。D7,D6选择计数器,确定控制字是对哪一个计数器进行初始化。
利用定时器产生制定频率声音的程序段:
3
武汉理工大学《汇编语言程序设计》课程设计
Mov al,10110110b 为组合格式:通道2,两字节技术,模式3,二进制码 Out 43h,al 幻数送方式寄存器 Mov dx,12h Mov ax,34dch
Div di (di)=Freq
Out 42h,al 频率计数值送通道2 Mov al,ah Out 42h,al
控制音长的时间可以简单的通过反复执行循环指令来得到。我们已执行2810次LOOP指令约需要10ms时间,因此使用10ms的倍数值来控制扬声器开关的时间间隔,就可以控制音长。具体实现的指令序列如下: In al,61h Mov ah,al Or al,3
Out 61h,al 接通扬声器
Leng:mov cx,2801 10ms音长的计数器 Delay:loop delay
Dec bx (bx)=10ms的倍数值 Jnz leng Mov al,ah
Out 61h,al 关闭扬声器
2.3 扬声器驱动方式
PC机上的大多数I/O都是由主办上的8255可编程序外围接口芯片PPI管理的。PPI包括三个8位寄存器,两个用于输入功能,一个用于输出功能。输入寄存器分配的I/O端口号为60H和62H,输出寄存器分配的I/O端口号为61H。由PPI输出寄存器中的0和1两位来控制扬声器的驱动方式。
连接到扬声器上的是定时器2.GATE2与端口61H的PBO相连,当PBO=1时,GATE2获得高电平,是定时器2可以在模式3下工作。定时器2的OUT2与端口61H的PBI通过一个与门与扬声器的驱动电路相连。当PBI=1时,允许OUT2的输出信号到达扬声器电路。
控制扬声器的代码: In al,16h Mov ah,al
Or al,00000011b Out 61h,al
?????
Mov al,ah
4
武汉理工大学《汇编语言程序设计》课程设计
Out 61h,al
2.4 主要的发生器件(可编程时间间隔定时器8251/54)
在8253/54定时器内部有3个独立工作的计数器:counter0,counter1,counter2,个计数器都分配有一个端口地址,分别为40H,41H和42H。8253/54内部还有一个公用的控制寄存器,端口地址为43H。端口地址输入到8253/54的CS,AL,AO端,分别对3个计数器和控制器寻址。如图下图所示:
8253/54定时器结构图
对8253/54编程时,先要设定控制字,来选择计数器,确定工作模式和计数值的格式。每个计数器由3个引腿和外部联系。CLK为时钟输入端,GATE为门控信号输入端,OUT为技术/定时信号输出端。每个计数器中包含一个16位的计数寄存器,这个计数器是以倒计数的方式计数的,也就是说,从计数初值开始逐次减1,直到减为0为止。
同时8253/54三个计数器是分别编程的,对任一个计数器编程时,必须首先将控制字写入控制寄存器。控制字的作用是确定需要使用的计数器,同时确定要求输出的脉冲波形。另外,对8253/54的初始化工作还包括,向选定的计数器送入一个计数初值,因为这个计数值可以是8位的,也可以是16位的,而8253/54的数据总线是8位的,所以要用两条输出指令来写入初值。
控制字节由8位组成即D7,D6,D5,D4,D3,D2,D1,D0选择计数值的格式,1为BCD码格式,0为二进制格式。D3,D2,D1选择操作模式,它决定了输出脉冲的形状。D5,D4读写指示位。D7,D6选择计数器,确定控制字是对哪一个计数器进行初始化。
对8253/54设置初始值时,一定要符合控制的格式规定,是二进制数还是BCD码表示的数,是只写高(低)字节,还是高低字节都写。控制字一旦做出决定,程序中给出的
5
武汉理工大学《汇编语言程序设计》课程设计
计数值就要和控制的要求一致。
2.5 乐曲构成
由于把很多发生程序“结合”就构成理论上的曲子,所以利用计算机控制发生的原理,可以编写演奏乐曲的音调。在一首乐曲中,每个音符的音高和音场与频率和节拍有关。组成乐曲的每个音符的频率值和持续时间是乐曲程序发声所需要的两个数据。
音符的持续时间是根据乐曲的速度及每个音符的节拍数来确定。在4/4(四四拍)中,四分音符为1拍,每小节4拍,全音符持续4拍,二分音符持续2拍,四分音符持续1拍,八分音符持续半拍等。如果给全音符的持续时间为0.25s(25*10ms),八分音符的持续时间为0.125(12.5*10ms).
音符的频率参考下表编写: 低音 中音 高音 1 131 262 524 2 147 294 588 3 165 330 660 4 175 349 698 5 196 392 784 6 220 220 880 7 247 494 984 3.设计方案说明
3.1 设计思路
编写这个乐曲程序可分为四个步骤: 1) 定义频率表和时间表
根据音阶表和简谱为演奏的乐曲定义一个频率表FREQ和一个节拍时间表
TIME.
2) 将两个表的偏移地址放入SI和DI LEA SI,MUS_FREQ LEA BP,DS:MUS_TIME 3) 取频率和时间 MOV DI,{SI} MOV BX,DS:{BP} 4) 调用SOUND子程序发出音调
6
武汉理工大学《汇编语言程序设计》课程设计
3.2 程序流程图
主程序流程图
说明:在进入主界面的时候有6个选项,分别是 1: MUSIC1 -- MERRY CHRISTMAS
7
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库乐曲程序的设计与实现(2)在线全文阅读。
相关推荐: