微 机 原 理 课 程 设 计 报 告1Word格式文档下载.docx
《微 机 原 理 课 程 设 计 报 告1Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《微 机 原 理 课 程 设 计 报 告1Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
第一章设计概述
1.1设计思想
用汇编编写一程序,利用程序控制计算机的发生系统,并利用键盘控制音频,从而达到在DOS界面下模拟电子琴发声效果。
其中,DOS界面下每个音阶都有确定的频率,频率用D/A输出相应的不断产生对应的频率。
设计中采用模块化程序设计,区域划分,层次清晰。
1.2设计目标
编写一实现电子琴的程序,并实现若干扩展功能。
基本功能:
用键盘输入对应的七个音阶,通过主机箱的喇叭发出声音。
扩展功能:
1、主菜单功能:
有系统主菜单用户提示界面。
2、播放选择:
进入主菜单可输入编号播放相应编号的歌曲
3、放录音:
任意时刻播放记录的曲目
4、在播放录制曲目或预设曲目时,按键盘上q键可以暂停播放,按ESC键返回主菜单。
1.3设计环境
16位的汇编语言程序设计有几种工作环境,本实验以及所有程序都是通过MASM5.0编译的,MASM5.0一个汇编语言的编译、连接、调试及运行的集成环境。
支持标号的快速定位,编译速度快。
1.4设计主流程图
图1-1主程序流程图
第二章系统设计
2.1模块化分
模拟电子琴主要可分为三个模块音频代码模块、键盘控制模块、主界面显示模块。
三个模块之间通过程序调用的方式实现系统电子琴的模拟。
模块式划分不但增强对程序的可读习性,而且对当程序调试过程中有很大的帮助。
2.2音频代码模块
基于PC计算机的时钟晶振为1.1931816MHz,利用电脑里面的蜂鸣器发出声音。
查询对应音阶的频率,利用对应频率编写相应音符的频率。
各音阶标称频率值:
/*-------------------------------------------------------------*/
音符:
1234567
(重低音)
对应频率(Hz):
131147165175196220247
(低音)
262294330349392440494
(中音)
523587659698784880988
(高音)
1046117513181397156817601975
2.3键盘控制模块
代码段中定义对应键盘按键的音频控制代码:
note_tdw131,147,165,175,196,220,247;
重低音
dw262,294,330,349,392,440,494;
低音
dw523,587,659,698,784,880,988;
中音
dw1046,1175,1318,1397,1568,1760,1975;
高音
dw0;
休止符0
;
'
1'
'
2'
3'
4'
5'
6'
7'
;
从低到高
key_tdb'
q'
w'
e'
r'
t'
y'
u'
;
重低音
db'
a'
s'
d'
f'
g'
h'
j'
z'
x'
c'
v'
b'
n'
m'
0'
;
利用键盘按键“q、w、e、r、t、y、u”实现音调的重低音输入,
利用键盘按键“a、s、d、f、g、h、j”实现音调的低音输入,
利用键盘按键“z、x、c、v、b、n、m”实现音调的中音输入,
利用键盘按键“1、2、3、4、5、6、7”实现音调的重低音输入。
2.4主界面显示模块
制作一个菜单,使用菜单条选择功能,让用户选择演奏的乐曲。
用汇编中9号控制字,将字符串提示显示在屏幕上如图2-1所示。
达到基本要求
①有提示使用ESC键或者ENTER键可以退出当前过程或返回DOS。
②显示低音、高音、中音、提示界面。
③按键按下p时出现播放列表如图2-2所示。
图2-1主菜单图
图2-2歌曲列表图
2.5系统组成框图
系统中用到PC机扬声器相应程序,PC机扬声器电路以及相关接口电路如图2-3所示。
2.6系统工作原理
PC中的定时电路有三个通道,通道3用于发声,通道1用于控制系统内部的时钟。
大家都十分清楚用DOS的"
TIME"
命令可以观察并修改系统内部的一个时钟,这个时钟之所以能连续运转主要依靠定时器的通道1。
通道1的工作方式和通道3一样,但是系统启动时设定其发出一个频率固定为18.2Hz的信号,这个信号直接送到系统中的"
中断控制器"
。
每一个"
Hz"
都产生一个硬件中断,一般称这个硬中断为"
IRQ0"
,对应的中断号是08H。
也就是说,当计算机启动后,我们的机器看上去十分平静,但实际上CPU非常忙碌。
在定时器的控制下每隔55毫秒就要执行一个08H号中断,这个中断的主要工作就是连续地计数。
在内存"
0040H:
006CH"
处有四字节的存储空间专门用于保存计数值,CPU每执行一次08H中断,这四字节的计数值就被加1,不难算出这个计数值每增加1091后时间恰好过了1分钟,每增加65454后时间恰好过了1小时。
系统内部的时钟之所以能准确走时,靠得就是08H中断和这四字节的计数值。
因此我们要想精确的定时,必须依靠时钟计数值才行。
由于PC计算机的时钟晶振为1.1931816MHz,根据频率的公式:
f=1/T
则频率周期为
T=1/f
定时器的计数器为16位计数器,则最大的计数值为65536,那么其定时时间为:
t=65536*T=65536/f=0.0549254(秒)
即:
PC定时器每秒可中断18.2065次。
第三章程序设计及调试
3.1程序功能功能描述
程序开始,显示提示信息,对缓存区初始化。
按键扫描,接着调用发音子程序在把AL送缓存区,发出与按键相对应频率的声音,从而实现计算机钢琴功能。
并不停地对Esc键、Enter键扫描,当Esc键或Enter键按下时,就退出程序。
当按下p时,显示播放音乐目录。
当按下数字选择键时,播放程序中预设的曲目。
当检测到q时,退出到计算机钢琴演奏状态。
3.2程序流程图
图3-1程序流程图
3.3DOS/BIOS功能调用,文件列表清单
1、扫描键盘按键
功能号:
用 途:
扫描键盘按键键值
参 数:
AH=0
调 用:
INT16H
返 回:
AL=按键的ASCII码
2、退出系统,返回DOS
4CH
读取时钟计数值
AH=4CH
INT21H
无
3、取得时钟计数值
INT1AH
CX=计数值高16位
DX=计数值低16位
AL=0表示未过24小时
AL<
>
0表示已过24小时
3.4程序的调试
程序直接运行就可以正常工作,调试步骤如下:
1)在MASM5.0汇编工具编译文件。
2)连接目标文件生成EXE文件。
3)运行所生成的EXE文件即可。
程序正常运行截图如3-2图所示:
图3-2运行界面图
3.5调试中出现的问题、原因及排除方法
在编程调试的过程中,遇到了很多麻烦,总结起来有以下几点:
问题1:
寄存器不够用怎么办?
原因:
使用了太多的寄存器,AX、BX、CX、DX。
解决办法:
使用外部变量定义,定义外部变量的方法为:
变量名数据类型?
比如节拍变量定义:
jiepaidb?
节拍变量定义
问题2:
跳转,转移指令跳出的范围太大,编译出现错误怎么办?
程序结构过于复杂,庞大。
使用过程,也就是子程序设计,直接把一个要频繁要用到的函数
打包成一个子过程,然后用CALL调用子过程就可以了,这样就可以避免使用跳转和转移指令了。
比如开启蜂鸣器子过程:
/*-------------------------------------------------------------------------------------------*/
开启蜂鸣器
spk_onprocnear
pushax;
保存ax的值
inal,61h;
获取61h端口的当前值
oral,03h;
把61h端口低二位置1,即打开蜂鸣器
out61h,al;
输出数据到61h端口
popax;
恢复ax的值
ret
spk_onendp
调用子过程如下:
callspk_on;
关闭蜂鸣器
问题3:
寄存器的值变幻无常,怎么办?
原因:
程序结构过于复杂,使用寄存器比较频繁,以及使用了BIOS中断程序,这样会导致其它与之相关寄存器的值的改变。
解决办法:
堆栈是保护环境的主要工具,一旦用错,后过将很严重,比如我们在调试程序的过程中,遇到过这样的问题:
在一个函数的开始,我先用PUSH把所有寄存器入栈了,在函数的执行中,我又把一个寄存器PUSH到栈中保存,却忘记了在执行POP指令之前把它恢复出来!
这样就造成了所有的寄存器的值都的生了变化,包括数据和代码段寄存器,这样不出问题才怪呢?
!
所以,要记住,PUSH了一个变量之后在新的PUSH来临之前如果又有POP别的变量的语句,一定会出问题!
解决的办法只有一个,把push和pop对上号。
问题4:
要显示的字符串过多,但又不想重复写代码,既要美观,又要易读,怎么办?
过于频繁的调用中断显示字符串,导致程序过于庞大和复杂,可读性差。
解决这种问题的最好方法是直接把显示部分写成子过程,但是子过程在传递参数的时候不方便,所以就用宏定义,宏定义可以很方便的传递参数,不仅使得程序美观好看,而且可读性好,程序代码紧凑。
例如:
先在数据段DataSegment里面定义要显示的字符串:
msg_1db'
<
---WelcomeyoutothisOS.--->
$'
0dh,0ah;
定义字节
msg_2db0dh,0ah,'
InthisOS.youcanpressbelowkeystoenjoy:
$'
再在代码段CodeSegment里面定义要调用的宏:
字符显示
Showmacrostr;
宏定义,输入参数:
字符串str
leadx,str;
装入str的有效地址
movah,09h;
调用中断21,09h显示字符串
int21h
endm;
宏定义结束
要显示字符串就可以直接调用宏了,可以带参数,如下所示:
Showmsg_1
Showmsg_2
问题4:
汇编里面怎样进行查表处理?
还不够牢固的掌握汇编编程
汇编里面进行查表处理的我只掌握了一种简单的设计,直接用下标
例如:
要用查表实现不同频率的选择时,可先在数据段DataSegment里面定义要用到的频率数据:
note_tdw131,147,165,175,196,220,247;
dw262,294,330,349,392,440,494;
dw523,587,659,698,784,880,988;
dw1046,1175,1318,1397,1568,1760,1975;
dw0;
再利用MOV指令实现数据的读取,不但的循环查表,直到找到对应的下标值,由于定义的数据为16为二进制数据,所以要取到下一个数据,每次BX就要加2,或者先令BX加1再左移一位即可。
movcx,note_t[bx];
取得对应数组下标值的频率值
设计心得
在整个课程设计过程中,我们不断地在遇到问题和解决问题之中盘旋。
例如在学习相关编程的时候,虽然说是与C语言原理类似,但是终究还是不同,我们只能在摸索中前进。
在老师和同学们的帮助下我还是如期的完成了课设。
经过这个课程设计,虽然时间比较短,完成任务的效果不是很理想,但是既然自己尝试过,就肯定学到了不少东西,也真正体会到做汇编程序的乐趣,收获还是挺大的。
这次课程设计对我综合运用所学知识的能力的提高有不小的帮助,之前做的实验都是很简单的编程,实现的功能都比较简单,可是这次要实现的功能相对来说比较复杂,要求掌握的知识比较综合。
编写程序的过程中,体会最深的是子程序的调用和程序的条理问题,一个程序就算功能实现了,但是也要使主程序和子程序的条理分明,易读性高,才能算一个比较好的程序。
检查程序过程中,在充分思考的基础上多次实验是检查改正程序的良方。
在设计扩展功能的过程中,大胆想像并且用多种思路来求解实现目标是必备的武器。
要提高自己的编程能力,你必须亲自去体验、去设计、编辑、编译、调试、运行。
这样才能使自己的编程能力有所提高。
在做课程设计的日子里得到了张焕龙老师的悉心指导和同学的帮助,在此向他们致以诚挚的谢意。
感谢提供相关技术帮助的老师和同学,你们的支持和鼓励使我对这次的设计完成有了信心和动力,我在此深表谢意。
参考文献
[1]姚燕男,薛钧义编著.微型计算机原理与接口技术[M].北京:
高等教育出版社.2004
[2]刘永华,王成端编著.微型机原理与接口技术[M].北京:
清华大学出版社.2006
[3]杨立等编著.微型计算机原理与接口技术[M].北京:
中国水利水电出版社.2005
[4]王萍,周根元等编著.微机原理应用实践[M].北京:
机械工业出版社.2001
[5]袁开榜等编著.微型计算机原理与与常用接口技术[M].北京:
中国水利水电出版社.2006
[6]古辉主编.微型计算机接口技术[M].北京:
科学出版社.2006
[7]顾元刚,韩燕汇编语言与微机原理教程[M]·
北京:
电子工业出版社,2000