微机原理课程设计电子琴设计.docx
《微机原理课程设计电子琴设计.docx》由会员分享,可在线阅读,更多相关《微机原理课程设计电子琴设计.docx(44页珍藏版)》请在冰豆网上搜索。
微机原理课程设计电子琴设计
广州大学松田学院
课程设计说明书
题目
姓名
专业
班级
系(部)
指导老师
二零一四年十二月三十日
摘要
本文通过8255和8253来实现电子琴模拟,主要可以分成两部分,分别为输入部分和发音部分。
输入部分主要是由8255和8个常开型开关来完成。
发音部分由CUP通过对定时器8253的通道2进行编程,使其I/O寄存器接收一个控制声音频率的16位计数值,端口61H的最低位控制通道2门控的开断,以产生特殊的音响。
本文用到的是8253的方式3——方波发生器。
在程序设计中,为了避免过于频繁的调用中断显示字符串,应用了宏定义;还通过子程序调用,有效的解决了跳转和转移过多的问题;再加上合理的DOS和BIOS功能调用,以及各种指令的综合,最终作出了漂亮的电子琴界面,并实现了电子琴演奏高、中、低音,以及播放预存乐曲的功能。
关键词:
电子琴8253定时器8255DOS调用宏定义
1设计任务及要求
初始条件:
用汇编语言设计一个电子琴,在屏幕上显示出来,界面要美观,功能上模拟现实电子琴功能。
要求完成的主要任务:
1.实现弹奏功或演奏。
其中弹奏:
用户每按一琴键弹奏相应音符;演奏:
按下某键后自动弹奏预存琴谱功能;还可以附加变调
2.界面要美观。
2工作原理
PC机扬声器电路以及相关接口电路如图2-1。
图2-1PC机扬声器电路及相关接口电路
通过8255和8253来实现电子琴模拟,主要可以分成两部分,分别为输入部分和发音部分。
输入部分:
主要是由8255和8个常开型开关来完成。
发音部分:
CUP通过对定时器的通道2进行编程,使其I/O寄存器接收一个控制声音频率的16位计数值,端口61H的最低位控制通道2门控的开断,以产生特殊的音响。
当通道2用于发声时,采用的是方式3,在方式3下,输出线为“1”和为“0”的时间各占计数时间的一半,因而产生一系列间隔均匀的脉冲。
从定时器输出的方波信号,经功率放大和滤波后驱动扬声器。
送到扬声器的信号还受到了从并行接口芯片8255(端口地址为61H)来的双重控制,端口61H的最低位控制通道2的门控开断,以产生特殊的音频信号,端口61H的PB1位和定时器的输出信号同时作为与门的输入,PB0和PB1位可由程序决定为0还是为1。
显然只有PB0和PB1都是1时,才能使扬声器发出声音。
控制音长的时间可以简单地通过反复执行指令来得到。
2.18253简介
8253芯片是常用的可编程计数器,在微机中有着极其重要的作用。
常用于事件计数器,单稳态触发器,分频器,方波发生器,硬件触发的单脉冲发生器等。
计数器/定时器8253包括3个独立的16位计数器通道,而每个计数器都有6种工作方式,可以按二进制或十进制(BCD码)进行计数。
本文用到的是8253的方式3——方波发生器来实现了简易电子琴的设计。
8253的方式控制字如图2-2所示。
图2-28253的方式控制字
8253的工作方式3——方波发生器:
它的特点是:
(1)输出为周期性的方波。
若计数值为N,则输出方波的周期是N个CLK脉冲的宽度。
(2)写入控制字后,输出将变为高电平,当写入计数初值后,就开始计数,输出仍为高电平;当计数到初值的一半时,输出变为低电平,直至计数到0,输出又变为高电平,重新开始计数。
(3)若计数值为偶数,则输出对称方波;如果计数值为奇数,则前(N+1)/2个CLK脉冲期间输出为高电平,后(N-1)/2个CLK脉冲期间输出为低电平。
(4)GATE信号能使计数过程重新开始,GATE=1允许计数,GATE=0禁止计数。
停止后OUT将立即变高电平,当GATE再次变高以后,计数器将自动装入计数初值,重新开始计数。
2.28255简介
按功能可把8255分为三个逻辑电路部分,即:
口电路、总线接口电路和控制逻辑电路。
8255共有三个8位口,其中A口和B口是单纯的数据口,供数据I/O使用。
而C口则既可以作数据口,又可以作控制口使用,用于实现A口和B口的控制功能。
8255A的方式控制字如图2-3所示。
图2-38255A的方式控制字
3设计思路
3.1程序功能描述
程序开始,显示电子琴界面和提示信息,对缓存区初始化。
按键扫描,接着调用发音子程序把al送缓存区,发出与按键相对应频率的声音,从而实现计算机钢琴功能:
键盘按键“q、w、e、r、t、y、u”实现音调的高音输入;
键盘按键“a、s、d、f、g、h、j”实现音调的中音输入;
键盘按键“z、x、c、v、b、n、m”实现音调的低音输入。
不停地对Esc键进行扫描,当Esc键按下时,就退出程序;当按下p时,播放预存音乐;当检测到Enter键时,退出到计算机钢琴演奏状态。
3.2程序流程图
程序流程图如图3-1所示。
图3-1程序流程图
3.3DOS/BIOS功能调用
DOS操作系统为程序设计者提供了可以直接调用的软中断处理程序,每一个中断处理程序完成一个特定的功能操作。
依据编程需要选择适当的处理程序,编程者不需再重新编写程序,而是使用INTn软中断指令。
每执行一种不同类型码n的软中断指令,就执行一个中断处理程序,其主要功能如下:
(1) 磁盘的读/写控制。
(2)内存管理、文件操作和目录管理。
(3)基本输入/输出(对键盘、打印机和显示器等)控制,另外还有日期、时间管理等。
BIOS是固化在只读存储器ROM中的一系列输入/输出服务程序,它存放于内存的高地址区域内,除负责处理系统中的全部内部中断外,还提供对主要I/O接口的控制功能,如键盘、显示器、磁盘、打印、日期与时间等。
BIOS采用模块化结构,每个功能模块的入口地址都存于中断向量表中。
对这些中断调用是通过软中断指令INTn来实现的,中断指令中的操作数n即为中断类型码。
BIOS的调用方法与DOS系统功能调用方法类似:
(1)置功能号于AH中。
(2)置入口参数。
(3)执行INTn。
(4)分析出口参数及状态。
下面介绍程序中将要用到的一下DOS/BIOS功能调用:
3.3.1INT16H(键盘I/O中断)
1.功能号:
00H
功能:
从键盘读入ASCII字符,放在AL中
入口参数:
AH=00H
2.功能号:
01H
功能:
测试有无键被按下
入口参数:
AH=01H
3.3.2INT10H(屏幕及显示器中断)
1.功能号:
00H
功能:
设置显示模式
入口参数:
AH=00H
AL=显示模式
2.功能号:
02H
功能:
用文本坐标下设置光标位置
入口参数:
AH=02H
BH=显示页码
DH=行(Y坐标)
DL=列(X坐标)
3.功能号:
09H
功能:
在当前光标处按指定属性显示字符
入口参数:
AH=09H
AL=字符
BH=显示页码
BL=属性(文本模式)或颜色(图形模式)
CX=重复输出字符的次数
4.功能号:
0BH
功能:
设置调色板、背景色或边框
入口参数:
AH=0BH
设置颜色:
BH=00H,BL=颜色
选择调色板:
BH=01H,BL=调色板(320×200、4种颜色的图形模式)。
5.功能号:
0CH
功能:
写图形象素
入口参数:
AH=0CH
AL=象素值
BH=页码
(CX、DX)=图形坐标列(X)、行(Y)
3.3.3INT21H(DOS系统功能调用)
功能号:
4CH
功能:
退出系统,返回DOS
入口参数:
AH=4CH
4方案比较及论证
在程序设计的过程中,遇到了很多问题,总结起来有以下几点:
问题1:
要显示的字符串过多,但又不想重复写代码
原因:
过于频繁的调用中断显示字符串,导致程序过于庞大和复杂,可读性差。
解决办法:
解决这种问题的最好方法是直接把显示部分写成子过程,但是子过程在递参数的时候不方便,所以就用宏定义,宏定义可以很方便的传递参数,不仅使得程序美观好看,而且可读性好,程序代码紧凑。
问题2:
寄存器不够用
原因:
使用了太多的寄存器,AX、BX、CX、DX。
解决办法:
使用外部变量定义,定义外部变量的方法为:
变量名数据类型?
问题3:
跳转,转移指令跳出的范围太大,编译出现错误
原因:
程序结构过于复杂,庞大。
解决办法:
使用过程,也就是子程序设计,直接把一个要频繁要用到的函数打包成一个子过程,然后用CALL调用子过程就可以了,这样就可以避免使用跳转和转移指令了。
5程序源代码及注释
主程序如下(宏定义及子程序见附录):
datasegment
;------------------------------进度条字符-----------------------
st_loaddb10;起始行
db4;起始列
db0bh;字体颜色
db'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII'
db00
;------------------------------字符定义-----------------------
start_coldb?
;存储起始行
textdb14;起始行
db2;起始列
db0fh;字体颜色
db'piano--AUTOMATION0808^_^',0ffh,0ffh;显示字
db'HAVEAGOODTIME!
',0ffh;以0ffh来判断是否换行
db'[-1-2-3-4-5-6-7-]',0ffh
db'H[qwertyu]p:
play',0ffh
db'M[asdfghj]enter:
stop',0ffh
db'L[zxcvbnm]Esc:
exit',0ffh
db'1/2:
speeddown/up',0ffh
db00
;------------------------------白色琴键坐标-------------------
st_lxdw50,61,72,83,94,105,116;起点横坐标
dw127,138,149,160,171,182,193
dw204,215,226,237,248,259,270
st_ydw50;起点纵坐标
ed_lxdw60,71,82,93,104,115,126;终点横坐标
dw137,148,159,170,181,192,203
dw214,225,236,247,258,269,280
ed_ydw90;终点纵坐标
;------------------------------黑色琴键坐标--------------------------
bt_xdw57,68,90,101,112;起点横坐标
dw134,145,167,178,189
dw211,222,244,254,265
bt_ydw50;起点纵坐标
bd_xdw64,75,97,108,119;终点横坐标
dw141,152,174,185,196
dw218,229,251,262,273
bd_ydw70;终点纵坐标
;------------------------------音乐频率值----------------------------
tunedw220,247,278,294,330,371,416;低音
dw441,495,556,589,661,742,833;中音
dw882,990,1112,1178,1322,1484,1655;高音
soundcolordw0;音色缓存,用于改变播放或弹奏时琴上音响和琴面上点阵的颜色
key_tunedw0;按键状态缓存,用于判断是否有手动按键,1为有,0为无
keynumdw1;按键编号缓存,用于提取对应的按键位置
delay_timedw7000;延时缓存,用于播放时存入bx中来计数
;------------自动演奏的歌曲频率和延时---------《卡农》轻快改编版-----------
mus_freqdw1112,990,882,833,742,661,742,833;声音频率部分
dw882,833,742,661,589,556,589,495
dw882,833,882,441,416,661,556,589,441,882,833,742,833,1113,1322,1484
dw1178,1112,990,1178,1178,1112,882,833,742,661,589,556,495,589,556,495
dw441,495,556,589,661,495,661,589,556,742,661,589,661,589,556,495
dw441,371,742,833,882,833,742,661,589,556,495,742,661,742,661,589
dw556,1112,990,882,990,882,1112,990,1178
dw1322,1112,1178,1322,1112,1178,1322,661,742,833,882,990,1112,1178
dw1112,882,990,1112,556,589,661,742,661,589,661,556,589,661
dw589,742,661,589,556,495,556,495,441,495,556,589,661,742
dw589,742,661,742,833,882,661,742,833,882,990,1112,1178,1322
dw1112,882,990,1112,990,882,990,833,882,990,1112,990,882,833
dw882,742,833,882,441,495,556,589,556,495,556,882,833,882
dw742,882,833,742,661,589,661,589,556,589,661,742,833,882
dw742,882,833,882,833,742,833,882,990,882,833,882,742,883
dw1112,556,589,556,495,990,1112,990,882,556,441,742,661,330,294,330
dw371,742,833,742,833,330,294,330,371,742,661,742,833,833,742,833
dw441,882,990,880,833,416,441,416,371,742,661,742,833,416,556,495
dw441,882,990,1178,1112,556,661,1112,882,1178,1112,1178,990,661,589,661
dw556,882,833,882,556,661,661,742,883,661
dw556,882,1112,1178,882,1112,1112,990,882,833
dw742,742,661,742,833,882,1112,990,882,1178
dw1322,1178,1112,990,1112,990,882,833,882,833,742,661,742,661,589,556
dw589,589,495,441
dw441
dw-1;以后以-1来判断是否结束
;----------------------------声音节拍部分,32为一拍------------------------
mus_timedw16dup(32),64dup(8)
dw16,16,32,32,32,16,16,16,16
dw8dup(8,4,4,8,4,4,8dup(4))
dw64dup(8)
dw6dup(8,4,4,8,8)
dw20dup(8),32
dataends
;************************************代码段*********************************
codesegment
assumeds:
data,cs:
code
;-------------------------主程序-----------------------
;---依次调用:
开场效果--初始化--键盘扫描--按键处理程序-------------
mainprocfar
start:
callshow_load;调用进度条显示程序
;---延时20*waitf----
pushbx
movbx,20
del:
callwaitf
decbx
jnzdel
popbx
;------------重新开始-------
restart:
;自动播放音乐时,按‘enter’键或音乐完全结束后会返回这里
callinit;调用初始化程序
new_scan:
;键盘扫描程序没有检测到功能键被按下时,会返回这里
callscan_key;调用键盘扫描程序,扫描所按下的键
;-----------按键处理-------
calldo_key
;----重新扫描---
jmpnew_scan;重新扫描有无键按下,直到按下esc键
mainendp
6运行结果分析
电子琴界面如图6-1所示。
图6-1电子琴界面
电子琴播放预存音乐时的界面如图6-2所示。
相比初始界面,播放预存音乐时,右上角的第一个灯变绿了,上面和左右两边的点开始闪烁,且每播放一个音符,界面下方就多了"I"一个符号。
图6-2电子琴播放预存音乐的界面
7调试过程记录
在程序调试的过程中,遇到最大的问题就是,寄存器的值变幻无常,容易出错。
原因:
程序结构过于复杂,使用寄存器比较频繁,以及使用了BIOS中断程序,这样会导致其它与之相关寄存器的值的改变。
解决办法:
堆栈是保护环境的主要工具,一旦用错,后果将很严重,比如我们在调试程序的过程中,遇到过这样的问题:
在一个函数的开始,我先用PUSH把所有寄存器入栈了,在函数的执行中,我又把一个寄存器PUSH到栈中保存,却忘记了在执行POP指令之前把它恢复出来!
这样就造成了所有的寄存器的值都的生了变化。
PUSH了一个变量之后在新的PUSH来临之前如果又有POP别的变量的语句,一定会出问题!
解决的办法只有一个,把PUSH和POP对上号。
8课程设计小结
在本次设计中,可以说是一次成功的经验。
在学完了《微型原理与接口技术》这门课的基础上来搞做这个设计,使我对这门课的理论知识的理解有很大程度上的加强。
微机原理这门课程本身是一门实验性和工程性很强的专业技术课,因此不仅要重视理论教学,更应注意实践技能的培养和训练。
课程设计是这门课程的一个重要环节,通过课程设计,巩固、加深和拓宽了学习的理解,使自己的分析、设计和调试8086微机系统的能力得到了进一步的提高。
通过整整一个星期的摸索和编程,查资料,终于把程序完成了,和小组的成员一起讨论问题,分析问题,发现问题,解决问题,也收获了不少,我们的编程技术都有所提高,我们的体会就是:
要提高自己的编程能力,你必须亲自去体验、去设计、编辑、编译、调试、运行。
每一个程序员都是在失败、尝试、失败、尝试与收获中成长起来的。
在设计过程中,对不同方案的构思、分析、比较到最后的定案,这些工作,培养了我们的分析问题,解决问题和创新的能力。
在方案确定后,在软件编程方面,对编写的程序经上机实践和调试,对存在的问题进行反复修改,使其达到了最优方案。
这样的编程机会在平时是很少有的,所以,在编程方面我们得到了很多的锻炼,使自己更加熟悉了汇编语言,了解了编程思想,为以后的学习以及工作打下了扎实的基础。
我认为,在这次的课程设计中,不但做出了一个符合要求的电子琴,而且为自己积累了一笔有用的财富。
参考文献
[1]龚尚福.微机原理与接口技术.西安电子科技大学出版社,2003.8
[2]李芷.微机原理与接口技术.电子工业出版社,2002
[3]钱晓捷.汇编语言程序设计(第二版).电子工业出版社,2003
[4]宋杰等.微机原理与接口技术课程设计.北京 :
机械工业出版社 ,2005
[5]杨立,邓振杰,荆淑霞等.微型计算机原理与接口技术(第二版).北京:
中国铁道出版社,2006
[6]小捷.汇编语言程序设计.第2版.西安:
西安电子科技大学出版社,2003
附录
;**********************************矩形绘制宏*******************************
drawmacrostart_x,start_y,end_x,end_y,color
localdraw_next
;local:
避免宏重复调用时,标号的重复
;功能:
画填充的矩形
;使用条件:
start_xpushax;堆栈
pushbx
pushcx
pushdx
movah,0ch;12号功能,写像素
moval,color;取颜色值
movbh,0;页号0
movcx,start_x;列起始点
movdx,start_y;行起始点
draw_next:
int10h;画点
inccx;画横线
cmpcx,end_x;比较行是否画完
jnedraw_next;画另一行
movcx,start_x;另一行的起始点
incdx;下一行
cmpdx,end_y;比较列是否画完
jnedraw_next;未完继续画
popdx;出栈
popcx
popbx
popax
endm
;********************************矩形点阵绘制宏****************************
draw_pointmacrostart_x,start_y,end_x,end_y,color
localdraw_next
;local:
避免宏重复调用时,标号的重复
;功能:
画矩形点阵
;使用条件:
start_xpushax
pushbx
pushcx
pushdx
movah,0ch;12号功能,写像素
moval,color;设置颜色
movbh,0;页号0
movcx,start_x;列起始点
movdx,start_y;行起始点
draw_next: