ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:133.59KB ,
资源ID:6681921      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6681921.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(乐曲程序的设计与实现.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

乐曲程序的设计与实现.docx

1、乐曲程序的设计与实现课程名称汇编语言程序设计题 目乐曲程序的设计与实现课程设计任务书 11 实验内容、目的 11.1实验内容 11.2 实验目的 1 2 设计中使用的关键技术及方法 2 2.1 位触发方式 2 2.2 利用定时器产生声音.3 2.3 扬声器驱动方式4 2.4 主要的发生器件5 2.5 乐曲构成6 3 设计方案说明 6 3.1 设计思路6 3.2 程序流程图 7 3.3 关键代码设计实现及分析8 4 调试过程及实验结果分析11 4.1 调试过程 11 4.2 实验结果 12 5 设计心得与改进方案 13 5.1 心得体会 13 5.2 改进方案 13 6 参考文献14 7 附录

2、源程序 14 本科生课程设计成绩评定表 18 课程设计任务书学生姓名: 专业班级: 指导教师: 工作单位:计算机科学与技术学院 题目: 乐曲程序的设计与实现初始条件:理论:完成了汇编语言程序设计课程,对微机系统结构和80系列指令系统有了较深入的理解,已掌握了汇编语言程序设计的基本方法和技巧。实践:完成了汇编语言程序设计的4个实验,熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法。要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)进一步理解和掌握程序直接控制I/O方式,掌握计算机发声程序的设计。具体的设计任务及要求:1采用位触发方式编写程序,使计算机发出

3、音响并演奏乐曲(例如两只老虎等)。1)进一步理解程序直接控制I/O方式和位触发方式控制声音的工作原理。2)一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编写乐曲程序的关键。根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;3)编写程序并调试通过。2了解定时器的工作原理,掌握利用定时器产生声音的方法,使计算机演奏乐曲(例如两只老虎等)。编写程序并调试通过。在完成设计任务后,按要求撰写课程设计说明书;对课程设计说明书的具体要求请见课程设计指导书。阅读资料:1)IBMPC汇编语言程序设计实验教程3.1节2)IBMPC汇编语言程序设计(第2版)10.4节,10.5节时间安排

4、:设计安排一周:周1、周2:完成系统分析及设计。周3、周4:完成程序调试,和验收。周5:撰写课程设计报告。指导教师签名: 年 月 日系主任(或责任教师)签名: 年 月 日乐曲程序的设计与实现1实验内容、目的1.1 实验内容 1进一步理解和掌握程序直接控制I/O方式,掌握计算机发声程序的设计。具体的设计任务及要求:1) 进一步理解程序直接控制I/O方式和位触发方式控制声音的工作原理。2) 一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编写乐曲程序的关键。根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;3) 编写程序并调试通过。2了解定时器的工作原理,掌握利用定时器产

5、生声音的方法,使计算机演奏乐曲(例如两只老虎等)。编写程序并调试通过。1.2 实验目的 汇编语言是计算机能够提供给用户使用的最快而又有效的语言,也是能够用计算机所有硬件特性并能直接控制硬件的唯一语言。通过这次实验要求我们:1)了解通用发生程序。2)了解与掌握定时、计数、音乐、频率、时间之间的关系。3)学会用发生程序的设计方法4)学会用汇编语言编辑音乐程序 通过音乐程序设计熟悉并掌握用汇编语言编程的方法和特点,借此来比较高级语言低级语言的优缺点,以便更好运用各种语言来开发应用软件通过实际动手能力的培养,进一步熟悉汇编语言的结构和使用方法,达到能独立阅读、编制和调试一定规模的汇编语言程序的水平。能

6、用汇编语言熟练的运用三大结构,进一步掌握各个指令的功能,特别是转向指令,能掌握子程序的定义及调用,包括段间及段内调用,以及正确的运用DEBUG指令,进一步理解和掌握程序直接控制I/O方式。2.设计中使用的关键技术及方法ROM BIOS 中有个BEEP子程序,这能根据BL中组出的时间计数值控制8254定时器,产生持续时间为1个或几个0.5秒,频率为896HZ的声音,我们可以利用并修改BEEP,使其产生任一频率的声音。为此我们需要做两点修改,首先,BEEP程序只能产生896HZ的声音,我们的通用发声程序应能产生任一频率的声音。其次,BEEP产生声音的持续时间(音长)只能是0.5秒的倍数,我们希望声

7、音的持续时间更易于调整,例如可以是10ms的倍数。我们知道BEEP能将计数值533H送给定时器2产生896HZ的声音的,那么产生其它频率声音的时间计数值应为:533H896给定频率=123280H给定频率发声程序包括3个步骤: (1)在8253中的42端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使定时器2准备接收计数初值。(2)在8253中的42H端口(Timer2)装入一个16位的计数值(533H895/频率),以建立将要产生的声音频率。(3)把输出端口61H的PB0、PB1两位置1,发出声音。2.1 位触发方式程序直接控制PPI(8255A可编程序外围接口

8、芯片)的输出控制器(I/O端口为61H)的第一位,使该位按所需的频率进行1和0的交替变化,从而控制开关电路产生一串脉冲波形,这些脉冲波形经放大后驱动扬声器发出声音。如果控制波形的脉宽和长度就可以产生不同频率和不同音长的声音。扬声器发声通用子程序:通用发生程序CFSOUND:cfsound proc near push dx 保存将要用到的寄存器 push ax in al,61h mov ah,al and al.11111100b 关断定时器通道2的门控 sound:xor al,2 触发61h端口第一位 out 61h,al mov ax,2801 mov bx,50 mul bx div

9、 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 soundpop ax 恢复寄存器pop dxmov al,ah 写回61H口原值,关闭扬声out 61h,alret 子程序结束返回 cfsound endp2.2 利用定时器产生声音 利用机器硬件即INTEL8253/8254定时器产生声音的一种方法。 CPU通过对定时器的通道2(端口地址为42H)进行编程,使其I/O寄存器接

10、收一个控制声音频率的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选择计数器,确定控制字是对哪一个计数器进行初始化。

11、 利用定时器产生制定频率声音的程序段: 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,

12、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时

13、,GATE2获得高电平,是定时器2可以在模式3下工作。定时器2的OUT2与端口61H的PBI通过一个与门与扬声器的驱动电路相连。当PBI=1时,允许OUT2的输出信号到达扬声器电路。控制扬声器的代码:In al,16hMov ah,alOr al,00000011bOut 61h,alMov al,ahOut 61h,al2.4 主要的发生器件(可编程时间间隔定时器8251/54)在8253/54定时器内部有3个独立工作的计数器:counter0,counter1,counter2,个计数器都分配有一个端口地址,分别为40H,41H和42H。8253/54内部还有一个公用的控制寄存器,端口地址

14、为43H。端口地址输入到8253/54的CS,AL,AO端,分别对3个计数器和控制器寻址。如图下图所示: 8253/54定时器结构图对8253/54编程时,先要设定控制字,来选择计数器,确定工作模式和计数值的格式。每个计数器由3个引腿和外部联系。CLK为时钟输入端,GATE为门控信号输入端,OUT为技术/定时信号输出端。每个计数器中包含一个16位的计数寄存器,这个计数器是以倒计数的方式计数的,也就是说,从计数初值开始逐次减1,直到减为0为止。同时8253/54三个计数器是分别编程的,对任一个计数器编程时,必须首先将控制字写入控制寄存器。控制字的作用是确定需要使用的计数器,同时确定要求输出的脉冲

15、波形。另外,对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码表示的数,是只写高(低)字节,还是高低字节都写。控制字一旦做出决定,程序中

16、给出的计数值就要和控制的要求一致。2.5 乐曲构成由于把很多发生程序“结合”就构成理论上的曲子,所以利用计算机控制发生的原理,可以编写演奏乐曲的音调。在一首乐曲中,每个音符的音高和音场与频率和节拍有关。组成乐曲的每个音符的频率值和持续时间是乐曲程序发声所需要的两个数据。音符的持续时间是根据乐曲的速度及每个音符的节拍数来确定。在4/4(四四拍)中,四分音符为1拍,每小节4拍,全音符持续4拍,二分音符持续2拍,四分音符持续1拍,八分音符持续半拍等。如果给全音符的持续时间为0.25s(25*10ms),八分音符的持续时间为0.125(12.5*10ms).音符的频率参考下表编写:1234567低音1

17、31147165175196220247中音262294330349392220494高音5245886606987848809843.设计方案说明3.1 设计思路 编写这个乐曲程序可分为四个步骤:1)定义频率表和时间表 根据音阶表和简谱为演奏的乐曲定义一个频率表FREQ和一个节拍时间表TIME.2)将两个表的偏移地址放入SI和DI LEA SI,MUS_FREQ LEA BP,DS:MUS_TIME3)取频率和时间 MOV DI,SI MOV BX,DS:BP 4)调用SOUND子程序发出音调3.2 程序流程图 主程序流程图 说明:在进入主界面的时候有6个选项,分别是 1: MUSIC1 -

