1、1学 号: 0120910340933课 程 设 计课程名称 汇编语言程序设计题 目 乐曲程序的设计与实现学 院 计算机科学与技术学院专 业 计算机科学与技术班 级 0909 班姓 名 王嘉辛指导教师 伍新华2012 年 1 月 3 日目 录目录课程设计任务书 .11 实验内容、目的 .11.1 实验内容 .11.2 实验目的 .12 设计中使用的关键技术及方法 22.1 位触发方式 22.2 利用定时器产生声音.32.3 扬声器驱动方式42.4 主要的发生器件52.5 乐曲构成63 设计方案说明 63.1 设计思路63.2 程序流程图 73.3 关键代码设计实现及分析84 调试过程及实验结果
2、分析114.1 调试过程 114.2 实验结果 125 设计心得与改进方案 135.1 心得体会 135.2 改进方案 136 参考文献147 附录 源程序 14本科生课程设计成绩评定表 18 1课程设计任务书学生姓名: 王嘉辛 专业班级: 计算机科学与技术学院 0909 指导教师: 伍新华 工作单位:计算机科学与技术学院 题目: 乐曲程序的设计与实现初始条件:理论:完成了汇编语言程序设计课程,对微机系统结构和 80 系列指令系统有了较深入的理解,已掌握了汇编语言程序设计的基本方法和技巧。实践:完成了汇编语言程序设计的 4 个实验,熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法。要
3、求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)进一步理解和掌握程序直接控制 I/O 方式,掌握计算机发声程序的设计。具体的设计任务及要求:1采用位触发方式编写程序,使计算机发出音响并演奏乐曲(例如两只老虎等) 。1) 进一步理解程序直接控制 I/O 方式和位触发方式控制声音的工作原理。2) 一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编写乐曲程序的关键。根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;3) 编写程序并调试通过。2了解定时器的工作原理,掌握利用定时器产生声音的方法,使计算机演奏乐曲(例如两只老虎等) 。编写程序并调
4、试通过。在完成设计任务后,按要求撰写课程设计说明书;对课程设计说明书的具体要求请见课程设计指导书。阅读资料:1) IBMPC 汇编语言程序设计实验教程3.1 节2) IBMPC 汇编语言程序设计(第 2 版) 10.4 节,10.5 节时间安排:设计安排一周:周 1、周 2:完成系统分析及设计。周 3、周 4:完成程序调试,和验收。周 5:撰写课程设计报告。指导教师签名: 年 月 日系主任(或责任教师)签名: 年 月 日武汉理工大学汇编语言程序设计课程设计1乐曲程序的设计与实现1实验内容、目的1.1 实验内容1进一步理解和掌握程序直接控制 I/O 方式,掌握计算机发声程序的设计。具体的设计任务
5、及要求:1) 进一步理解程序直接控制 I/O 方式和位触发方式控制声音的工作原理。2) 一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编写乐曲程序的关键。根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;3) 编写程序并调试通过。2了解定时器的工作原理,掌握利用定时器产生声音的方法,使计算机演奏乐曲(例如两只老虎等) 。编写程序并调试通过。1.2 实验目的汇编语言是计算机能够提供给用户使用的最快而又有效的语言,也是能够用计算机所有硬件特性并能直接控制硬件的唯一语言。通过这次实验要求我们:1) 了解通用发生程序。2) 了解与掌握定时、计数、音乐、频率、时间之间的关系。
6、3) 学会用发生程序的设计方法4) 学会用汇编语言编辑音乐程序通过音乐程序设计熟悉并掌握用汇编语言编程的方法和特点,借此来比较高级语言低级语言的优缺点,以便更好运用各种语言来开发应用软件通过实际动手能力的培养,进一步熟悉汇编语言的结构和使用方法,达到能独立阅读、编制和调试一定规模的汇编语言程序的水平。能用汇编语言熟练的运用三大结构,进一步掌握各个指令的功能,特别是转向指令,能掌握子程序的定义及调用,包括段间及段内调用,以及正确的运用武汉理工大学汇编语言程序设计课程设计2DEBUG 指令,进一步理解和掌握程序直接控制 I/O 方式。2.设计中使用的关键技术及方法ROM BIOS 中有个 BEEP
7、 子程序,这能根据 BL 中组出的时间计数值控制 8254 定时器,产生持续时间为 1 个或几个 0.5 秒,频率为 896HZ 的声音,我们可以利用并修改 BEEP,使其产生任一频率的声音。为此我们需要做两点修改,首先,BEEP 程序只能产生 896HZ 的声音,我们的通用发声程序应能产生任一频率的声音。其次,BEEP 产生声音的持续时间(音长)只能是 0.5 秒的倍数,我们希望声音的持续时间更易于调整,例如可以是 10ms的倍数。我们知道 BEEP 能将计数值 533H 送给定时器 2 产生 896HZ 的声音的,那么产生其它频率声音的时间计数值应为:533H896给定频率=123280H
8、给定频率发声程序包括 3 个步骤: (1)在 8253 中的 42 端口送一个控制字 0B6H(10110110B) ,该控制字对定时器 2 进行初始化,使定时器 2 准备接收计数初值。(2)在 8253 中的 42H 端口(Timer2)装入一个 16 位的计数值(533H895/频率) ,以建立将要产生的声音频率。(3)把输出端口 61H 的 PB0、PB1 两位置 1,发出声音。2.1 位触发方式程序直接控制 PPI(8255A 可编程序外围接口芯片)的输出控制器(I/O 端口为61H)的第一位,使该位按所需的频率进行 1 和 0 的交替变化,从而控制开关电路产生一串脉冲波形,这些脉冲波
9、形经放大后驱动扬声器发出声音。如果控制波形的脉宽和长度就可以产生不同频率和不同音长的声音。扬声器发声通用子程序:通用发生程序 CFSOUND:cfsound proc nearpush dx 保存将要用到的寄存器push axin al,61hmov ah,al武汉理工大学汇编语言程序设计课程设计3and al.11111100b 关断定时器通道 2 的门控sound:xor al,2 触发 61h 端口第一位out 61h,al mov ax,2801mov bx,50mul bxdiv cx (cx)=freqmov dx,axmov cx,dx (dx)=控制脉宽的计数值wait: lo
10、op wait 延时循环mov ax,8mul bxmov bx,ax (bx)=扩大 8 倍的节拍计数器dec bx (bx)=脉冲持续的时间jnz soundpop ax 恢复寄存器pop dxmov al,ah 写回 61H 口原值,关闭扬声out 61h,alret 子程序结束返回cfsound endp2.2 利用定时器产生声音利用机器硬件即 INTEL8253/8254 定时器产生声音的一种方法。CPU 通过对定时器的通道 2(端口地址为 42H)进行编程,使其 I/O 寄存器接收一个控制声音频率的 16 位计数值,端口 61H 的最低位控制通道 2 门控的开断,以产生特殊的音响。
11、当定时器接收的计数值为 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 选择计数器,确定控制字是对哪一个计数器进行初始化。武汉理工大学汇编语言程序设计课程设计4利用定时器产生制定频率声音
12、的程序段:Mov al,10110110b 为组合格式:通道 2,两字节技术,模式 3,二进制码Out 43h,al 幻数送方式寄存器Mov dx,12hMov ax,34dchDiv di (di)=FreqOut 42h,al 频率计数值送通道 2 Mov al,ahOut 42h,al控制音长的时间可以简单的通过反复执行循环指令来得到。我们已执行 2810 次 LOOP指令约需要 10ms 时间,因此使用 10ms 的倍数值来控制扬声器开关的时间间隔,就可以控制音长。具体实现的指令序列如下:In al,61hMov ah,alOr al,3Out 61h,al 接通扬声器Leng:mov
13、 cx,2801 10ms 音长的计数器Delay:loop delayDec bx (bx)=10ms 的倍数值 Jnz lengMov al,ahOut 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 相连
14、,当 PBO=1 时,GATE2获得高电平,是定时器 2 可以在模式 3 下工作。定时器 2 的 OUT2 与端口 61H 的 PBI 通过一个与门与扬声器的驱动电路相连。当 PBI=1 时,允许 OUT2 的输出信号到达扬声器电路。控制扬声器的代码:In al,16hMov ah,alOr al,00000011bOut 61h,al武汉理工大学汇编语言程序设计课程设计5Mov al,ahOut 61h,al2.4 主要的发生器件(可编程时间间隔定时器 8251/54)在 8253/54 定时器内部有 3 个独立工作的计数器:counter0,counter1,counter2,个计数器都分
15、配有一个端口地址,分别为 40H,41H 和 42H。8253/54 内部还有一个公用的控制寄存器,端口地址为 43H。端口地址输入到 8253/54 的 CS,AL,AO 端,分别对 3 个计数器和控制器寻址。如图下图所示:8253/54 定时器结构图对 8253/54 编程时,先要设定控制字,来选择计数器,确定工作模式和计数值的格式。每个计数器由 3 个引腿和外部联系。CLK 为时钟输入端,GATE 为门控信号输入端,OUT 为技术/定时信号输出端。每个计数器中包含一个 16 位的计数寄存器,这个计数器是以倒计数的方式计数的,也就是说,从计数初值开始逐次减 1,直到减为 0 为止。同时 8
16、253/54 三个计数器是分别编程的,对任一个计数器编程时,必须首先将控制字写入控制寄存器。控制字的作用是确定需要使用的计数器,同时确定要求输出的脉冲波形。另外,对 8253/54 的初始化工作还包括,向选定的计数器送入一个计数初值,因为这个计数值可以是 8 位的,也可以是 16 位的,而 8253/54 的数据总线是 8 位的,所以要用两条输出指令来写入初值。控制字节由 8 位组成即 D7,D6,D5,D4,D3,D2,D1,D0 选择计数值的格式,1为 BCD 码格式,0 为二进制格式。D3,D2,D1 选择操作模式,它决定了输出脉冲的形状。武汉理工大学汇编语言程序设计课程设计6D5,D4
17、 读写指示位。D7,D6 选择计数器,确定控制字是对哪一个计数器进行初始化。对 8253/54 设置初始值时,一定要符合控制的格式规定,是二进制数还是 BCD 码表示的数,是只写高(低)字节,还是高低字节都写。控制字一旦做出决定,程序中给出的计数值就要和控制的要求一致。2.5 乐曲构成由于把很多发生程序“结合”就构成理论上的曲子,所以利用计算机控制发生的原理,可以编写演奏乐曲的音调。在一首乐曲中,每个音符的音高和音场与频率和节拍有关。组成乐曲的每个音符的频率值和持续时间是乐曲程序发声所需要的两个数据。音符的持续时间是根据乐曲的速度及每个音符的节拍数来确定。在 4/4(四四拍)中,四分音符为 1
18、 拍,每小节 4 拍,全音符持续 4 拍,二分音符持续 2 拍,四分音符持续 1 拍,八分音符持续半拍等。如果给全音符的持续时间为 0.25s(25*10ms) ,八分音符的持续时间为 0.125(12.5*10ms).音符的频率参考下表编写:1 2 3 4 5 6 7低音 131 147 165 175 196 220 247中音 262 294 330 349 392 220 494高音 524 588 660 698 784 880 9843.设计方案说明3.1 设计思路编写这个乐曲程序可分为四个步骤:1) 定义频率表和时间表根据音阶表和简谱为演奏的乐曲定义一个频率表 FREQ 和一个节拍时间表TIME.2) 将两个表的偏移地址放入 SI 和 DILEA SI,MUS_FREQLEA BP,DS:MUS_TIME3) 取频率和时间武汉理工大学汇编语言程序设计课程设计7MOV DI,SIMOV BX,DS:BP 4) 调用 SOUND 子程序发出音调3.2 程序流程图主程序流程图