汇编模拟电子琴程序2.docx
《汇编模拟电子琴程序2.docx》由会员分享,可在线阅读,更多相关《汇编模拟电子琴程序2.docx(13页珍藏版)》请在冰豆网上搜索。
汇编模拟电子琴程序2
《汇编语言程序设计》
课程设计报告
题目:
模拟电子琴(音乐播放项目子程序)
指导老师:
学生姓名:
学号:
专业:
班级:
2011年6月20日
(一)程序设计任务:
1.1题目:
模拟电子琴
1.2要求:
设计一个可模拟发声的电子琴程序,并实现功能,附加显示。
(二)课题背景:
2.1汇编语言的优点:
汇编语言由于采用了助记符号来编写程序,比用机器语言的二进制代码编程要方便些,在一定程度上简化了编程过程。
汇编语言的特点是用符号代替了机器指令代码,而且助记符与指令代码一一对应,基本保留了机器语言的灵活性。
使用汇编语言能面向机器并较好地发挥机器的特性,得到质量较高的程序。
用汇编语言等非机器语言书写好的符号程序称为源程序,运行时汇编程序要将源程序翻译成目标程序。
目标程序是机器语言程序,它一经被安置在内存的预定位置上,就能被计算机的CPU处理和执行。
汇编语言像机器指令一样,是硬件操作的控制信息,因而仍然是面向机器的语言,使用起来还是比较繁琐费时,通用性也差。
但是,汇编语言用来编制系统软件和过程控制软件,其目标程序占用内存空间少,运行速度快,有着高级语言不可替代的用途。
设计一个可模拟发声的电子琴程序,作为音乐播放项目的子程序。
2.3程序设计目的:
利用汇编功能实现一个小的电子琴程序,主要功能是根据键盘上的按键发出不同的音符,并记录播放每个音符。
每个音符由它的音调和频率以及时间来决定。
(三)运行环境:
硬件:
8086以上CPU,内存256M以上。
软件:
WINDOWS操作系统,MASM,LINK汇编编译链接件。
(四)程序概要设计:
4.1课程设计基础知识(附图):
8253A内部结构:
4.2程序设计思想:
音乐发声是根据频率和它的延时实现的,不同的音符有不同的频率和时间,根据任务要求先设计一个可视菜单,应用系统显示功能,设置一定的显示方式,在对每个音符1-8定义应有的频率和时间,插入发声子程序,利用DOS功能输入相应数字发出相应的音,整个程序利用栈来实现,这样就做成了一个简单的模拟电子琴程序。
1.系统概述
1.1系统方案综述
从系统实现的功能上来看,简易电子琴的课程设计主要分为手动弹奏乐曲和自动播放音乐两大部分组成。
手动弹奏乐曲是根据PC机硬件键盘设置功能键并通过不同频率使其发出不同的声音就,即音阶,自动播放音乐则是通过中断的方法来实现。
从系统硬件结构上来看,我们主要使用到PC机、8086单片机、8253定时器芯片、8255可编程并行接口芯片、蜂鸣器等等。
将这些硬件电路有机地结合起来使之满足电子琴的实现硬件需要。
从系统软件设计角度来看,将电子琴的课程设计采用程序模块化设计方法,将程序分为主程序、键盘扫描程序模块、中断发音程序模块等等。
此外,采用程序设计思想,将中断定时方式与外部按键查询方式相结合,实现手动弹奏乐曲和自动播放音乐两部分的切换和启动。
从音乐产生原理方面来看,通过控制8253芯片定时器的定时时间产生不同频率的音频脉冲,从而驱动蜂鸣器发出不同音乐的声音。
用软件延时来控制发音时间的长短,控制节拍。
把音乐的音符和相应的节拍变换为定时常数和延时常数,作为数据表格存放在存储器中,由程序查表得到定时常数和延时常数,分别用来控制8253定时器芯片产生的脉冲频率和发出该音频脉冲的持续时间。
因此,我们可以综合上述的方案设计原理,从软件和硬件两大部分进行有计划有步骤的系统分析和设计。
总设计图参见附件。
1.2系统设计思路
(1)手动弹奏乐曲和自动播放音乐用PC机键盘来实现。
手动弹奏乐曲中PC机键盘的8个键分别设置不同的音符,同时用一个键作为中断控制程序的控制键,通过其可实现手动弹奏乐曲与播放音乐之间的切换。
(2)软件的设计主要包括PC机键盘扫描、音乐播放程序和手动弹奏程序。
此次程序设计主要分为两大块:
手动弹奏乐曲程序和自动播放程序。
两者之间用功能转换程序对其进行结合,并实现各功能的控制。
(四)程序设计流程图:
实现功能
健康离开家
牛津布
设置文本方式
程序设计功能图:
(六)程序代码及其说明:
DATASEGMENT
ERRORDB'warning:
pleaseinputtherightnumber',0DH,0AH,'$'
FREQUENCYDW262,294,330,347,392,440,494,523
RECORDERDW300DUP(?
)
MESSAGEDB'********WELCOMETOTHECOMPUTERPIANO!
*******',0DH,0AH
DB'1.pleaseinputthenumber1--8',0DH,0AH
DB'2.whenyouwanttolistentherecoreder,pleaseinputtheSPACE',0DH,0AH
DB'3.whenyouhavelistenedthemusic,youcancontinuetoinputthenumber',0DH,0AH
DB'4.whenyouwanttoquit,youcanpresstheESCkey',0DH,0AH
DB'6.whenyouinputtherightnumber,thenumberwillshowinthescreen',0DH,0AH
DB0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,0AH,'$'
DATAENDS
STACKSEGMENTPARASTACK;定义堆栈段
DW100DUP(?
)
STACKENDS;堆栈结束
CODESEGMENT;给DS赋值
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA;给DS赋值
MOVDS,AX
MOVBYTEPTR[BP],0
MOVAX,0600H;清屏程序
MOVBX,0754H
MOVCX,0000H
MOVDX,19F4H
INT10H
LEADX,MESSAGE;取MESSAGE的有效地址给DX
MOVAH,09H
INT21H
REAGAIN:
LEADI,RECORDER;取RECORD的有效地址给DI
MOVAL,10110110B;把控制字写入AL
OUT43H,AL;通过AL将控制字写入43H端口,工作在方式3,用计数器2
AGAIN:
MOVAH,0;从键盘输入
INT16H;调用16号中断
MOVDL,AL
MOVAH,02H
INT21H
CMPAL,1BH;判断是不是ESC键
JZEXIT;若是ESC,则跳转到EXIT,则返回DOS
MOVBX,OFFSETFREQUENCY;取出频率组FREQUENCY的偏移地址给BX
CMPAL,'';把输入的字符同SPACE的ASCII码值进行比较
JERECYCLE;若等于,则跳转到RECYCLE,说明要执行记忆循环播放
CMPAL,'0';把输入的字符同'0'的进行比较
JBDISPLAY;若小于,则跳转到DISPLAY,即输入错误,重新输入
CMPAL,'8';输入的字符同'8'的ASCII码值进行比较
JADISPLAY;若大于,则跳转到DISPLAY,即输入错误,重新输入
ANDAX,0FH;接受数据,输入字符存入AX,取出低七位
SHLAX,1;左移一位
SUBAX,2;把移位后的值减2
MOVSI,AX;把AX的值送给SI
MOVCX,[BX][SI];把所要取的频率值用相对基址变址的方式取出,送至CX
NEXT:
MOVAX,34DCH;DX:
AX=1234DCH=1193180D
MOVDX,12H
DIVCX
MOV[DI],AX;把所输入的频率值记录到RECORDER中
INCDI;改变DI所指向的RECORDER的地址,加2
INCDI
INCBYTEPTR[BP];用BP做计数器,计算RECORDER中所记下的频率值个数
MOVBX,AX;把AX的值传给BX
MOVAX,BX
OUT42H,AL;把AX的低8位传入42H端口
MOVAL,AH;把高8位传给低8位
OUT42H,AL;把AX的高八位传到42H端口
INAL,61H;读取8255的状态,以控制PB0和PB1
ORAL,03H;将后两位置一,使扬声器发声
OUT61H,AL;写入61H端口
MOVCX,2810H;通过嵌套执行循环程序2810*4000
DELAY:
MOVDX,4000H
DELAY2:
DECDX
JNZDELAY2
LOOPDELAY
INAL,61H;重新读取61H端口的状态
ANDAL,11111100B;把PB0和PB1置0
OUT61H,AL;关闭扬声器
JMPAGAIN
DISPLAY:
LEADX,ERROR;显示调用,若输入的是0或9,则执行DISPLAY
MOVAH,09H;调用INT21,显示ERROR字符串
INT21H
JMPAGAIN;返回让用户重新输入
TEMP:
JMPREAGAIN
EXIT:
MOVAH,4CH;返回DOS
INT21H
RECYCLE:
LEADI,RECORDER;启动记忆程序,取RECORDER的有效地址
RECORDRECYCLE:
MOVAX,[DI];把所记忆的频率依次传送给AX
MOVWORDPTR[DI],0;取完后清除记忆值
INCDI;取完后清除记忆值
INCDI;把DI的值加2
MOVBX,AX;把AX的值传给BX
MOVAX,BX
OUT42H,AL;把AX的低8位传入42H端口
MOVAL,AH;把高8位传给低8位
OUT42H,AL;把AX的高八位传到42H端口
INAL,61H;读取8255的状态,以控制PB0和PB1
ORAL,03H;将后两位置一,使扬声器发声
OUT61H,AL;写入61H端口
MOVCX,4000H;通过嵌套执行循环程序3000*4000
DELAY3:
MOVDX,5000H
DELAY4:
DECDX
JNZDELAY4
LOOPDELAY3
INAL,61H;重新读取61H端口的状态
ANDAL,11111100B;把PB0和PB1置0
OUT61H,AL;关闭扬声器
DECBYTEPTR[BP];每执行一次,BP的值减一
JZTEMP;当BP减到0,则返回REAGAIN重新让用户输入
JMPRECORDRECYCLE;否则继续执行记忆播放
CODEENDS;代码段结束
ENDSTART
(七)实现界面(图)
由图可知:
当弹出一段乐谱的时候(如上以小星星为例),屏幕上出现了历史显示,当按下空格键时,电脑开始回放之前弹奏的所有音符。
当输入不为1-8时,如q,则出现了警告。
(八)总结与体会:
以前从没有学过关于汇编语言的知识,起初学起来感觉很有难度。
当知道要做课程设计的时候心里面感觉有些害怕和担心,担心自己不会或者做不好。
但是当真的要做的时候也只好进自己作大的努力去做,做到自己最好的。
我们在这个过程中有很多自己的感受,我想很多同学都会和我有一样的感受,那就是感觉汇编语言真的是很神奇,很有意思。
我们从开始的担心和害怕渐渐变成了享受,享受着汇编带给我们的快乐。
看着自己做出来的东西,心里面的感觉真的很好。
虽然我们做的东西都还很简单,但是毕竟是我们自己亲手做出来的。
很有成就感。
在这次课程设计中,我真正体会到了合作的重要性,遇到很多问题时,当我看书查资料不能解决时,这是去找同学讨论一下,收获很大,可以使很多问题迎刃而解,直到问题最终解决。
我想汇编语言设计和其他课程设计有共同的地方,那就是不仅加深和巩固了我们的课本知识,而且增强了我们自己动脑,自己动手的能力。
但是我想他也有它的独特指出,那就是让我们进入一个神奇的世界,那就是编程。
对于很多学过编程或者其他的类似程序的同学来说,这不算新奇,但是对于我来说真的新奇,很有趣,也使我有更多的兴趣学习微机原理和其他的汇编。
(九)参考文献:
《汇编语言程序设计》齐志儒高福祥编
《微机原理实验与课程设计指导书》陆红伟编