18、 MERRY CHRISTMAS 2: MUSIC2 TAIHU 3: MUSIC3 - LITTLE BEE4: PLAY BY KEYBOARD5: PRESS 5 TO QUIT6: CLEAR THE SCREEN 通过选择不同的选项进入其子界面来实现不同的功能。3.3 关键代码设计实现及分析3.3.1 程序段说明1) DATAS为数据段,其中存放在程序中所要显示的提示选择信息,还有乐曲的频率表和节拍表,和键盘控制发声对应的音符表。2) CODES为代码段,由于在整个程序中各个子程序都定义为NEAR,所以只需要有一个代码段,各个子程序的定义及实现都放在其中。3.3.2 PLAY_MUS

19、IC 乐曲演奏程序的实现及分析 “PLAY_MUSIC”为播放音乐的子程序,完成的功能是通过SI(频率表的偏移地址) BP(节拍表的偏移地址)(通过主程序传递过来的参数)找到对应的频率(DI)、节拍(BX),再以DI、BX为参数调用SOUNDF子程序来发出声音。关键代码:FREQ: MOV DI, SI CMP DI, 0 JE END_MUSIC MOV BX, DS:BP CALL SOUNDF ; 以DI(频率) BX(节拍)为参数,调用SOUNDF ADD SI, 2 ADD BP, 2JMP FREQ SI, BP是频率表和节拍表的偏移地址,通过寄存器间接寻址方式找到数据段中定义数据

20、,传递给BX和DI,然后调用SOUNDF发出一个频率为DI,节拍数为BX的声音注意: 在频率表中应该设置一个结束标志,“CMP DI, 0”,在这里以0作为结束标志。 3.3.3 SOUNDF通用发声程序的实现及分析 SOUNDF”为以传递过来的频率和节拍数,发出一个音符的频率的子程序。关键代码分析: MOV AL, 0B6H OUT 43H, AL 置43H端口为0B6H,选择计数器2,读/写LSB, MSB , 模式3,计数值为二进制数。 MOV DX, 12H MOV AX, 348CHDIV DI 按照公式,计数值=12348CH f ,商存放在AX中。 OUT 42H, AL MOV

21、 AL, AH OUT 42H, AL825354的数据总线为8位,而计数值为16位,所以应该分两次传递计数值。 IN AL, 61H MOV AH, AL OR AL, 3 OUT 61H, AL将61H的后两位置1,打开扬声器,使其发声。WAIT1: CALL WAITF DEC BX JNZ WAIT1 用WAITF产生一个10ms的延时,BX是节拍(10ms的倍数)。 MOV AL, AH OUT 61H, AL 恢复寄存器状态3.3.4 WAITF延迟程序的实现及分析“WAITF”为通过监控端口61H的PB4固定不变的触发时间来产生延迟时间的子程序。关键代码分析: MOV CX, 6

22、63WAITF1: IN AL, 61H AND AL, 10H ; 查看61H寄存器的第四位(PB4) CMP AL, AH JE WAITF ; PB4每15.08秒触发一次 MOV AH, AL ; LOOP WAITF1 10ms / 15.08us = 663,所以先置CX为663,每次通过调用WAITF都会产生一个10ms的延迟。3.3.5 KEYBOARD键盘发声程序的实现及分析“KEYBOARD”子程序,通过按不同的按键(1 8)来产生不同频率的音符。关键代码分析:PLAY_BY_KB: MOV AH, 7 INT 21H CMP AL, 0DHJE QT MOV BX, OF

23、FSET TABLE CMP AL, 1 JB PLAY_BY_KB CMP AL, 8JA PLAY_BY_KB 输入按键,回车退出,如果不是1 8的话跳转到开始重新输入。 AND AX, 0FH ; 清空AH SHL AX, 1 SUB AX, 2找到索引地址,是DW型的,所以需要乘2,而且是从0开始,应该减去2 MOV SI, AX MOV DI, BXSI MOV BX, 10CALL SOUNDF 通过索引从符号表里面找到对应的频率,调用SOUNDF发出声音。 4、调试过程及实验结果分析4.1调试过程 1: 在刚开始显示字符串的时候,应该加上0DH,0AH换行,而且在字符串的最后应该

