1学号:0121010340112课程设计课程名称汇编语言程序设计题目乐曲演奏程序学院计算机科学与技术学院专业计算机科学与技术班级1001班姓名XXX指导教师XXX2012年06月27日1课程设计任务书学生姓名:XXX专业班级:计科1001班指导教师:XXX工作单位:计算机科学与技术学院题目:乐曲演奏程序初始条件:理论:完成了《汇编语言程序设计》课程,对微机系统结构和80系列指令系统有了较深入的理解,已掌握了汇编语言程序设计的基本方法和技巧。实践:完成了《汇编语言程序设计》的4个实验,熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法。要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)理解键盘接口的工作原理,掌握BIOS键盘I/O功能,掌握复杂内存数据结构的定义和管理方法。具体的设计任务及要求:1)采用位触发方式编写程序,使计算机发出音响并演奏乐曲;2)要求在屏幕上用键盘选择歌曲;3)程序采用子程序结构,结构清晰;4)友好清晰的用户界面,能识别输入错误并控制错误的修改。在完成设计任务后,按要求撰写课程设计说明书;对课程设计说明书的具体要求请见课程设计指导书。阅读资料:1)《IBM—PC汇编语言程序设计实验教程》实验2.42)《IBM—PC汇编语言程序设计(第2版)》例6.11时间安排:设计安排一周:周1、周2:完成系统分析及设计。周3、周4:完成程序调试,和验收。周5:撰写课程设计报告。指导教师签名:年月日系主任(或责任教师)签名:年月日武汉理工大学《汇编语言程序设计》课程设计1乐曲程序的设计与实现1.实验原理1.1音调与频率和时间的关系利用计算机控制发声的原理,可以编写演奏乐曲的程序。乐曲是按照一定的高低、长短和强弱关系组成的音调。在一首乐曲中,每个音符的音高和音长与频率和节拍有关。组成乐曲的每个音符的频率值和持续时间是乐曲程序发声需要的两个数据。但实际上卷入计数器的输入频率与音符频率相除的值,通用发声程序的前半部分就是完成这个计算,并将计数值送入计数器2的功能。音符的持续时间是根据乐曲的速度及音箱的节拍数来确定的。1.2乐曲的频率和节拍乐曲是按照一定的高低、长短、强弱组成的音调。在一首乐曲中,每个音符的音高和音长和频率和节拍有关。每个音符的频率值和持续时间是乐曲程序发声需要的两个必要数据。高音阶从中C(263)到高C(523),各个音阶对应的频率如下所示:DW263---------CDW294---------DDW330---------EDW349---------FDW392---------GDW440---------ADW494---------BDW523---------C如果知道了乐曲的曲谱,就可以将每个音符的频率和持续时间定义为两个数据表,然后通过调用子程序将表中数据取出,通过扬声器发声。例如MERRYCHRISTMAS频率表和节拍表如下所示:武汉理工大学《汇编语言程序设计》课程设计2CHST_Fdw7dup(330),392,262,294,330,4dup(349),2dup(330),330,294,294,262,294,392dw7dup(330),392,262,294,330,4dup(349),2dup(330),392,392,349,294,262,0CHST_Tdw2dup(25,25,50),4dup(25),100,2dup(25,25,50)dw4dup(25),2dup(50),2dup(25,25,50)dw4dup(25),100,2dup(25,25,50),4dup(25),100其中,CHST_F为频率表,CHST_T为节拍表,两个表中的数据一一对应,每一组代表着乐曲中的一个音符,频率表中以0作为结束的标志。1.3实验要求1.进一步理解和掌握程序直接控制I/O方式,掌握计算机发声程序的设计。具体的设计任务及要求:1)进一步理解程序直接控制I/O方式和位触发方式控制声音的工作原理。2)一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编写乐曲程序的关键。根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;3)编写程序并调试通过。2.了解定时器的工作原理,掌握利用定时器产生声音的方法,使计算机演奏乐曲(例如《两只老虎》等)。编写程序并调试通过。1.4通用发声程序的设计原理PC机发声系统以8254的2号计数器为核心。系统初始化时,2号计数器I作在“方波发生器”方式,初值为二进制数,,写入顺序为先低后高,CLK2为1.193182MHz,当计数初值为533H时,OUT2输出的方波大约为900Hz,经过简单的滤波之后,送至扬声器。改变1.4号计数器的计数初值就可以使扬声器发出不同频率的音响。ROMBIOS中有个BEEP子程序,这能根据BL中组出的时间计数值控制8254定时器,产生持续时间为1个或几个0.5秒,频率为896HZ的声音,我们可以利用并修改BEEP,使其产生任一频率的声音。为此我们需要做两点修改,首先,BEEP程序只能产生896HZ的声音,我们的通用发声程序应能产生任一频率的声音。其次,BEEP产生声音的持续时间(音长)只能是0.5秒的倍数,我们希望声音的持续时间更易于调整,例如可以是10ms的倍数。武汉理工大学《汇编语言程序设计》课程设计3我们知道BEEP能将计数值533H送给定时器2产生896HZ的声音的,那么产生其它频率声音的时间计数值应为:533H×896÷给定频率=123280H÷给定频率发声程序包括3个步骤:(1)在8253中的42端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使定时器2准备接收计数初值。(2)在8253中的42H端口(Timer2)装入一个16位的计数值(533H×895/频率),以建立将要产生的声音频率。(3)把输出端口61H的PB0、PB1两位置1,发出声音。对于发音部分。PC机上的大多数输入/输出(I/O)都是由主板上的8255(或8255A)可编程序外围接口芯片(PPI)管理的。PPI包括3个8位寄存器,两个用于输入功能,一个用于输出功能。输入寄存器分配的I/O端口号为60H和62H,输出寄存器分配的I/O端口号为61H。由PPI输出寄存器中的0、1两位来选择扬声器的驱动方式。连接到扬声器上的是定时器2,从上图可以看到,GATE2与端口61H的PB0相连,当PB0=1时,GATE2获得高电平,使定时器2可以在模式3(方波)下工作。定时器2的OUT2与端口61H的PB1通过一个与门与扬声器的驱动电路相连。当PB1=1时,允许OUT2的输出信号到达扬声器电路。因此,只有PB0和PB1同时为“1”时,才能驱动扬声器地声。通过以下指令实现:INAL,61HORAL,3OUT61H,AL上面的指令用以打开扬声器,如要关闭扬声器时则为:ANDAL,0FCHOUT61H,AL当从8255中采集到输入的数据时,需要确定相应的频率,所以在软件编程时要建立一个数据表:TABLEDW493,440,392,349,329,293,261把相应的频率送到一个寄存器上,通过公式:计数值=533H×896÷f=1234DCH÷f算出计数值,再把算得的计数值送给8253,就可产生所要频率的方波。在把计数值送8253前,必须先把8253进行初始化:武汉理工大学《汇编语言程序设计》课程设计4MOVAL,0B6HOUT43H,AL使其选用通道2,工作在方式3下。就整个电路而言,接好电路后,通过软件编程不断地采集从8255口中输入的信号,而8个开关都接在8255的A口上,只要有开关按下,就会采集到一个数据,根据这个数据与事先编好的表对应,得到一个计数值,把这个计数值送给8253的通道2,8253的通道2工作的方式3下,这样就可以产生满足频率要求的发声方波。这个方波经驱动放大就可以使扬声器发出相应的声音。所以8255在这里完成两个任务,它不仅从A口中采集到数据,而且B口的PB1和PB0两个位要控制发声。8253的主要任务就是产生所要求发声的不同频率的方波。2、方案设计及说明2.1设计实现及功能了解了乐曲演奏的原理,就可以开始设计方案。首先,明确整个程序的结构及各个程序段的结构和功能,然后设计流程图。按照要求,程序需要完成的功能如下所示:1.程序需要通过定时器原理完成播放乐曲的功能,这是最基本的功能。2.在程序中添加一个键盘发声功能,即通过按键盘上不同的按键来发出不同频率的音符。3.程序应该有判断用户输入是否符合规定,如果输入不正确,应该有所提示。4.在用户输入较多的情况下,选择界面会显得较为凌乱,所以添加一个清屏功能显武汉理工大学《汇编语言程序设计》课程设计5得很有必要。5.在主界面选择不同的选项时,应该跳转到不同的子界面,结束之后再返回主选择界面。2.2流程图开始显示提示信息接收键盘输入是“Q”?是“A”?是“C”?是“B”?退出程序将音乐节拍频率地址导入ADDRESS调用MUSIC,播放音乐显示错误提示调用清屏程序是是是是否否否否武汉理工大学《汇编语言程序设计》课程设计6说明:在进入主界面的时候有6个选项,分别是1:MUSIC1--MERRYCHRISTMAS2:MUSIC2–TAIHU3:MUSIC3--LITTLEBEE4:PLAYBYKEYBOARD5:PRESS5TOQUIT6:CLEARTHESCREEN通过选择不同的选项进入其子界面来实现不同的功能。2.3关键代码设计实现及分析2.3.1程序段说明1)DATAS为数据段,其中存放在程序中所要显示的提示选择信息,还有乐曲的频率表和节拍表,和键盘控制发声对应的音符表。2)CODES为代码段,由于在整个程序中各个子程序都定义为NEAR,所以只需要有一个代码段,各个子程序的定义及实现都放在其中。2.3.2PLAY_MUSIC乐曲演奏程序的实现及分析“PLAY_MUSIC”为播放音乐的子程序,完成的功能是通过SI(频率表的偏移地址)BP(节拍表的偏移地址)(通过主程序传递过来的参数)找到对应的频率(DI)、节拍(BX),再以DI、BX为参数调用SOUNDF子程序来发出声音。关键代码:FREQ:MOVDI,[SI]CMPDI,0JEEND_MUSICMOVBX,DS:[BP]武汉理工大学《汇编语言程序设计》课程设计7CALLSOUNDF;以DI(频率)BX(节拍)为参数,调用SOUNDFADDSI,2ADDBP,2JMPFREQSI,BP是频率表和节拍表的偏移地址,通过寄存器间接寻址方式找到数据段中定义数据,传递给BX和DI,然后调用SOUNDF发出一个频率为DI,节拍数为BX的声音注意:在频率表中应该设置一个结束标志,“CMPDI,0”,在这里以0作为结束标志。2.3.3SOUNDF通用发声程序的实现及分析SOUNDF”为以传递过来的频率和节拍数,发出一个音符的频率的子程序。关键代码分析:MOVAL,0B6HOUT43H,AL置43H端口为0B6H,选择计数器2,读/写LSB,MSB,模式3,计数值为二进制数。MOVDX,12HMOVAX,348CHDIVDI按照公式,计数值=12348CH÷f,商存放在AX中。OUT42H,ALMOVAL,AHOUT42H,AL8253\54的数据总线为8位,而计数值为16位,所以应该分两次传递计数值。INAL,61HMOVAH,ALORAL,3OUT61H,AL将61H的后两位置1,打开扬声器,使其发声。武汉理工大学《汇编语言程序设计》课程设计8WAIT1:CALLWAITFDECBXJNZWAIT1用WAITF产生一个10ms的延时,BX是节拍(10ms的倍数)。MOVAL,AHOUT61H,AL恢复寄存器状态2.3.4WAITF延迟程序的实现及分析“WAITF”为通过监控端口61H的PB4固定不变的触发时间来产生延迟时间的子程序。关键代码分析:MOVCX,663WAITF1:INAL,61HANDAL,10H;查看61H寄存器的第四位(PB4)CMPAL,AH