汇编8阶电子琴剖析.docx
《汇编8阶电子琴剖析.docx》由会员分享,可在线阅读,更多相关《汇编8阶电子琴剖析.docx(23页珍藏版)》请在冰点文库上搜索。
汇编8阶电子琴剖析
2010年6月25日
微机原理与汇编语言课程设计任务书
一、题目:
电子琴
二、设计的目的
1.掌握利用PC机扬声器发出不同频率声音的方法;
2.学习利用系统功能调用从键盘上读取字符的方法;
3.掌握定时器/计数器8253的工作原理;
三、设计要求
编写程序,程序运行时使PC机成为一架可演奏的“钢琴”。
当按下数字键1-8时,依次发出1,2,3,4,5,6,7,I八个音调,Ctrl-c则退出演奏状态。
独立完成课程设计。
四、设计内容及步骤
1.PC机扬声器电路
电路图如图1所示:
图1PC机扬声器控制电路
通过给8253定时器装入不同的计数值,可以使其输出不同频率的波形。
当与门打开后,经过放大器的放大作用,便可驱动扬声器发出不同频率的音调。
为使该音调的声音持续一段时间,要插入一段延时程序,之后再将扬声器关闭(关闭与门)。
2.建立音频表
要使计算机成为可弹奏的简易电子琴,需要使用系统调用的01H功能以接收键入字符,并且要建立一张音频表。
五、课程设计工作计划
2010年6月21日指导教师布置任务,学生准备文献资料;
2010年6月21日~2010年6月24日学生按照课程设计的内容与要求进行操作
并写出课程设计报告。
2010年6月25日指导教师验收。
指导教师签字:
教研室主任签章:
微机原理与汇编语言课程设计指导教师评语与成绩
指导教师评语:
课程设计表现成绩:
课程设计验收成绩:
课程设计报告成绩:
课程设计总成绩:
指导教师签字:
2010年月日
目录
一、概述5
二、总体方案设计5
三、详细设计7
四、调试与运行结果说明10
五、课程设计总结11
六、谢启12
七、参考文献12
八、附录13
一、概述
1.功能说明:
1利用计算机的扬声器发音来实现;
②定义8个键,对应低音区和中音的i,能随意演奏乐曲;
③能选择多首乐曲中的一首演奏,乐曲自选;
④良好的交互界面用于乐曲的选择和音符的演奏;
2.设计思路:
依据设计功能的要求建立几个可以选择操作的界面。
根据字符的匹配在菜单上面选择要播放的音乐。
首先建立一个音乐的频率跟节拍的代码,利用宏定义将地址传到音乐播放的模块中,之间用8253工作方式3、计数器0、先读低八位后读高八位以及延时的程序。
选择的是自行播放音乐的时候按照1—8进行音乐频率的匹配,指针指向音乐频率的地址,进行一个字符一个字符的匹配。
最后加一个清屏代码使界面更加清晰。
二、总体方案设计
1.设计原理:
(1)要使扬声器发出不同的音调,就得输入不同频率的波形。
通过给8253定时/计数器装入不同的计数值,可以使其输出不同频率的方波。
经过放大器的放大作用,便可驱动扬声器发出不同的音调,只要插入一段延时程序之后,再将扬声器切断,音调的声音就可以持续一端时间。
通过计算机的不同按键输出不同的音调,需要使用系统调用功能以接收键入字符,并且要建立一张表,使键入字符与频率构成一个对应关系:
键入字符
1
2
3
4
5
6
7
8
音符
1
2
3
4
5
6
7
8
频率
1138
1207
1352
1521
1709
1807
2029
2277
乐曲是由不同的频率和节拍的音调组成的,因此控制驱动脉冲的频率和持续时间就是编写乐曲程序的关键。
频率对应8253的计数初值,而乐曲中的节拍决定了各音频持续的时间。
(2)利用8253计数/定时器和8255并行接口,定时器8253利用工作方式3产生一定频率信号,通过可编程的并行外围接口芯片8255控制频率信号的通断。
8255的A口设置为输出,8255的A口的低两位用来控制扬声器驱动,当输出端口的PA0位为“1”或为“0”时,将使控制驱动器的与门电路接通或关闭,使8253所发出的音频信号能到达驱动器或被阻断。
这样通过控制PA0的变化,可使扬声器接通和断开,控制扬声器是否能发出声音。
此外,通过控制PA0的通断时间,就能发出不同的音长。
8255的PA1位为“1”时,控制8253定时器产生驱动扬声器发声的音频信号,该位为“0”则不发信号。
8253有三个定时器,分为0号、1号和2号定时器,驱动扬声器的是0号定时器,该定时器工作在方式3,是一个频率发生器,它负责向扬声器发送指定频率的脉冲信号。
当8255的PA0和PA1都为1时,8253发出指定频率的声音信号的前提下,声音信号通过与门到达驱动器驱动扬声器发声。
硬件原理图如图1所示:
(3)系统实现2个功能,电子琴和音乐盒的功能。
两者发声的方法一样,只是一个数据是从键盘读取的,另一个是已经保存好的数据。
首先我们可以用一个子程序实现单个音调的产生,对8253输入不同的计数初值生成不同频率的波形,然后延时一段时间。
电子琴程序主要是读取键盘按键,根据键值产生不同的音调即可。
而乐曲的播放先将乐曲的音符编码表和节拍编码表建立好的,然后在播放时读取数据。
音乐盒的乐曲播放程序中需要有两组数据支持:
一组是频率数据,一组是节拍时间数据。
音符的频率可以通过简谱从频率表中查得。
节拍时间就是音符的持续时间,取决于乐曲的速度和每个音符的节拍数据。
如4/4(四四拍)中,每小节包括4拍,全音符持续4拍,二分音符持续2拍,四分音符持续一拍,八分音符持续半拍等。
有了音调与频率和时间的关系后,就可以按照乐曲的曲谱将每个音符的频率和持续的时间定义成两组数据表,然后编程依次取出表中的频率值和节拍值,调用单音调子程序就可依次产生各个音调,播放出乐曲。
在程序中存储几个乐曲数据,根据音乐盒子菜单选择相应的乐曲演奏,读取对应的数据输出。
2.程序模块及流程图:
(1).程序模块:
①.两个宏定义。
一个是带显示的宏定义,还有一个是音乐地址跟节拍的地址宏定义。
②.输入要操作的字符匹配模块
③.自行演奏的字符匹配模块
④.自行演奏模块
⑤.音乐播放模块
⑥.延时模块
⑦.8255、8253工作模块
⑧.清屏模块
(2).流程图:
是
YN
三、详细设计
1.软件设计:
1.单音调子程序SOUND:
单音调子程序的调用前需要进行以下几个方面工作:
1)确定相应的音调所对应的频率,查表可以得到,再由频率得到对应的8253计数初值。
2)确定音长,即一个音符所持续的时间。
在单音调子程序中实现发出一个音符的声音,持续所需的时间,流程图如图3所示:
2.电子琴程序
由于是用键盘的数字键1-8,要先读取键盘的输入,判断输入是否在1-8之间,不在就退到主菜单,若是就根据键值查表找出相应的频率,计算初值,调用发音子程序即可,此时的音长固定。
初值的计算方法是用输入的clk频率除以音符的频率。
2.编码实现:
⑴主程序中的清屏使用:
MOVAH,0
MOVAL,00
INT10H
⑵宏定义中的字符串显示功能:
MOVAH,9
INT21H
⑶INPUT程序块中带显示单字符的输入:
MOVAH,01H
INT21H
⑷RETU1程序块完全推出程序:
MOVAH,4CH
INT21H
⑸D1程序块从键盘接收字符不回显:
MOVAH,0
INT16H
四、调试与运行结果说明
1.调试过程出现问题及解决:
最初对扬声器发声方面的知识很是迷茫,上网查了关于音符、节拍以及音符频率表方面的东西,再结合微机原理才弄懂了怎样控制扬声器发音的音调等问题
汇编程序设计的基础知识也是临时学的,随用随查。
调试的时候出现了很多的问题。
宏定义出错,给音乐频率跟节拍定义的时候地址传递出现错误,查书了解到宏定义格式为:
宏指令名MACRO形参1,形参2……
}宏体
ENDM
修改后才可以运行,很多DOS系统功能调用参数格式不是很确定,查了很多资料才得及解决。
2.运行结果以及运行说明:
运行后进入的主界面就是如上图所示。
按照上面的提示进行各种操作,如果其中要输入错误,就会不断的跳出该界面提示重新选择。
A、B、C三个分别是对应播放的音乐。
D操作就是进入下面所示的界面自行弹奏音乐。
Q操作就是直接退出该程序。
进入该界面以后按U后按键1-8就可以进行自己演奏音乐,按Q就会进入第一个界面,进行重新选择
五、课程设计总结
刚听到题目的时候,要求用汇编语言以及微机原理接口技术的知识编写一个电子琴程序,头就懵了!
之前学过汇编,但是丝毫没认真听课,后来也没自学,感觉硬件编程太慢了,何况拿来编程啊,尽管这学期刚学了微机原理接口技术,还算听了几节课,可拿来实践还真是没想过,总之,难啊!
最让人费解的是怎样控制电脑发音,发出1-7的音调了!
去图书馆查了几本关于微机中电子琴的制作程序设计。
懂得了代码的实现方法。
其中宏定义使用就是结合课本跟资料学习应用。
刚刚开始用有点陌生,但是经过这次设计我更进一步懂得了使用方法。
关于计数器的初值是根据课本中的介绍,计算出来的。
音乐节拍的设置参考网络的音乐得以争取播放同时又研究了8255、8253的工作方式,问了同学问题以后以前不清楚的内容得以清晰。
清屏的代码完全为了使界面的整洁网络搜索的代码。
汇编语言的运用全是随用随查,再听了同学讲解了一点,勉强会些基本东西!
上网查了很多资料!
由于时间紧凑此次的课程设计还没有完全达到老师要求的模块化,其中还有一点冗余的代码未能消除。
代码未能实现音乐半路停止以及可以自动保存自行演奏歌曲。
系统实现的功能还是比较僵硬,不是那么智能。
设计中出现了很多错误,有的是自己经过查课本跟网络资料以后琢磨出来的!
有的就是跟同学探讨,多次的修改成功的。
经过这次的实验成功完成了一些基本的操作。
六、谢启
首先感谢老师给我们的这次机会吧,不是说机会难得,尽管有些“强制”,然而自己可是不会主动去编写的,编完了呢,通过这次实验总是学到了一些东西,比如汇编基本知识,伪指令、转移指令的语句,以及关于8255/8253芯片的一些东西。
多少还是磨练了一些心智,看到题目不知从何下手到最后编出一个完成基本操作的电子琴,期间时而沮丧、时而费解,最终还算是完成了吧!
最后感谢寝室好友的费心讲解,以及同学们的积极探讨、网上朋友的资源共享!
参考了很多资料才得以勉强完成任务!
七、参考文献
1)《汇编语言程序设计》葛建梅孙海邵珠富等编著中国水利水电出版社2005年8月第1版
2)《单片微型计算机原理、接口及应用》(第二版)徐惠民安德宁编著北京邮电大学出版社2000年10月第2版
3)《8051单片机实践与应用》吴金戌沈庆阳郭庭吉等著清华大学出版社2002年9月第1版
4)《微机原理与接口技术》(第二版)龚尚福主编西安电子科技大学出版社2008年8月第1版
八、附录
源程序如下:
DATASEGMENT
INFO1DB0DH,0AH,'WELCOMEYOUTOCOMEHERE!
$'
INFO2DB0DH,0AH,'thisisamusicprogram!
$'
INFO3DB0DH,0AH,'pleaseselect!
$'
INFO5DB0DH,0AH,'PLEASEINPUTAGAIN!
$'
MUSLISTDB0DH,0AH,'*********************'
DB0DH,0AH,'AMUSIC1'
DB0DH,0AH,'BMUSIC2'
DB0DH,0AH,'CMUSIC3'
DB0DH,0AH,'DPLAYBYYOURSELF'
DB0DH,0AH,'QEXIT'
DB0DH,0AH,'*********************'
DB0dh,0ah,'$'
MUSLIST1DB0DH,0AH,'*********************'
DB0DH,0AH,'UPRESS1-8toplay'
DB0DH,0AH,'QEXIT'
DB0DH,0AH,'*********************'
DB0dh,0ah,'$'a
tableDW8E5H,7EDH,70FH,6ADH,5F1H,548H,4B7H,8E5H/2;中音
;音乐一*********************************************************
MUS_FREG1DW330,294,262,294,3DUP(330)
DW3DUP(294),330,392,392
DW330,294,262,294,4DUP(330)
DW294,294,330,294,262,-1
MUS_TIME1DW6DUP(12),5
DW2DUP(12,12,5)
DW12DUP(12),10
;*********************************************************音乐二
MUS_FREG2DW330,392,330,294,330,392,330,294,330
DW330,392,330,294,262,294,330,392,294
DW262,262,220,196,196,220,262,294,332,262,-1
MUS_TIME2DW3DUP(5),12,12,5,12,12,10
DW2DUP(5,5,12,12),10
DW3DUP(5,12,12),10
;********************************************************音乐三
MUS_FREG3DW262,262,294,262,349
DW330,262,262,294,262
DW392,349,262,262,523
DW440,349,262,262,466
DW466,440,262,392,349,-1
MUS_TIME3DW5,5,10,10,10
DW10,10,5,5,10,10
DW10,10,10,5,5,10
DW10,10,10,10,10,5
DW5,10,10,10,10,10
DATAENDS
STACKSEGMENT
DB200DUP(0)
STACKENDS
CODESEGMENT
ASSUMEDS:
DATA,SS:
STACK,CS:
CODE
START:
MOVAX,DATA
MOVDS,AX
MOVaH,0;清屏
MOVAL,00
INT10H
;*****定义一个宏*****
SHOWMACROb
LEADX,b
MOVAH,9;带显示的字符串输出
INT21H
ENDM
;**********************音乐地址宏
ADDRESSMACROA,B
LEASI,A;音乐的地址跟频率地址
LEABP,DS:
B
ENDM
;***********************
showINFO1
showINFO2
showINFO3
showMUSLIST
INPUT:
MOVAH,01H;带显示的单字符输入
INT21H
CMPAL,'Q'
JZRETU1;退出
CMPAL,'A'
JNZB0;不是"A"跳到B0
ADDRESSMUS_FREG1,MUS_TIME1
CALLMUSIC
JMPEXIT1
B0:
CMPAL,'B';不是"B"跳到C0
JNZC0
ADDRESSMUS_FREG2,MUS_TIME2
CALLMUSIC
JMPEXIT1;无条件转移
C0:
CMPAL,'C'
JNZD0;不是"C"跳到D0
ADDRESSMUS_FREG3,MUS_TIME3
CALLMUSIC
JNZEXIT1
D0:
CMPAL,'D'
JZD00
JMPEXIT
RETU1:
MOVAH,4CH;终止当前程序并返回调用程序
INT21H
D00:
callclear
showMUSLIST1
;CMPAL,'U'
;JZD1
CMPAL,'Q'
JZEXIT
D1:
MOVAH,01H;带显示的单字符输入
INT21H
CMPAL,'Q'
JEEXIT;若为Q键,则返回菜单
CMPAL,'1';
JBD1
CMPAL,'8'
JASING;若不在'1'-'8'之间转sing
SING:
MOVAH,0;高位清0
SUBAL,31H;输入为一对应的是数组中的第0个
ADDAL,AL;一个字
MOVSI,AX
MOVAX,TABLE[SI]
MOVBX,2000;延时程序用的循环变量
CALLSPEAKER
JMPD1
SPEAKERPROC
PUSHAX
PUSHAX
MOVAL,0B6H;10110110/8253工作方式3,计数器0,先读低八位后读高八位,2进制
OUT43H,AL
POPAX
OUT42H,AL
MOVAL,AH
OUT42H,AL;写入计数器0
MOVAL,81H;开8255;开扬声器
OUT63H,AL
INAL,61H
ORAL,03H;D1D0=PB1PB0=11B,其他位不变
OUT61H,AL
WAIT0:
MOVCX,8FF0H
DELAY:
LOOPDELAY
DECBX
JNZWAIT0;调用延时子程序
ANDAL,0FCH;D1D0=PB1PB0=00B,其他位不变,关闭扬声器
OUT61H,AL
POPAX
RET
SPEAKERENDP
EXIT1:
showINFO5
JMPINPUT
EXIT:
callclear
showINFO5
showINFO1
showINFO2
showINFO3
showMUSLIST
JMPinput
;******************************************发声
GENSOUNDPROCNEAR
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHDI
MOVAL,0B6H;8253工作方式3,计数器0,先读低八位后读高八位,2进制
OUT43H,AL
;***********对音乐频率改变
MOVDX,12H
MOVAX,348ch;计数初值=1000000/频率,保存到AX
DIVDI
OUT42H,AL
MOVAL,AH
OUT42H,AL
INAL,61H;读8255的B口
MOVAH,AL
ORAL,3
OUT61H,AL
WAIT1:
MOVCX,3314
callWAITF
DELAY1:
DECBX
JNZWAIT1
MOVAL,AH
OUT61H,AL
POPDI
POPDX
POPCX
POPBX
POPAX
RET
GENSOUNDENDP
;********************************************
waitfprocnear
pushax
waitf1:
inal,61h
andal,10h
cmpal,ah
jewaitf1
movah,al
loopwaitf1
popax
ret
waitfendp
;*********************************************
MUSICPROCNEAR
PUSHDS
SUBAX,AX
PUSHAX
FREG:
MOVDI,[SI]
CMPDI,-1;判断是否是一首歌播放完毕
JEEND_MUS
MOVBX,DS:
[BP]
CALLGENSOUND
ADDSI,2
ADDBP,2
JMPFREG
END_MUS:
RET;当CX不为0时重复执行串指令
POPDS
MUSICENDP
;************************************************clear!
!
!
clearprocnear
pushax
pushbx
pushcx
pushdx
movah,6
moval,0
movch,0
movcl,0
movdh,24
movdl,79
movbh,7
int10h
popdx
popcx
popbx
popax
ret
clearendp
CODEENDS
ENDSTART