音乐播放程序设计文档格式.docx
- 文档编号:20810181
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:23
- 大小:367.71KB
音乐播放程序设计文档格式.docx
《音乐播放程序设计文档格式.docx》由会员分享,可在线阅读,更多相关《音乐播放程序设计文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
所以,扬声器发音时间的长短取决于8255A的PB1信号。
另外CPU通过读8255A的C口,得知8253通道2的状态和扬声器驱动器的状态。
4软件设计
4.1屏幕显示设计
程序运行时,屏幕显示第一界面如下:
MusicPlayer
PleaseSelectaSong
ATwoTigers
BZhengfu
QExit
----------------------
选择A、B分别演奏相应的音乐,选择Q键结束程序运行。
当输入别的按键信号时,显示出错提示信息,界面如下:
ERROR!
!
ChooseABQ
PleaseInputAgain!
按照提示信息重新输入正确字符即可。
上述提示信息在数据段定义,类型为字节型。
首先调用BIOS中断的10H号功能设置文本模式。
程序如下:
MOVAH,00H;
BIOS10子功能
MOVAL,02H;
80*25彩色文本模式
INT10H;
BIOS10功能调用
然后调用背景清屏子程序使文本屏幕清空,为输入信息作准备,清屏子程序如下:
CLRPROCNEAR
MOVBH,0;
第0页
MOVBL,00011010B;
字符属性,蓝底绿字不闪烁
MOVDX,0000H;
0行0列
MOVAL,'
'
;
输出的字符
MOVCX,80*25;
循环次数
MOVAH,02H;
BIOS10H子功能调用,置光标位置
INT10H
MOVAH,09H;
BIOS10H子功能调用,输出字符
INT10H
RET
CLRENDP
最后输出提示语字符。
输出提示语字符时,需要多次使用一段相同的输出代码,将该代码定义为宏,可以避免多次重复书写相同的代码。
不定义为子程序是为了避免多次调用使执行速度减慢。
相应宏定义语句为:
SHOWMACROb
LEADX,b;
将相应字符段的偏移地址装入DX
MOVAH,9;
DOS21H号中断9子功能输出多字符
INT21H
ENDM
则相应的字符提示信息输出代码为:
CALLCLR
showINFO1
showINFO2
showINFO3
showINFO4
showMUSLIST
4.2音乐发声控制
一首乐曲由若干音符组成,一个音符对应一个频率。
将与一个频率对应的计数器初值写入2号计数器(端口地址为42H),扬声器就发出相应的音调,计数器初值的计算公式:
计数器初值=1193182/输出频率
其中,1193182Hz转换成十六进制为12348CH,因此在打开扬声器的条件下,执行下列程序段即可发出与输出频率对应的音调。
MOVAL,0B6H;
写入方式控制字
OUT43H,AL;
写入控制端口
MOVDX,12H
MOVAX,348CH
DIV频率值
频率转换成计数初值
OUT42H,AL
;
低8位送2号计数器
MOVAL,AH
高位送2号计数器
接下来设计发声程序,发声系统受8255A芯片(端口地址为60H-63H)的两根输出线PB0和PB1的控制,PB0输出的高电平使2号计数器正常工作,PB1输出高电平打开输出控制门。
发声程序代码如下:
INAL,61H;
读取8255A的PB端口原输出值
MOVAH,AL;
将原输出值保存于AH中
ORAL,3;
使PB0、PB1、均为1
OUT61H,AL;
打开GATE2门,输出方波到扬声器
4.3节拍时间的实现
下面控制音符的演奏时间,这是设计音乐程序的关键问题。
最直观的方法是按照谱为每一个音符规定一个演奏时间。
在遇到一首不熟悉歌曲时,初期很难确定每个音符的演唱时间,而调试程序的需大量的时间。
为每一个音符规定“单位时间”:
单位时间*N=音符的延长时间
其中,N为调试参数,一首歌曲只有一个调试参数。
设计程序时可以用EQU伪指令定义调试参数,初值现行估算,调试时在修改它。
节拍时间设置好以后,就可以利用延时程序,通过PB1端口控制发声的时间长短。
80x86的各种处理器采用6-66MHZ的工作频率,LOOP治理的执行时间在这些处理器上也不同。
为了建立一个与处理器无关的时间延迟,IBM采用了一个利用硬件产生时间延迟的方法,即通过监控端口61H的PB4,使PB4每15.08us触发一次,以产生一个固定不变的时间基准,在IBM-PC/XT中的BIOS中的WAITF子程序,就是一个产生N*15.08us时间延迟的程序,调用WAITF子程序时,CX寄存器必须装入15.08us的倍数N。
本程序延时程序参考上面的原理,代码如下:
waitfprocnear;
延时保护程序
pushax;
保护寄存器
waitf1:
inal,61h;
读取PB端口地址
andal,10h;
低四位清零
cmpal,ah;
检查是否改变
jewaitf1;
等待改变
movah,al;
改变,保护新端口值
loopwaitf1;
继续,直到CX=0
popax;
恢复寄存器
ret
waitfendp
4.4音乐乐谱编程
组成音乐的每个音符的频率值和持续时间是音乐程序发声所需要的两个数据,根据音调与频率和时间之间的关系,把要编辑的音乐的每个音符的频率和持续时间定义成两个数据表,进而把它们写入通用发声程序。
音符频率表示见表1所示,编程产生各种音符的频率时可参照此表。
表1音符频率表(单位:
赫兹)
4.5程序流程图
主程序流程图如图2。
Y
N
N
图2主流程图
MUSIC子程序流程图如图3。
Y
图3MUSIC子程序流程图
GENSOUND子程序流程图如图4所示:
N
图4GENSOUND子程序流程图
5程序调试及运行
把编好的源程序命名保存为YINYUE.asm,在asm集成环境中进行调试,检查错误并逐一改正,直至编译无错误,如果编译成功,就选择运行选项中的生成exe文件,这样就生成了一个可运行程序。
调试过程中会遇到一些问题,比如界面出现错误,如图5所示。
图5运行错误界面
对于上面出现的错误,要在主菜单的数据段定于语句中字符串后面加了'
$'
,问题就可以得到解决。
运行结果演示过程见附录2。
6小结与体会
本文编写的音乐演奏程序可以满足设计要求,能够播放音乐,并且能够有屏幕显示,极大地方便了人机交互。
这次微机原理课程设计历时两个星期,在整整两星期的日子里,不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
在这次的课程设计中,对于汇编语言的各种功能终于有了一个比较全面和具体的认识,在亲自动手编写程序的过程中,发现了很多读程序时不能发现的漏洞。
虽然上课学过很多的理论,平时也看了一些辅导书上的程序,但是真正自己动手才发现以前对于编程工具的使用还处于一知半解的状态上,各种指令和伪指令代码间的联系还不会应用,这次经过一段上机的实践,对于怎么去排错、查错,怎么去看每一步的运行结果,怎么去了解每个寄存器的内容以确保程序的正确性上都有了很大程度的提高。
在这次课程设计中,把以前学的支离破碎的指令代码相互的功能结合起来,使它们共同组成一个具有一定功能的小程序,这样大大提高了对于汇编语言的功能的认识,同时也极大地提高了我的兴趣。
通过这次课程设计使我更加体会到了理论与实际相结合的重要性,只有理论知识是远远不够的,在实践中可能会遇到各种各样的问题,不多经历就无法感受到这一点。
要在实践中提高自己的动手能力和解决问题的能力,从而学以致用。
附录
附录1程序源代码
DATASEGMENT
INFO1DB0DH,0AH,'
MusicPlayer$'
INFO2DB0DH,0AH,'
$'
INFO3DB0DH,0AH,'
PleaseSelectaSong$'
INFO4DB0DH,0AH,'
$'
INFO5DB0DH,0AH,'
ERROR!
ChooseABQ$'
INFO6DB0DH,0AH,'
PleaseInputAgain!
MUSLISTDB0DH,0AH,'
ATwoTigers'
DB0DH,0AH,'
BZhengfu'
QExit'
-------------------------'
$'
;
*********************************************两只老虎
MUS_FREG1DW262,294,330,262
DW262,294,330,262
DW330,350,393
DW393,441,393,350,330,262
DW294,196,262
DW294,196,262,-1
MUS_TIME1DW4*15,4*15,4*15,4*15
DW4*15,4*15,4*15,4*15
DW4*15,4*15,8*15
DW2*15,1*15,2*15,1*15,4*15,4*15
*********************************************征服
MUS_FREG2DW784,1046,988,784,880,659,880
DW880,880,880,784,659,659,698
DW698,698,698,784,880,659,698,587
DW784,1046,988,784,784,880,784
DW784,1046,988,784,880,659,880
DW698,698,698,659,523,523,587,523,-1
MUS_TIME2DW50,100,50,50,100,50,250
DW50,100,50,50,100,50,250
DW50,50,100,50,100,50,250
DW50,50,100,50,50,200,50,250
DW50,100,50,50,100,50,250
DW50,50,100,50,100,50,300
DW50,50,100,4DUP(50),200
*********************************************
DATAENDS
STACKSEGMENT
DB200DUP('
STACK'
)
STACKENDS
CODESEGMENT
ASSUMEDS:
DATA,SS:
STACK,CS:
CODE
MAIN:
MOVAX,DATA
MOVDS,AX
MOVAH,00H;
MOVAL,02H;
INT10H;
BIOS10功能调用
CALLCLR
*********************************************定义宏
SHOWMACROb
LEADX,b;
将提示语的偏移地址送入DX
MOVAH,9;
调用中断,输出多字符
ENDM
*********************************************音乐地址宏
ADDRESSMACROA,B
LEASI,A;
将频率表的偏移地址送入SI
LEABP,DS:
B;
将节拍时间表的偏移地址送入BP
ENDM
******
showINFO1
showINFO2
showINFO3
showINFO4
showMUSLIST
INPUT:
MOVAH,01H;
等待输入一个字符
CMPAL,'
Q'
;
比较字符
JZretu;
是,返回
A'
与A比较
JNZB0;
不等再比较
ADDRESSMUS_FREG1,MUS_TIME1;
取数据
CALLMUSIC;
调用音乐子程序
JMPEXIT1
B0:
B'
JNZexit
ADDRESSMUS_FREG2,MUS_TIME2
CALLMUSIC
EXIT1:
JMPINPUT;
继续等待输入
EXIT:
CALLCLR;
背景清屏
showINFO5;
输入错误,显示提示语
showINFO6
showINFO1
showINFO2
jmpinput
RETU:
MOVAH,4CH;
返回
CLRPROCNEAR
MOVBH,0;
MOVBL,011010B;
字符属性
MOVDX,0000H;
;
要输出的字符
MOVCX,80*25;
MOVAH,02H;
置光标位置
MOVAH,09H;
BIOS10子功能调用,输出字符
CLRENDP
******************************************发声
GENSOUNDPROCNEAR
PUSHAX;
PUSHBX
PUSHCX
PUSHDX
PUSHDI
MOVAL,0B6H;
OUT43H,AL;
输出到控制端口
MOVDX,12H
MOVAX,348ch
DIVDI;
得到发声频率
OUT42H,AL;
发送低字节
MOVAL,AH
发送高字节
INAL,61H;
MOVAH,AL;
ORAL,3;
使PB1、PB0均为1
OUT61H,AL;
WAIT1:
MOVCX,3314;
延时
callwaitf
DELAY1:
DECBX;
节拍时间值减1
JNZWAIT1
MOVAL,AH;
取回AH中的8255A的PB端口原输出值
OUT61H,AL;
恢复8255A的PB端口
POPDI;
POPDX
POPCX
POPBX
POPAX
RET
GENSOUNDENDP
********************************************
waitfprocnear;
延时子程序
pushax;
inal,61h;
读取PB端口值
andal,10h;
低4位清零
cmpal,ah;
检查PB3是否改变
jewaitf1;
movah,al;
loopwaitf1;
popax;
ret
MUSICPROCNEAR;
音乐子程序
PUSHDS;
压入数据段
SUBAX,AX;
标志位清零
PUSHAX
FREG:
MOVDI,[SI];
取音符频率,送DI
CMPDI,-1;
结束?
JEEND_MUS;
是,退出
MOVBX,DS:
[BP];
取音符持续时间
CALLGENSOUND;
调用GENSOUND发声子程序
ADDSI,2;
频率表指针增2
ADDBP,2;
时间表指针增2
JMPFREG;
继续演奏
END_MUS:
RET;
MUSICENDP
CODEENDS
ENDMAIN
附录2程序运行结果
程序开始运行时界面见附图1所示。
附图1开始运行界面
输入正确的字符命令后运行界面见附图2所示。
附图2正常运行界面
输入错误字符后的运行界面见附图3所示。
附图3输入错误字符界面
输入退出字符Q后运行界面见附图4所示。
然后按任意键即可退出运行界面。
附图4输入字符Q界面
附录3芯片资料
8253只有一个控制字,一个方式控制字只决定一个计数通道的工作模式。
8253的控制字格式如附表1所示,共分为4部分:
通道选择,计数器读/写方式,工作方式和计数码的选择。
附表18253控制字
D7D6D5D4D3D2D1D0
SC1
SC2
RL1
RL0
M2
M1
M0
BCD
计数器选择方式见附表2。
附表28253通道选择
SC1SC0
对应的通道
00
通道0
01
通道1
10
通道2
11
不用
计数器读/写方式选择见附表3。
附表38253读/写方式
RL1RL0
通道读写操作
计数器锁存
只读写低8位字节
只读写高8位字节
读写16位
工作方式选择见附表4。
附表48253工作方式选择
M2M1M0
工作方式选择
000
工作方式0
001
工作方式1
×
工作方式2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 音乐 播放 程序设计
![提示](https://static.bdocx.com/images/bang_tan.gif)