24、以$来结尾,然后调用DOS调用 INT 21H,来显示字符串。调试中发现,如果一个字符串末尾不加$的话,DOS调用会直接把之后定义的字符串也同时显示出来,直到遇到$为止。这是由内存的分配模式所决定的,同时定义的变量在内存中会处于相邻位置。2: 在调试子程序KEYBOARD的时候,发现管输入0程序不会返回,是因为在程序中直接 CMP AL, 0。而从键盘输入的是ASC码,0对应的ASC码为30H,所以修改语句如下: CMP AL, 0。3: 在调试KEYBOARD的时候,发现输入1 8 只有7会发出声音,检查后发现由于在TABLE表中定义的是DW字,而在程序中直接将输入符号作为索引值,应该将输入

25、数字减一乘二才能得到正确的索引值。4: 在调用CLEAR的时候,发现每次显示的列表都会向下移动。在清除前应该将光标位置移动到第0行,第0列。 5: 在输入字符较多的情况下,界面显得较为凌乱,所以在程序中添加了一个清屏子程序,每次在返回选择界面的情况下清屏,但是在调试过程中,每当调用CLEAR的时候就出现错误: “C:WINDDOWSsystem32cmd.exe NTVDM CPU 遇到无效的指令 CS:01e7 IP:018b OP:db fe 06 cd 02”,查阅资料,发现是软件兼容问题。最后查阅书本,发现如果要实现清屏功能的话应该先把光标的位置定位到界面的开始位置(行、列号都为0),

26、然后参照书本P330的例9.11来实现清屏功能。6: 刚开始时候,直接把延迟时间(15.08us)通过CX寄存器传递给子程序WAITF,这样会导致每次传递的时候都应该计算。所以之后在WAITF中直接将CX初始化为663(10ms/15.08us = 663),每次调用WAITF就能产生10ms的延迟,但要特别注意的是,如果WAITF中用到CX,首先应该将CX压栈(PUSH CX),返回之前出栈(POP CX)。7: 结果显示界面显得比较单调,为了增加程序美观性,定义了一个利用BIOS功能调用来设置显示方式和背景色。但要特别注意的是调用的时机,应该在每次刷新并且显示选择列表之前调用。 4.2实验

27、结果这是进入程序页面后的屏幕显示,通过y和n来播放音乐或者结束图表 4 播放音乐界面 程序正在播放歌曲。上面是两只老虎的简谱,可以结合这个来听音高低。结果如上所示5、设计心得与改进方案5.1 心得体会在程序中,各个变量及标号应该有统一且明确的命名规范,例如频率表的命名规则为:“歌曲名_F“,节拍表的命名规则为:“歌曲名_T“ 这样能使代码的可读性大大增强,且在编程中也能使逻辑更加清晰,增加编程效率。 不能一开始就开始编写程序,而是应该首先分析问题,设计出程序的框架流程图,明确各个程序段的功能,这样能使效率提高并且能增强持续的逻辑性和可读性,也可以避免出现很多错误 在设计中应该考虑全面,并且兼顾

28、到各方面的问题。不能仅仅完成布置的任务,应该努力使程序更健壮,能够处理错误的输入并且给出提示,而且应该有更强的交互能力。在做课程设计的过程中难免会出现这样那样的问题,因此要保持良好的心态,在遇到问题时应该仔细想问题的起因及解决方法,不能想都不想就直接放弃或者问人,这样就失去了做报告的意义,因为在解决问题的过程中可以发现很多以前忽视的问题。发现问题,解决问题是我们的主要目的。这次的课程设计让我有机会通过实践来加强、巩固学习过的知识,极大的增强了自己编程能力。5.2 改进方案1. 刚开始设计流程图的时候,可以直接将内置的2首音乐分别定义一个子程序来演奏,在之后的编程过程中,发现这样的设计不合理且会

29、使代码变的更长且冗余,然后改进设计,以一个SOUNDF子程序来演奏音乐,调用SOUNDF的时候直接将需要演奏的频率表和节拍表作为参数传递给SOUNDF程序,这样能使代码更简洁,可读性大大增强。 2. 如果需要播放其他音乐时,只要在数据段增加此音乐的频率表和节拍表,然后在选择项中添加一个选项即可。3. 在调用子程序的过程中,应该注意保存寄存器中的内容,避免在子程序中破坏其中的数据。可以考虑使用主界面的方式,多插入几首歌曲,增加程序的选择性,使不至于单一。 可以通过自己设计的利用系统定时器的中断程序来实现控制发声时间长短的功能,使程序的发声时间有一个具体的时间基准。在系统定时器的中断处理程序中,有一条中断指令INT 1CH,时钟中断每发生一次(约每秒中断18

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1