音乐播放器课程设计.docx
《音乐播放器课程设计.docx》由会员分享,可在线阅读,更多相关《音乐播放器课程设计.docx(32页珍藏版)》请在冰豆网上搜索。
音乐播放器课程设计
课程设计任务书
学生姓名:
宋晓阳专业班级:
电气0805班
指导教师:
刘永红工作单位:
自动化学院
题目:
键盘电子乐器
初始条件:
掌握汇编语言程序设计方法,所设计的程序运行后可通过键盘控制,满足系统功能,并实现该系统设计方案。
在DOS,windows,汇编软件环境下运行。
要求完成的主要任务:
(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
1.设计一个用键盘演奏音乐的程序,计时器系统设计编程定时输出――电子音调,用pc机内部8253time~使扬声器发声。
用汇编语言对8253进行编程,使其OUT0上输出一定的频率,将其一定频率输出到喇叭上,演奏出不同的音节。
pc机的数字键(1-7)作为电子音调的音调选择
2.课程设计说明书应包括:
a)设计任务及要求
b)方案比较及认证
c)程序设计基本思想,程序流程图,部分源程序及注解
d)调试记录及结果分析
e)参考资料
f)附录:
全部源程序清单
g)总结
时间安排:
2011年元月07日--元月09日选题、查阅资料和方案设计
2011年元月10日--元月14日编程
2011年元月15日--元月16日调试程序,改进与提高
2011年元月17日撰写课程设计报告(有调试过程及结果的截屏)
2011年元月18日答辩和交课程设计报告
指导教师签名:
2011年元月6日
系主任(或责任教师)签名:
年月日
摘要
利用PC上的定时/计数芯片8253A控制PC扬声器发声。
编写内核模块,直接操作扬声器相关端口,或字符设备驱动,供应用程序调用,用键盘使其发出不同的声音。
关键字:
8253定时器中断
键盘电子乐器
1.方案比较
1.1发声程序循环
优点:
简单,易于思维
缺点:
程序过于长,比较繁琐
1.2调用宏,进行发声
优点:
程序短
缺点:
不易想到
2.芯片介绍
2.18255芯片简述
图1-18255引脚图
8255可编程外围接口芯片是Intel公司生产的通用并行I/O接口芯片,它具有A、B、C三个并行接口,+5V单电源供电。
2.1.18255三种方式下工作
方式0—基本输入/输出方式
方式1—选通输入/输出方式
方式2—双向选通输入/输出方式
2.1.28255引脚图
如右图所示,各引脚功能如:
D7~D0——与CPU侧连接的八条双向数据线;
WR(低电平有效)—写输入信号;
RD(低电平有效)—读输入信号;
CS(低电平有效)—片选输入信号;
A0、A1—片内寄存器选择输入信号;
PA7~PA0—A口外设双向数据线;
PB7~PB0—B口外设双向数据线;
PC7~PC0—C口外设双向数据线;RESET—复位输入信号
2.1.38255端口地址
寄存器
A口
B口
C口
控制寄存器
端口地址
60H
61H
62H
63H
2.28253芯片简述
8253可编程定时/计数器是Intel公司生产的通用外围芯片之一,有3个独立的十六位计数器,技术频率范围为0~2MHz,它所有的技术方式和操作方式都通过编程控制。
图1-28253引脚图
2.2.18253六种工作方式
方式0:
计数结束中断
方式1:
可编程频率发生器
方式2:
频率发生器
方式3:
方波频率发生器
方式4:
软件触发的选通信号
方式5:
硬件触发的选通信号
2.2.28253引脚图
如上图所示,各引脚功能如下:
D7~D0—八条双向数据线;
WR(低电平有效)—写输入信号;
RD(低电平有效)—读输入信号;
CS(低电平有效)—片选输入信号;
A0、A1—片内寄存器地址输入信号;
CLK—计数输入,用于输入定时基准脉冲或计数脉冲;
OUT—输出信号,以相应的电平指示计数的完成,或输出脉冲波形;
GATE—选通输入,用于启动或禁止计数器的操作,以使计数器和计测对象同步。
2.2.38253端口地址
寄存器
0#计数器
1#计数器
2#计数器
控制寄存器
端口地址
40H
41H
42H
43H
本次课设要求用8253做。
计算机中可以利用8253/54定时器来驱动扬声器。
连接到扬声器上的是定时器2,GATE2与端口61H的PB0相连,当PB0=1时,GATE2获得高电平,使定时器2可以在模式3下工作。
定时器2的OUT2与端口61H的PB1通过一个与门与扬声器的驱动电路相连。
当PB1=1时,允许OUT2的输出信号到达扬声器电路。
下面是控制扬声器的代码:
INAL,61H;getthecurrentsettingofportB
MOVAH,AL;saveit
ORAL,00000011B;makePB0=1andPB1=1
OUT61H,AL;turnthespeakeron
......;howlongthebeepsoundgoeshere
MOVAL,AH;gettheoriginalsettingofportB
OUT61H,AL;turnoffthespeaker
对于IBMPC兼容机来说,无论是8086,80486还是Pentium,驱动扬声器的过程是相同的。
至于音调发出的时间量(音长),则取决于它的延迟的时间,这个延迟时间可以在PC机的80x86主处理器的帮助下实现。
3.通用发声程序
BIOS中的BEEP子程序能根据BX中给出的计数值控制8253/54定时器,产生频率为896Hz的声音。
实际上BEEP是一个很好的通用发声程序。
首先,BEEP程序只能产生896Hz的声音,通用发声程序应能产生任一频率的声音。
其次BEEP产生声音的持续时间(音长)只能是0.5s的倍数,我们希望声音的持续时间更易于调整,例如是10ms的倍数。
给计数器2装入计数值533H就能产生896Hz的声音(1.1931MHz/896Hz=1331=533H),同样,产生其他频率声音的计数值也可以用下式计算出来:
假设发声频率存放在DI寄存器中,下面的指令使AX中得到送往定时器2的计数值:
MOVDX,12H
MOVAX,348CH
DIVDI
利用CPU来产生延迟时间是最常用的一种方法,但对8088/86,80286,386,486以及Pentium来说,它们产生的延迟时间都是不一样的。
对基于8088/86的PC/XT,PS/2等PC机,可用下面的程序来产生时间延迟:
MOVCX,N
DELAY:
LOOPDELAY
在8088/86CPU中,执行一条LOOP指令需要17个时钟周期,因此,执行上面的指令大约需要N*17*T时钟周期。
在BIOS中,利用上述方法来产生250ms延迟时间的程序如下:
SUBCX,CX
G7:
LOOPG7;
如果要产生与10ms成倍数的延迟时间,可在BX寄存器中放入倍数。
例如,要产生1s的持续时间,则在BX中放入100,以控制LOOP指令执行
次,
也就是10ms的100倍。
指令如下:
MOVBX,100
WAIT:
MOVCX,2800
DELAY:
LOOPDELAY
DECBX
JNZWAIT
上述流程图为:
图2-1程序流程图
下面在修改后的BEEP程序的基础上,为8088/86编写一个任一频率(由DI指定)和任一持续时间(由CX和BX指定)的通用发声程序。
此程序包括三个步骤:
(1)在8253/54中的43端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使定时器2准备接收计数初值。
(2)在在8253/54中的42端口(Timer2)装入一个16位的计数值(533H*896/频率),以建立将要产生的声音频率。
(3)把输出端口61H的0/1两位置1,发出声音。
GENSOUNDPROCNEAR
;**********************************
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHDI
;**********************************
MOVAL,0B6H;写8253的控制字选中8253通道1读写16位工作方式3二进制计数方式
OUT43H,AL;向8253中写入上述功能的控制字
MOVDX,12H;假定发生频率存放在DI寄存器中,下面的三行指令使AX中得到送往定时器2的计数值
MOVAX,348ch;1193100HZ/freq
DIVDI;valueoffreq
OUT42H,AL;将AL中数放到8253计数器中
MOVAL,AH
OUT42H,AL;将AL中数放到8253计数器中
INAL,61H;从61h号端口读取PB口现在的状态
MOVAH,AL;将PB口的状态放进AH
ORAL,3;将AL低两位置1
OUT61H,AL;向61h号端口写入一个字节,打开扬声器
WAIT1:
MOVCX,2000;3314
callwaitf
DELAY1:
DECBX
JNZWAIT1
MOVAL,AH;recovervalueofport
OUT61H,AL;从61h号端口读入一个字节
;***********************************
POPDI
POPDX
POPCX
POPBX
POPAX
;***********************************
RET
GENSOUNDENDP
WAITFPROCNEAR
PUSHAX
WAITF1:
INAL,61H
ANDAL,10H;checkpb4
CMPAL,AH;diditchange
JEWAITF1;waitforchange
MOVAH,AL;savethenewpb4status
LOOPWAITF1;continueuntilcxbecomes0
POPAX
RET
WAITFENDP
GENSOUND程序能产生19~65536Hz的声音,这个频率的下限19Hz是使除法不产生溢出的最小的DI值((DX)=12H=18d<19)。
其上限65536Hz是多余的,因为人们最高能听到的音频约为20000HZ。
4.音调与频率和时间的关系
利用计算机控制发声的原理,可以编写演奏乐曲的程序。
在一首乐曲中,每个音符的音高和音长与频率和节拍有关。
图3-1音频频率对照表
组成乐曲的每个音符的频率值和持续时间是乐曲程序发生所需要的两个数据。
音符的频率可以从图3-1中查表得到,但实际上送入计数器2的是输入频率1.1932MHz与音符频率相除的值,通用发声程序SOUNDF的前半部分就是完成这个计算,并将计数值送入计数器2的功能。
;
MOVAL,0B6H;写8253的控制字选中8253通道1读写16位工作方式3二进制计数方式
OUT43H,AL;向8253中写入上述功能的控制字
MOVDX,12H;假定发生频率存放在DI寄存器中,下面的三行指令使AX中得到送往定时器2的计数值
MOVAX,348ch;1193100HZ/freq
DIVDI;valueoffreq
OUT42H,AL;将AL中数放到8253计数器中
MOVAL,AH
OUT42H,AL;将AL中数放到8253计数器中
;.................................
附录
附录一:
程序一流程图
附录二:
程序一
DATASEGMENTPARA'DATA'
INFO1DB0DH,0AH,'WELCOMEYOUTOCOMEHERE!
$'
INFO2DB0DH,0AH,'thisisaPianoprogram!
$'
INFO3DB0DH,0AH,'pleasepress!
$'
INFO4DB0DH,0AH,'INPUTERROR!
$'
INFO5DB0DH,0AH,'PLEASEINPUTAGAIN!
$'
MUSLISTDB0DH,0AH,'1262'
DB0DH,0AH,'2294'
DB0DH,0AH,'3330'
DB0DH,0AH,'4347'
DB0DH,0AH,'5392'
DB0DH,0AH,'6440'
DB0DH,0AH,'7494'
DB0DH,0AH,'8524'
DB0dh,0ah,'$'
MUS_FREG1DW262,-1
MUS_TIME1DW50,25
MUS_FREG2DW294,-1
MUS_TIME2DW50,25
MUS_FREG3DW330,-1
MUS_TIME3DW50,25
MUS_FREG4DW347,-1
MUS_TIME4DW50,25
MUS_FREG5DW392,-1
MUS_TIME5DW50,25
MUS_FREG6DW440,-1
MUS_TIME6DW50,25
MUS_FREG7DW494,-1
MUS_TIME7DW50,25
MUS_FREG8DW524,-1
MUS_TIME8DW50,25
DATAENDS
STACKSEGMENTPARASTACK'STACK'
DB200DUP('STACK')
STACKENDS
CODESEGMENT
ASSUMEDS:
DATA,SS:
STACK,CS:
CODE
MAINPROCFAR
MOVAX,DATA
MOVDS,AX
MOVAH,0;设置显示方式
MOVAL,4;设置显示方式
INT10H;调用显示器中断
MOVAH,0BH;设置背景颜色或彩色组
MOVBH,0;设置背景颜色
MOVBL,2;蓝色
INT10H;调用显示器中断
MOVAH,0BH;设置背景颜色或彩色组
MOVBH,01H;设置字体颜色
MOVBL,1;黑色
INT10H;调用显示器中断
;*****定义一个宏*****
;功能09H功能描述:
输出一个字符串到标准输出设备上。
;如果输出操作被重定向,那么,将无法判断磁盘已满入口参数:
AH=09HDS:
DX=待输出字符的地址
;说明:
待显示的字符串以’$’作为其结束标志
SHOWMACROb
LEADX,b
MOVAH,9
INT21H
ENDM
;**********************
showINFO1;显示字符串
showINFO2;显示字符串
showINFO3;显示字符串
showMUSLIST;显示字符串
INPUT:
MOVAH,01H;设置光标类型
INT21H;调用中断,返回dos
CMPAL,'Q';是否按下Q
JZretu;是则跳转,不是继续向下运行
CMPAL,'1';是否按下1
JNZB0;不是1跳转,是继续向下运行
CALLMUSIC1;跳转到MUSIC1程序
JMPEXIT1;跳转EXIT1
B0:
CMPAL,'2';是否按下2
JNZC0;不是2则跳转,是继续运行
CALLMUSIC2;调用MUSIC2程序
JMPEXIT1;跳转到EXIT1
C0:
CMPAL,'3';是否按下3
JNZD0;不是3跳转,是继续运行
CALLMUSIC3;跳转到MUSIC3程序
JMPEXIT1
D0:
CMPAL,'4';是否按下4
JNZE0;不是4跳转,是继续运行
CALLMUSIC4;跳转到MUSIC4程序
JMPEXIT1
E0:
CMPAL,'5';是否按下5
JNZF0;不是5跳转,是继续运行
CALLMUSIC5;跳转到MUSIC5程序
JMPEXIT1
F0:
CMPAL,'6';是否按下6
JNZG0;不是6跳转,是继续运行
CALLMUSIC6;跳转到MUSIC6程序
JMPEXIT1
G0:
CMPAL,'7';是否按下7
JNZH0;不是7跳转,是继续运行
CALLMUSIC7;跳转到MUSIC7程序
JMPEXIT1
H0:
CMPAL,'8';是否按下8
JNZexit;不是8跳转,是继续运行
CALLMUSIC8;跳转到MUSIC8程序
EXIT1:
showINFO5;显示字符
JMPINPUT;跳转到INPUT
EXIT:
callclear;跳转到clear
showINFO4;显示字符
showINFO5;显示字符
showINFO1;显示字符
showINFO2;显示字符
showINFO3;显示字符
showMUSLIST;显示字符
jmpinput;跳转到INPUT
RETU:
MOVAH,4CH;带返回码返回
INT21H;调用dos中断
MAINENDP
MUSIC1PROCNEAR
PUSHDS
SUBAX,AX
PUSHAX
LEASI,MUS_FREG1;putsthefregtableoffsetinSI
LEABP,DS:
MUS_TIME1;putsthetimetableoffsetinBP
FREG1:
MOVDI,[SI];readnextfrequency
CMPDI,-1;endoftone
JEEND_MUS1;ifyes,exit
MOVDX,DS:
[BP];else,fetchtheduration
MOVBX,5400
CALLGENSOUND;playthenote
ADDSI,2;updatethetablepointer
ADDBP,2
JMPFREG1;goprocessnextnote
END_MUS1:
RET
MUSIC1ENDP
GENSOUNDPROCNEAR
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHDI
MOVAL,0B6H;写8253的控制字选中8253通道1读写16位工作方式3二进制计数方式
OUT43H,AL;向8253中写入上述功能的控制字
MOVDX,12H
MOVAX,533H*896
DIVDI
OUT42H,AL;将AL中数放到8253计数器中
MOVAL,AH
OUT42H,AL;将AL中数放到8253计数器中
INAL,61H;从61h号端口读入一个字节
MOVAH,AL
ORAL,3
OUT61H,AL;向61h号端口写入一个字节
WAIT1:
MOVCX,8FF0H;向CX中写入数
DELAY1:
LOOPDELAY1;延时
DECBX;BX-1
JNZWAIT1;运算结果不为0,则ZF=0,则转移
MOVAL,AH
OUT61H,AL;从61h号端口读入一个字节
POPDI
POPDX
POPCX
POPBX
POPAX
RET
GENSOUNDENDP
MUSIC2PROCNEAR
PUSHDS
SUBAX,AX
PUSHAX
LEASI,MUS_FREG2
LEABP,DS:
MUS_TIME2
FREG2:
MOVDI,[SI]
CMPDI,-1
JEEND_MUS2
MOVDX,DS:
[BP]
MOVBX,1400
CALLGENSOUND
ADDSI,2
ADDBP,2
JMPFREG1
END_MUS2:
RET
MUSIC2ENDP
MUSIC3PROCNEAR
PUSHDS
SUBAX,AX
PUSHAX
LEASI,MUS_FREG3
LEABP,DS:
MUS_TIME3
FREG3:
MOVDI,[SI]
CMPDI,-1
JEEND_MUS3
MOVDX,DS:
[BP]
MOVBX,1400
CALLGENSOUND
ADDSI,2
ADDBP,2
JMPFREG1
END_MUS3:
RET
MUSIC3ENDP
MUSIC4PROCNEAR
PUSHDS
SUBAX,AX
PUSHAX
LEASI,MUS_FREG4;putsthefregtableoffsetinSI
LEABP,DS:
MUS_TIME4;putsthetimetableoffsetinBP
FREG4:
MOVDI,[SI];readnextfrequency
CMPDI,-1;endoftone
JEEND_MUS4;ifyes,exit
MOVDX,DS:
[BP];else,fetchtheduration
MOVBX,5400
CALLGENSOUND;playthenote
ADDSI,2;updatethetablepointer
ADDBP,2
JMPFREG4;goprocessnextnote
END_MUS4:
RET
MUSIC4ENDP
MUSIC5PROCNEAR
PUSHDS
SUBAX,AX
PUSHAX
LEASI,MUS_FREG5;putsthefregtableoffsetinSI
LEABP,DS:
MUS_