乐曲程序的设计与实现汇编
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学号:13
课程设计
课程名称汇编语言程序设计
题目乐曲程序的设计与实现
学院计算机科学与技术学院
专业计算机科学与技术
班级0909班
姓名王世创
指导教师伍新华
2011 年12 月30 日
目录
课程设计任务书 (1)
1、实验内容及要求 (1)
2、实验原理 (1)
2.1 通用发声程序原理 (1)
2.2 乐曲的频率和节拍 (3)
3、方案设计及说明 (4)
3.1 设计实现及功能 (4)
3.2 流程图 (4)
4、详细设计 (6)
4.1 程序段说明 (6)
4.2 主要的宏和过程实现 (6)
4.2.1 DISPLAY显示宏 (6)
4.2.2 ADDRESS显示宏 (6)
4.2.3 MUSIC显示宏 (7)
4.2.4 GENSOUND通用发声程序 (8)
4.2.5 WAITF延时程序 (9)
4.2.5 EXIT退出 (10)
5、调试过程及实验结果分析 (10)
5.1 调试过程 (10)
5.5实验结果 (11)
6、设计心得与改进方案 (12)
6.1注意事项 (12)
6.2 改进方案 (13)
6.3 心得体会 (13)
7、参考文献 (13)
8、程序清单 (14)
课程设计任务书
学生姓名:王世创专业班级:计算机科学与技术学院0909
指导教师:伍新华工作单位:计算机科学与技术学院
题目: 乐曲程序的设计与实现
初始条件:
理论:完成了《汇编语言程序设计》课程,对微机系统结构和80系列指令系统有了较深入的理解,已掌握了汇编语言程序设计的基本方法和技巧。
实践:完成了《汇编语言程序设计》的4个实验,熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
进一步理解和掌握程序直接控制I/O方式,掌握计算机发声程序的设计。
具体的设计任务及要求:
1.采用位触发方式编写程序,使计算机发出音响并演奏乐曲(例如《两只老虎》等)。
1)进一步理解程序直接控制I/O方式和位触发方式控制声音的工作原理。
2)一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编写乐曲程序的关键。
根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;
3)编写程序并调试通过。
2.了解定时器的工作原理,掌握利用定时器产生声音的方法,使计算机演奏乐曲(例如《两只老虎》等)。
编写程序并调试通过。
在完成设计任务后,按要求撰写课程设计说明书;对课程设计说明书的具体要求请见课程设计指导书。
阅读资料:
1)《IBM—PC汇编语言程序设计实验教程》3.1节
2)《IBM—PC汇编语言程序设计(第2版)》10.4节,10.5节
时间安排:
设计安排一周:周1、周2:完成系统分析及设计。
周3、周4:完成程序调试,和验收。
周5:撰写课程设计报告。
指导教师签名:年月日
系主任(或责任教师)签名:年月日
乐曲程序的设计与实现
1.实验内容及要求
1.进一步理解和掌握程序直接控制I/O方式,掌握计算机发声程序的设计。
具体的设计任务及要求:
1) 进一步理解程序直接控制I/O方式和位触发方式控制声音的工作原理。
2) 一首乐曲是由不同频率和节拍的音调组成,因此控制脉冲的频率和持续时间是编
写乐曲程序的关键。
根据已知的音符频率对照表,设置乐曲的频率表和节拍时间表;
3) 编写程序并调试通过。
2.了解定时器的工作原理,掌握利用定时器产生声音的方法,使计算机演奏乐曲(例如《两只老虎》等)。
编写程序并调试通过
2.实验原理
2.1 通用发声程序原理
PC机发声系统以8254的2号计数器为核心。
系统初始化时,2号计数器I作在“方波发生器”方式,初值为二进制数,,写入顺序为先低后高,CLK2为1.193182MHz,当计数初值为533H时,OUT2输出的方波大约为900Hz,经过简单的滤波之后,送至扬声器。
改变1.4号计数器的计数初值就可以使扬声器发出不同频率的音响。
ROM BIOS 中有个BEEP子程序,这能根据BL中组出的时间计数值控制8254定时器,产生持续时间为1个或几个0.5秒,频率为896HZ的声音,我们可以利用并修改BEEP,使其产生任一频率的声音。
为此我们需要做两点修改,首先,BEEP程序只能产生896HZ的声音,我们的通用发声程序应能产生任一频率的声音。
其次,BEEP产生声音的持续时间(音长)只能是0.5秒的倍数,我们希望声音的持续时间更易于调整,例如可以是10ms的倍数。
我们知道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”时,才能驱动扬声器地声。
通过以下指令实现:
IN AL,61H
OR AL,3
OUT 61H,AL
上面的指令用以打开扬声器,如要关闭扬声器时则为:
AND AL,0FCH
OUT 61H,AL
当从8255中采集到输入的数据时,需要确定相应的频率,所以在软件编程时要建立一个数据表:
TABLE DW 493,440,392,349,329,293,261
把相应的频率送到一个寄存器上,通过公式:
计数值=533H×896÷ f=12348CH÷ f
算出计数值,再把算得的计数值送给8253,就可产生所要频率的方波。
在把计数值送8253前,必须先把8253进行初始化:
MOV AL,0B6H
OUT 43H,AL
使其选用通道2,工作在方式3下。
就整个电路而言,接好电路后,通过软件编程不断地采集从8255口中输入的信号,而8个开关都接在8255的A口上,只要有开关按下,就会采集到一个数据,根据这个数据与事先编好的表对应,得到一个计数值,把这个计数值送给8253的通道2,8253的通道2工作的方式3下,这样就可以产生满足频率要求的发声方波。
这个方波经驱动放大就可以使扬声器发出相应的声音。
所以8255在这里完成两个任务,它不仅从A口中采集到数据,而且B口的PB1和PB0两个位要控制发声。
8253的主要任务就是产生所要求发声的不同频率的方波。
2.2 乐曲的频率和节拍
乐曲是按照一定的高低、长短、强弱组成的音调。
在一首乐曲中,每个音符的音高和音长和频率和节拍有关。
每个音符的频率值和持续时间是乐曲程序发声需要的两个必要数据。
高音阶从中C(263)到高C(523), 各个音阶对应的频率如下所示:
DW 263 --------- C
DW 294 --------- D
DW 330 --------- E
DW 349 --------- F
DW 392 --------- G
DW 440 --------- A
DW 494 --------- B
DW 523 --------- C
如果知道了乐曲的曲谱,就可以将每个音符的频率和持续时间定义为两个数据表,然后通过调用子程序将表中数据取出,通过扬声器发声。
例如MERRY CHRISTMAS频率表和节拍表如下所示:
CHST_F dw 7 dup(330),392,262,294,330,4 dup(349),2 dup(330),330,294,294,262,294,392
dw 7 dup(330),392,262,294,330,4 dup(349),2 dup(330),392,392,349,294,262,0 CHST_T dw 2 dup(25,25,50),4 dup(25),100,2 dup(25,25,50)
dw 4 dup(25),2 dup(50),2 dup(25,25,50)
dw 4 dup(25),100,2 dup(25,25,50),4 dup(25),100
其中,CHST_F为频率表,CHST_T为节拍表,两个表中的数据一一对应,每一组代表着乐曲中的一个音符,频率表中以0作为结束的标志。
3.方案设计及说明
3.1 设计实现及功能
了解了乐曲演奏的原理,就可以开始设计方案。
首先,明确整个程序的结构及各个程序段的结构和功能,然后设计流程图。
按照要求,程序需要完成的功能如下所示:
1.程序需要通过定时器原理完成播放乐曲的功能,这是最基本的功能。
2.程序应该有判断用户输入是否符合规定,如果输入不正确,应该有所提示。
并且能再次输入。
3.2 流程图
图表 1 主程序流程图
说明:在进入主界面的时候有3个选项,分别是
A:music:Merry Christmas
B:music:the boat on Taihu lake
Q: exit
通过选择不同的选项进入其子界面来实现不同的功能。
4.详细设计
4.1 程序段说明
1) DATA为数据段,其中存放在程序中所要显示的提示选择信息,还有乐曲的频率表
和节拍表,和键盘控制发声对应的音符表。
2) CODE为代码段,由于在整个程序中各个子程序都定义为NEAR,所以只需要有一个
代码段,各个子程序的定义及实现都放在其中。
3)STACK为长度为200的堆栈
4.2主要的宏和过程的实现
4.2.1 DISPLAY显示宏
为将事先定义的数据段字符串显示在屏幕上,定一个参数为b的宏。
将b的地址传到DX。
随后调用DOS09号功能调用。
将字符串显示到屏幕。
调用DISPLAY的实例为: DISPLAY INFO1
DISPLAY INFO2
DISPLAY INFO3
DISPLAY MUSLIST
在此段代码中,程序显示提示作用的字符串和歌曲列表。
DISPLAY宏具体实现如下:
DISPLAY MACRO b
LEA DX,b
MOV AH,9
INT 21H
ENDM
4.2.2 ADDRESS音乐地址宏
歌曲包含节拍和频率。
此处定义的音乐地址宏包含两个参数,将歌曲频率地址导入SI 将歌曲节拍导入BP。
当选择不同的歌曲时,主程序调用该宏,将用户要求的歌曲的频率和
节拍导入,以便在MUSIC中实现发声。
音乐地址宏实现如下:
ADDRESS MACRO A,B
LEA SI,A
LEA BP,DS:B
ENDM
4.2.3 MUSIC宏
在ADDRESS中,程序已经将歌曲的首个频率地址和首个节拍地址分别导入SI、BP。
为了检测歌曲是否结束,在MUSIC中,首先将SI传递到DI,DI与-1相减,如等于0,则得出该频率定义为-1 。
在歌曲频率表定义中将-1定为该歌曲结束标志,此时MUSIC跳出结束。
若该频率不为-1。
调用通用发生程序GENSOUND,将该音符按照频率和节拍表发声。
发声后SI、BP分别加2,跳转到下一个音符的频率和节拍,继续检测歌曲是否结束。
如频率不为0,继续将该音符发声,并循环此过程。
具体实现方法如下:
MUSIC PROC NEAR
PUSH DS
SUB AX,AX
PUSH AX
FREG:
MOV DI,[SI]
CMP DI,0
JE END_MUS
MOV BX,DS:[BP]
CALL GENSOUND
ADD SI,2
ADD BP,2
JMP FREG
END_MUS:
RET
MUSIC ENDP
4.2.4 通用发声程序GENSOUND
该发生程序是在修改BEEP发声程序的基础上,以实现为8088/86编写一个任意频率和任意持续时间的通用发声程序。
该程序包括以下三个步骤:
(1)在8253/54 中的43端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使得定时器2准备接受计数初值。
(2)在8253/54中的42H端口装入一个16位计数值,已建立将要产生的声音频率。
(3)把输出端口61H的0、1两位置1,发出声音。
具体实现如下:
GENSOUND PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AL,0B6H
OUT 43H,AL
MOV DX,12H
MOV AX,348ch
DIV DI
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL
WAIT1:
MOV CX,3314
call waitf
DELAY1:
DEC BX
JNZ WAIT1
MOV AL,AH
OUT 61H,AL
POP DI
POP DX
POP CX
POP BX
POP AX
RET
GENSOUND ENDP
该GENSOUND程序能产生19~65535Hz的声音,这个频率的下限是使除法不产生溢出的最小值。
其上限65535是多余的,因为人能听到的声音最高频率为20000Hz。
此外一般情况下,GENSOUND程序产生的声音不单单和频率有关,还和CPU有关。
CPU 工作频率越高,时延越短,产生的声音越急促。
为了使程序产生一个与CPU工作频率无关的合适时延,在MUSCI中调用了一个时间延时程序WAITF。
4.2.5 WAITF延时程序
80x86的各种处理器采取了6~66MHz的工作频率,loop指令的执行时间在这些处理器上也不相同。
为了建立一个与处理器无关的延时,IBM采用了一种利用硬件产生时间延时的方法,即通过监控端口61H和PB4,使PB4每15.08微秒触发一次,一产生一个固定不变的时间基准。
在IBM PC AT BIOS 的WAITF子程序,就是一个产生Nx15.08微秒时间演示的程序。
调用WAITF子程序时,CX寄存器必须装入15.08微秒的倍数N。
利用WAITF子程序能获得任意的时间延时,而不必在考虑CPU的型号和工作频率。
具体实现如下:
waitf proc near
push ax
waitf1:
in al,61h
and al,10h
cmp al,ah
je waitf1
mov ah,al
loop waitf1
pop ax
ret
waitf endp
4.2.6EXIT退出
当程序要求退出时,主程序会调用RETU进行退出。
EXIT程序内容实际为一个BIOS功能调用。
RETU:
MOV AH,4CH
INT 21H
5.调试过程及实验结果分析
5.1调试过程
1: 在刚开始显示字符串的时候,应该加上0DH,0AH换行,而且在字符串的最后应该以"$"来结尾,然后调用DOS调用 INT 21H,来显示字符串。
调试中发现,如果一个字符串末尾不加"$"的话,DOS调用会直接把之后定义的字符串也同时显示出来,直到遇到"$"为止。
这是由内存的分配模式所决定的,同时定义的变量在内存中会处于相邻位置。
6:在WAITF中直接将CX初始化为3314,每次调用WAITF就能产生10ms的延迟,但要特别注意的是,如果WAITF中用到CX,首先应该将CX压栈(PUSH CX),返回之前出栈
(POP CX)。
5.2实验结果
图1欢迎界面
图2错误提示
图3退出
6.设计心得与改进方案
6.1 注意事项
1. 在程序中,各个变量及标号应该有统一且明确的命名规范,例如频率表的命名规则为:“MUS_FREGn”,节拍表的命名规则为:“MUS_TIMEn”这样能使代码的可读性大大增强,且在编程中也能使逻辑更加清晰,增加编程效率。
2. 不能一开始就开始编写程序,而是应该首先分析问题,设计出程序的框架流程图,明确各个程序段的功能,这样能使效率提高并且能增强持续的逻辑性和可读性。
3. 在设计中应该考虑全面,并且兼顾到各方面的问题。
不能仅仅完成布置的任务,应该努力使程序更健壮,能够处理错误的输入并且给出提示,而且应该有更强的交互能力。
4. 在做课程设计的过程中难免会出现这样那样的问题,因此要保持良好的心
态,在遇到问题时应该仔细想问题的起因及解决方法,不能想都不想就直接放弃或
者问人,这样就失去了做报告的意义,因为在解决问题的过程中可以发现很多以前
忽视的问题。
发现问题,解决问题是我们的主要目的。
6.2 改进方案
在播放一首乐曲中,可以增加一个按ESC按键中断当前播放并返回到主选择界面的功能。
还可以考虑加入在线音乐练习功能,可以在键盘上自己弹奏音乐!这个功能看到被人实现过。
6.3 心得体会
从选题到程序成形可以运行,我收获了好多。
这个过程中我深感自己的专业知识不足所带来的困难,使我知道要想写好汇编语言的程序,必须认真对待代码的每一个细节,还必须熟练的掌握debug 命令,这对程序的调试是非常重要的。
通过这次实际动手能力的培养,我进一步熟悉了汇编语言的结构和使用方法,基本达到了能独立阅读、编制和调试一定规模的汇编语言程序的水平。
在这次学习中加强了我的上机操作能力,加强了我对汇编这门课程的认识,增强了我的学习积极性。
汇编语言是一种面向机器的程序设计语言,是和计算机硬件结合最密切的语言,虽然程序设计语言的发展很快,但它是用户能够使用的最快和最能发挥硬件功能的唯一的一种计算机语言。
在汇编语言中使计算机发声的方法作为一个小的实用程序,具体的显示了汇编语言的用途。
我有了在以后的其他程序中可以更熟练的运用此方法来控制计算机的发声进行汇编课程设计的想法。
在日后的学习中我要加强汇编语言的综合应用程序设计方法,提高汇编语言实际应用能力、增加计算机各方面的知识和运用能力。
7.参考文献
[1]沈美明,温冬婵.IBM—PC汇编语言程序设计(第2版).清华大学出版社,2001年8月.
[2]沈美明,温冬婵.IBM—PC汇编语言程序设计实验教程.清华大学出版社,2003年3月.
8.程序清单
;********** 定义一个宏显示
DISPLAY MACRO b
LEA DX,b
MOV AH,9
INT 21H
ENDM
;**********************音乐地址宏
ADDRESS MACRO A,B
LEA SI,A
LEA BP,DS:B ;10
ENDM
;***********************
DATA SEGMENT
INF01 DB 0DH,0AH,'Welcome!$'
INF02 DB 0DH,0AH,'Here are some music$'
INF03 DB 0DH,0AH,'Please choose one$'
INF04 DB 0DH,0AH,'Wrong input!$'
INF05 DB 0DH,0AH,'Please try again!$'
MUSLIST DB 0DH,0AH,'A:music:Merry Christmas' ;20 DB 0DH,0AH,'B:music:the boat on Taihu lake'
DB 0DH,0AH,'Q: exit'
db 0dh,0Ah,'$'
;****************************************** 音乐一圣诞节快乐
MUS_FREG1 dw 7 dup(330),392,262,294,330,4 dup(349),2 dup
(330),330,294,294,262,294,392
dw 7 dup(330),392,262,294,330,4 dup(349),2 dup
(330),392,392,349,294,262,0
MUS_TIME1 dw 2 dup(25,25,50),4 dup(25),100,2 dup(25,25,50)
dw 4 dup(25),2 dup(50),2 dup(25,25,50)
dw 4 dup(25),100,2 dup(25,25,50),4 dup(25),100
;****************************************** *音乐二太湖船
MUS_FREG2 DW 330,392,330,294,330,392,330,294,330
DW 330,392,330,294,262,294,330,392,294,0
MUS_TIME2 DW 3 DUP(50),25,25,50,25,25,100
DW 2 DUP(50,50,25,25),100
DW 3 DUP(50,25,25),100 DATA ENDS
;***********************************************************
STACK SEGMENT
DB 200 DUP ('STACK')
STACK ENDS
CODE SEGMENT ;60 ASSUME DS:DATA,SS:STACK,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV aH, 0
MOV AL,00
INT 10H
DISPLAY INF01
DISPLAY INF02
DISPLAY INF03
DISPLAY MUSLIST ;70
INPUT: ;控制播放的主程序 MOV AH,01H
INT 21H
Q: ;60
CMP AL,'Q'
JZ RETU
A:
CMP AL,'A'
JNZ B
ADDRESS MUS_FREG1,MUS_TIME1
CALL MUSIC
JMP EXIT1
B:
CMP AL,'B'
JNZ EXIT ;70 ADDRESS MUS_FREG2,MUS_TIME2
CALL MUSIC
JMP EXIT1
EXIT1:
JMP INPUT
EXIT:
DISPLAY INF04
DISPLAY INF05 JMP INPUT
RETU: ;80 MOV AH,4CH
INT 21H
;******************************************发声 ;100 GENSOUND PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AL,0B6H
OUT 43H,AL
MOV DX,12H
MOV AX,348ch ;110 DIV DI
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL
WAIT1:
MOV CX,3314 ;120
call waitf
DELAY1:
DEC BX
JNZ WAIT1
MOV AL,AH
POP DI
POP DX
POP CX
POP BX ;130 POP AX
RET
GENSOUND ENDP
;********************************************
waitf proc near
push cx
waitf1:
in al,61h
and al,10h
cmp al,ah ;140 je waitf1
mov ah,al
loop waitf1
pop cx
ret
waitf endp
;********************************************* 音乐播放
MUSIC PROC NEAR
PUSH DS
SUB AX,AX
PUSH AX
FREG:
MOV DI,[SI]
CMP DI,0
MOV BX,DS:[BP]
CALL GENSOUND
ADD SI,2
ADD BP,2
JMP FREG ;160 END_MUS: RET
MUSIC ENDP
;********************************************
CODE ENDS
END START
本科生课程设计成绩评定表
及格(60-69分)、60分以下为不及格
指导教师签名:
201 年月日。