1、微机原理课程设计报告院 系: 襄樊学院物理与电子工程学院班 级: 电子信息科学与技术0611班指导老师: 张 静姓 名: 杜 勇 06111028邓 丰 06111025雷 雄 06111026目 录一、课题名称及设计组成员2二、课题内容及要求2三、方案、系统组成框图和工作原理说明21、方案22、系统组成框图23、工作原理2四、程序功能描述及程序流程22、程序功能描述23、程序流程图3五、程序源代码及注释3六、DOS/BIOS功能调用,文件列表清单3七、电路的连接及调试31、电路连接32、调试步骤3八、调试中出现的问题、原因及排除方法3九、收获和体会3十、参考文献4一、课题名称及设计组成员课题
2、名称计算机钢琴和音乐发生器程序设计人姓名学号分工杜 勇06111028按键键值与频率查表设计邓 丰06111025按键扫描处理雷 雄06111026固定频率发声分析报告日期2009年 3 月 2 日二、课题内容及要求1、 计算机钢琴基本功能:I、利用键盘按键“q、w、e、r、t、y、u”实现音调的重低音输入,利用键盘按键“a、s、d、f、g、h、j”实现音调的低音输入,利用键盘按键“z、x、c、v、b、n、m”实现音调的中音输入,利用键盘按键“1、2、3、4、5、6、7”实现音调的重低音输入。II、实现菜单选择以及处理各种功能键的多种中级功能。2、 音乐播放系统控制实现功能: 制作一个菜单,使
3、用菜单条选择功能,让用户选择演奏的乐曲。 用定时器方式演奏画皮之主题曲画心实现音乐演奏。 提示使用ESC键或者ENTER键可以退出当前过程或返回DOS。 实现控制变量可以控制不同的效果以及要求,如播放速度,间隔等。 界面美观,程序结构化程度高,模块结构合理。 设计出相应的音乐取码软件。3、 实验环境16位的汇编语言程序设计有几种工作环境,本实验以及所有程序都是通过MASM5.0编译的,MASM5.0一个汇编语言的编译、连接、调试及运行的集成环境。支持标号的快速定位,编译速度快。三、方案、系统组成框图和工作原理说明1、方案基于PC计算机的时钟晶振为1.1931816MHz,利用电脑里面的蜂鸣器发
4、出声音。各音阶标称频率值:/*-*/音符:1234567(重低音)对应频率(Hz):131147165175196220247(低音)对应频率(Hz):262294330349392440494(中音)对应频率(Hz):523587659698784880988(高音)对应频率(Hz):1046117513181397156817601975/*-*/2、系统组成框图PC机扬声器电路以及相关接口电路如下:PC机扬声器电路以及相关接口电路3、工作原理PC中的定时电路有三个通道,通道3用于发声,通道1用于控制系统内部的时钟。大家都十分清楚用DOS的TIME命令可以观察并修改系统内部的一个时钟,这个
5、时钟之所以能连续运转主要依靠定时器的通道1。通道1的工作方式和通道3一样,但是系统启动时设定其发出一个频率固定为18.2Hz的信号,这个信号直接送到系统中的中断控制器。每一个Hz都产生一个硬件中断,一般称这个硬中断为IRQ0,对应的中断号是08H。也就是说,当计算机启动后,我们的机器看上去十分平静,但实际上CPU非常忙碌。在定时器的控制下每隔55毫秒就要执行一个08H号中断,这个中断的主要工作就是连续地计数。在内存0040H:006CH处有四字节的存储空间专门用于保存计数值,CPU每执行一次08H中断,这四字节的计数值就被加1,不难算出这个计数值每增加1091后时间恰好过了1分钟,每增加654
6、54后时间恰好过了1小时。系统内部的时钟之所以能准确走时,靠得就是08H中断和这四字节的计数值。因此我们要想精确的定时,必须依靠时钟计数值才行。由于PC计算机的时钟晶振为1.1931816MHz,根据频率的公式:f=1/T 则频率周期为T=1/f 定时器的计数器为16位计数器,则最大的计数值为65536,那么其定时时间为:t=65536*T=65536/f=0.0549254(秒) 即:PC定时器每秒可中断18.2065次。四、程序功能描述及程序流程2、程序功能描述程序开始,显示提示信息,对缓存区初始化。按键扫描,接着调用发音子程序在把AL送缓存区,发出与按键相对应频率的声音,从而实现计算机钢
7、琴功能。并不停地对Esc键、Enter键扫描,当Esc键或Enter键按下时,就退出程序。当按下p时,显示播放音乐目录。当按下数字选择键时,播放程序中预设的曲目。当检测到q时,退出到计算机钢琴演奏状态。3、程序流程图开始显示缓存区,变量初始化键盘扫描调用发音子程序是否Esc或Enter键是否p键是否为q键返回DOSYNNYYN播放音乐菜单播放音乐程序键盘扫描是否播放完毕YN五、程序源代码及注释;/*-*/;编译环境:MASM5.0;日期:2009-3-2;时间:8:03;数据段定义data segment;数据定义段assumeds:data;建立数据段寄存器寻址msg_1 db $,0dh,
8、0ah;定义字节msg_2db0dh,0ah,In this OS. you can press below keys to enjoy:$msg_3db0dh,0ah,Super Low:q-w-e-r-t-y-u$msg_4db0dh,0ah, Low:a-s-d-f-g-h-j$msg_5db0dh,0ah, Mid:z-x-c-v-b-n-m$msg_6db0dh,0ah, Hig:1-2-3-4-5-6-7$msg_7 db0dh,0ah,Anytime you can press Esc or Enter to exit.$msg_8db0dh,0ah,Whats more, yo
9、u can press p to play music!$msg_9db0dh,0ah,Please select the music(press q to exit the main menu):$msg_10db0dh,0ah,1. Huaxin$msg_11db0dh,0ah,2. Jingle bells$msg_12db0dh,0ah,3. Happy birthday to you$msg_13db0dh,0ah,4. Happy new year$msg_21db0dh,0ah, $note_tdw 131,147,165,175,196,220,247;重低音dw 262,29
10、4,330,349,392,440,494;低音 dw 523,587,659,698,784,880,988;中音 dw 1046,1175,1318,1397,1568,1760,1975;高音dw0;休止符0;1,2,3,4,5,6,7;从低到高key_tdbq,w,e,r,t,y,u;重低音dba,s,d,f,g,h,j;低音dbz,x,c,v,b,n,m;中音db1,2,3,4,5,6,7;高音db0;休止符0;画心music_n1 db b,c,c,x,z,x,x,b,c db 0,b,c,c,x,z,x,b,n db c,0,b,c,c,x,z,x,z,j db z,x,j,g,
11、h,d,g db h,h,c,x,z,j,j,g,h db g,g,h,h,z,j,h,g db s,d,d,d,g,h,h,j,z,g db z,x,x,c,c,b,c,c,x,z,x db z,j,z,x,j,g,h,d,g db h,h,c,x,z,j,g,h,h,0 db d,d,g,h,h,z,j,h,g,h db h,d,d,d,g,h,h,j,z,g,z db x,x,c,c,b,c,c,x,z db x,z,j,z,x,j,g,h,d,g,h db h,c,x,z,j,g,h,h,b,c db c,x,z,x,x,b,c,c,c,b,c db c,x,z,x,b,n,x,c,c
12、 db b,c,c,x,z,x,z,j db z,x,j,g,h,d,g,h,h,c db x,z,j,g,h,h,0music_d1 db 4, 4, 8, 4, 4, 8, 4, 4, 16 db 8, 4, 4, 8, 4, 4, 8, 4, 4 db 16, 8, 4, 4, 8, 4, 4, 8, 4, 4 db 4, 4, 4, 4, 8, 4, 4 db 8, 4, 4, 4, 4, 8, 8, 4 db 4, 4, 8, 4, 4, 4, 4, 8 db 4, 2, 16, 4, 4, 8, 4, 4, 4, 4 db 4, 4, 4, 4, 8, 4, 4, 8, 4, 4,
13、 8 db 4, 4, 4, 4, 4, 4, 8, 4, 4 db 8, 4, 4, 4, 4, 8, 4, 2, 8, 8 db 4, 4, 4, 8, 4, 4, 4, 4, 4, 4 db 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4 db 4, 4, 4, 16, 4, 4, 8, 4, 4 db 8, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8 db 4, 4, 4, 4, 8, 4, 4, 16, 4, 4 db 8, 4, 4, 8, 4, 4, 4, 4, 8, 4, 4 db 8, 4, 4, 8, 4, 4, 4, 4, 8 db 4, 4
14、, 8, 4, 4, 8, 4, 4 db 4, 4, 4, 4, 8, 4, 4, 8, 4, 4 db 4, 4, 8, 4, 4, 32;铃儿响叮当+生日快乐+新年好music_n2 db g,c,x,z,g,0,g,h,g,c,x,z;铃儿响叮当 db h,0,h,a,h,v,c,x,j,g,b,b,v,x,c,z db g,c,x,z,g,0,g,h,g,c,x,z,h,v,c,x db b,b,b,b,n,b,v,x,z db c,c,c,c,c,c,c,b,z,x,c db v,v,v,v,c,c,c,x,x,z,x,b db c,c,c,c,c,c,c,b,z,x,c db v
15、,v,v,v,c,c,b,b,v,x,z,0 db g,g,h,g,z,j;生日快乐 db g,g,h,g,x,z db g,g,b,c,z,j,h db v,v,c,z,x,z,0 db z,z,z,g,c,c,c,z,z,c,b,b,v,c,x,x,c;新年好 db v,v,c,x,c,z,z,c,x,g,j,x,z,0music_d2 db 4, 4, 4, 4, 8, 4, 2, 2, 4, 4, 4, 4 db 8, 4, 2, 2, 4, 4, 4, 4, 8, 8, 4, 4, 4, 4, 8, 4 db 4, 4, 4, 4, 8, 4, 2, 2, 4, 4, 4, 4, 4
16、, 4, 4, 4 db 4, 4, 4, 4, 4, 4, 4, 4, 16 db 4, 4, 8, 4, 4, 8, 4, 4, 4, 2, 16 db 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 8, 8 db 4, 4, 8, 4, 4, 8, 4, 4, 4, 2, 16 db 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 16,32 db 4, 4, 8, 8, 8, 16 db 4, 4, 8, 8, 8, 16 db 4, 4, 8, 8, 8, 8, 8 db 4, 4, 8, 8, 8, 16, 32 db 4, 4, 8, 8, 4, 4,
17、8, 8, 4, 4, 8, 8, 4, 4, 16, 4, 4 db 8, 8, 4, 4, 8, 8, 4, 4, 8, 8, 4, 4, 32jiepai db ?;节拍变量定义speeddb2;播放速度控制jiangedb1;音符间隔停顿时间dataends;数据定义段结束;/*-*/;/*-*/;代码段定义code segment;代码定义段 assumecs:code;建立代码段寄存器寻址;/*-*/;/*-*/;字符显示show macro str;宏定义,输入参数:字符串str leadx,str;装入str的有效地址 mov ah,09h;调用中断21,09h显示字符串 in
18、t 21h endm;宏定义结束;/*-*/;/*-*/;主函数mainprocfar;主函数过程定义mov ax,data;取数据段地址mov ds,ax;装载数据段寄存器ds,使之指向当前数据段showmsg_21showmsg_1;调用宏,显示字符串showmsg_2showmsg_3showmsg_4showmsg_5showmsg_6showmsg_7showmsg_8showmsg_21movbx,0;设定查表数组下标初值;/*-*/;/*-*/;按键扫描key_scan:moval,6mov jiepai,al ;初始化节拍movbx,0000h;初始化指针movah, 00h;
19、利用bios的16号中断,扫描键盘按键int16h;AL中返回按键的ASCII码cmpal, 0dh;判断是否为Enter键jzexit;是回车键就退出cmpal, 1bh;判断是否为Esc键jzexit;是退出键就退出cmpal, p;判断是否为p键jzplay;是p键就play musiclookup:cmpkey_tbx,al;取出对应频率值jenextincbx;指针+1jmplookupnext:shlbx,1;指针2,计算频率表指针movcx,note_tbx;取得对应数组下标值的频率值callbeep;调用固定频率子程序jmpkey_scan;否则继续扫描;/*-*/;/*-*/
20、exit:;退出 mov ah,4ch;调用中断21,4ch退出系统 int 21h;/*-*/;/*-*/;音乐播放菜单play:showmsg_9showmsg_10showmsg_11showmsg_12showmsg_13showmsg_21input:movah, 00h;利用bios的16号中断,扫描键盘按键int16h;AL中返回按键的ASCII码cmpal, q;判断是否为Enter键jzstart;是q键就退到主菜单cmpal, 1;判断是否为数字1jznext6;是1键就播放相对应的歌曲cmpal, 2;判断是否为数字2jznext7;是2键就播放相对应的歌曲jmpinpu
21、t;否则继续扫描按键next6:callplay_m1next7: callplay_m2start:callmain;/*-*/;/*-*/;音乐播放程序1play_m1procnearnext5:movbx,0next3:moval,music_n1bx;取出music频率值 push ax moval,music_d1bx;取出music节拍 mov jiepai,al pop axcmpal, 0;是否为音乐结束标志符jeinput;是则退出playpushbx;保存bx,bx为music频率指针movbx,0look1:cmpkey_tbx,al;查表取出对应频率值的指针bxjene
22、xt1;找到就beepincbx;指针+1andbx,0ffhjmplook1;未找到则继续查找next1:shlbx,1;指针2,计算频率表指针movcx,note_tbx;取得对应数组下标值的频率值cmpcx,0jenext4callbeep;调用固定频率子程序callpause;调用停顿时间popbx;获得music指针incbx;继续取得下一个音符jmpnext3next4:callnobeepcallpause;调用停顿时间popbx;获得music指针incbx;继续取得下一个音符jmpnext3play_m1 endp;/*-*/;/*-*/;音乐播放程序2play_m2 pro
23、cnearnex5:movbx,0nex3:moval,music_n2bx;取出music频率值 push ax moval,music_d2bx;取出music节拍 mov jiepai,al pop axcmpal, 0;是否为音乐结束标志符jeinput;是则退出playpushbx;保存bx,bx为music频率指针movbx,0loo1:cmpkey_tbx,al;查表取出对应频率值的指针bxjenex1;找到就beepincbx;指针+1andbx,0ffhjmploo1;未找到则继续查找nex1:shlbx,1;指针2,计算频率表指针movcx,note_tbx;取得对应数组下
24、标值的频率值cmpcx,0jenex4callbeep;调用固定频率子程序callpause;调用停顿时间popbx;获得music指针incbx;继续取得下一个音符jmpnex3nex4:callnobeepcallpause;调用停顿时间popbx;获得music指针incbx;继续取得下一个音符jmpnex3play_m2 endp;/*-*/;/*-*/mainendp;主函数过程结束;/*-*/;/*-*/;固定频率响beep procnearmovdx,0012hmovax,34dchdivcx;ax为所得分频值out42h,al;输出频率值,低8位moval,ahout42h,a
25、l;输出频率值,高8位callspk_on;开启蜂鸣器movah,00h;取时钟计数值int1ahmoval,jiepai;18.2次为1000ms, 2次约为100msaddal,speedcbw ;al值转为16位axaddax,dx;加上当前时钟计数值,得到计数终值movbx,ax;计数终值置入bxdelay1:movah,00hint1ah;取时钟计数值cmpbx,dx;到终值吗?jnzdelay1;未到,继续延时callspk_off;关闭蜂鸣器retbeep endp;/*-*/;/*-*/;休止符延迟时间nobeep procnearcallspk_off;关闭蜂鸣器movah,
26、00h;取时钟计数值int1ahmoval,jiepai;18.2次为1000ms, 2次约为100msaddal,speedcbw ;al值转为16位axaddax,dx;加上当前时钟计数值,得到计数终值movbx,ax;计数终值置入bxdelay2:movah,00hint1ah;取时钟计数值cmpbx,dx;到终值吗?jnzdelay2;未到,继续延时retnobeep endp;/*-*/;/*-*/;音符间隔停顿时间pause procnearcallspk_off;关闭蜂鸣器movah,00h;取时钟计数值int1ahmoval,jiange;18.2次为1000ms, 2次约为100mscbw ;al值转为16位axaddax,dx;加上当前时钟计数值,得到计数终值movbx,ax;计数终值置入bxdelay3:movah,00hint1ah;取时钟计数值cmpbx,dx;到终值吗?jnzdelay3;未到,继续延时retpause endp;/*-*/;/*-