信息与电气工程学院电子信息工程CDIO一级项目(2013/2014学年第一学期)题目:音乐演奏程序设计专业班级:xxxxxxxxxxxxxxxxx学生姓名:xxxxxxx学号:xxxxxxxxx指导教师:xxxxxxx设计周数:设计成绩:2013年12月28日1、项目设计目的1.1掌握接口电路的应用和设计技术。
1.2掌握汇编语言的设计思路。
1.3掌握8086的控制流程,以及8255和8253芯片的功能。
1.4用汇编程序完成键控音乐播放器,用8253定时器来产生声音。
1.5使学生能够较全面地巩固和应用课堂中所学的基本理论和程序设计方法,能够较熟练地完成汇编语言程序的设计和调试。
2、项目设计正文2.1设计内容要求完成一个音乐程序,即通过按下键盘上某个按键就可以按预先设定的程序播放音乐或者终止程序。
比如:按大写字母“1”,唱乐曲“沂蒙山小调”;按大写字母“2”,唱乐曲“生日快乐”按大写字母“3”,唱乐曲“棉花糖”;按"4"键,退出。
并且可以重复操作。
2.2总体设计思路在IBM-PC/XT机中都带有8253-5定时/计数器,IBM-PC/AT中带有8254定时/计数器,这两种芯片功能十分类似。
本文通过对8253-5定时/计数器芯片的操作实现音乐演奏。
该声音接口通过汇编语言对8253-5的端口直接进行操作,可以不必要过多的使用BIOS的调用和DOS的调用。
计数器芯片有3个通道,各自具有专用功能。
通道0时系统的始终节拍计时器,通道1专用于产生动态RAM的定时刷新信号,通道2用来控制计算机的扬声器的声音频率。
该音乐演奏主要用到通道2的功能,使通道2工作在“方波发生器”方式,产生相应频率的音调送至喇叭驱动电路,使喇叭发出不同音调的声音。
使用8255A的PB0控制通道2的计数,PB1控制通道2的输出对扬声器产生控制的时间。
人机交互包括屏幕显示提示语以及人工输入相应参数,主要应用到BIOS的10H号中断调用以及DOS 的21H号中断调用。
BIOS的10H号中断调用用于显示器驱动,设置显示模式和光标位置;DOS的21H号中断调用用于单字符输入以及多字符输出显示。
音乐演奏实现的一个主要步骤是乐谱编程。
通过相应的频率表将乐谱中对应的音符转化为计数器的计数初值,节奏通过延时程序转化为对喇叭发音时间的控制,从而实现音符和节拍的数字化。
2.3流程图2.3.1主程序流程图图2-1 主程序流程图2.3.2 MUSIC子程序流程图图2-2 MUSIC子程序流程图2.4通用发声程序设计原理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,61HOR AL,3OUT 61H,AL上面的指令用以打开扬声器,如要关闭扬声器时则为:AND AL,0FCHOUT 61H,AL当从8255中采集到输入的数据时,需要确定相应的频率,所以在软件编程时要建立一个数据表:TABLE DW 493,440,392,349,329,293,261把相应的频率送到一个寄存器上,通过公式:计数值=533H×896÷ f=1234DCH÷ f算出计数值,再把算得的计数值送给8253,就可产生所要频率的方波。
在把计数值送8253前,必须先把8253进行初始化:MOV AL,0B6HOUT 43H,AL使其选用通道2,工作在方式3下。
就整个电路而言,接好电路后,通过软件编程不断地采集从8255口中输入的信号,而8个开关都接在8255的A口上,只要有开关按下,就会采集到一个数据,根据这个数据与事先编好的表对应,得到一个计数值,把这个计数值送给8253的通道2,8253的通道2工作的方式3下,这样就可以产生满足频率要求的发声方波。
这个方波经驱动放大就可以使扬声器发出相应的声音。
所以8255在这里完成两个任务,它不仅从A口中采集到数据,而且B口的PB1和PB0两个位要控制发声。
8253的主要任务就是产生所要求发声的不同频率的方波。
2.5乐曲编辑乐曲是按照一定的高低、长短和强弱关系组成的音调,在每一首乐曲中,每个音符的音高和音长与发声系统中的频率、节拍有关。
可参考下表:音符频率/HZ 半周期/us 音符频率/HZ 半周期/us低1DO 262 1908 #4FA# 740 0676#1DO# 277 1805 中5SO 784 0638低2RE 294 1700 #5SO# 831 0602#2RE# 311 1608 中6LA 880 0568低3M 330 1516 #6LA# 932 0536低4FA 349 1433 中7SI 988 0506#4FA# 370 1350 高1DO 1046 0478低5SO 392 1276 #DO# 1109 0451#5SO# 415 1205 高2RE 1175 0426低6LA 440 1136 #2RE# 1245 0402#6LA# 466 1072 高3M 1318 0372低7SI 494 1012 高4FA 1397 0358中1DO 523 0956 #4FA# 1480 0338#1DO# 554 0903 高5SO 1568 0319中2RE 578 0842 #5S0# 1661 0292#2RE# 622 0804 高6LA 1760 0284中3M 659 0759 #6LA# 1865 0268中4FA 698 0716 高7SI 1976 02532.6各个功能的实现2.6.1显示功能LEA DX,INFO1MOV AH,9INT 21HLEA DX,INFO2INT 21HLEA DX,MUSLISTINT 21HLEA DX,INFO3INT 21HLEA DX,INFO6INT 21H在此段代码中,程序显示提示作用的字符串和歌曲列表。
2.6.2音乐播放模块MUSIC1:LEA SI,FREG1 ;将频率表的偏移地址送入SILEA BP,DS:TIME1 ;将节拍时间表的偏移地址送入BP CALL MUSIC ;调用MUSIC子程序JMP INPUTMUSIC2:LEA SI,FREG2LEA BP,DS:TIME2CALL MUSICJMP INPUTMUSIC3:LEA SI,FREG3LEA BP,DS:TIME3CALL MUSICJMP INPUT2.6.3 MUSIC子程序MUSIC PROC NEARPUSH DSSUB AX,AX ;标志位清零PUSH AXFREG:MOV DI,[SI] ;取音符频率,送DICMP DI,-1JE END_MUSMOV BX,DS:[BP] ;取音符持续时间CALL GENSOUND ;调用GENSOUND发声子程序ADD SI,2 ;频率表指针增2ADD BP,2 ;时间表指针增2JMP FREG ;继续演奏END_MUS:RETMUSIC ENDP2.6.4音乐发声控制一首乐曲由若干音符组成,一个音符对应一个频率。
将与一个频率对应的计数器初值写入2号计数器(端口地址为42H),扬声器就发出相应的音调,计数器初值的计算公式:计数器初值=1193182/输出频率其中,1193182Hz转换成十六进制为12348CH,因此在打开扬声器的条件下,执行下列程序段即可发出与输出频率对应的音调。
MOV AL,0B6H ;写入方式控制字OUT 43H,AL ;写入控制端口MOV DX,12HMOV AX,348CHDIV 频率值;频率转换成计数初值OUT 42H,AL ;低8位送2号计数器MOV AL,AHOUT 42H,AL ;高位送2号计数器接下来设计发声程序,发声系统受8255A芯片(端口地址为60H-63H)的两根输出线PB0和PB1的控制,PB0输出的高电平使2号计数器正常工作,PB1输出高电平打开输出控制门。
发声程序代码如下:IN AL,61H ;读取8255A的PB端口原输出值MOV AH,AL ;将原输出值保存于AH中OR AL,3 ;使PB0、PB1、均为1OUT 61H,AL ;打开GATE2门,输出方波到扬声器2.6.5延时程序利用WAITF子程序能获得任意的时间延时,而不必在考虑CPU的型号和工作频率。
具体实现如下:waitf proc nearpush axwaitf1:in al,61hand al,10hcmp al,ahje waitf1mov ah,alloop waitf1pop axretwaitf endp2.7程序执行结果初始运行界面正确输入时的界面输入错误时的界面3收获与体会通过这次课程设计,我们对各个芯片有了进一步的了解,对各个芯片的功能有了更深刻的认识和体会,平时上课的理论知识只是停留在理论的层面,只有通过了这样的试验才能更好的体会到,做到了理论和实际的相结合,使理论知识真正运用到了实践中去。