资源描述
微机原理课程设计报告
院 系: 襄樊学院物理与电子工程学院
班 级: 电子信息科学与技术0611班
指导老师: 张 静
姓 名: 杜 勇 06111028
邓 丰 06111025
雷 雄 06111026
目 录
一、课题名称及设计组成员 2
二、课题内容及要求 2
三、方案、系统组成框图和工作原理说明 2
1、方案 2
2、系统组成框图 2
3、工作原理 2
四、程序功能描述及程序流程 2
2、程序功能描述 2
3、程序流程图 3
五、程序源代码及注释 3
六、DOS/BIOS功能调用,文件列表清单 3
七、电路的连接及调试 3
1、电路连接 3
2、调试步骤 3
八、调试中出现的问题、原因及排除方法 3
九、收获和体会 3
十、参考文献 4
一、课题名称及设计组成员
课题名称
计算机钢琴和音乐发生器程序
设计人
姓名
学号
分工
杜 勇
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、 音乐播放系统控制
实现功能:
① 制作一个菜单,使用菜单条选择功能,让用户选择演奏的乐曲。
② 用定时器方式演奏画皮之主题曲《画心》实现音乐演奏。
③ 提示使用ESC键或者ENTER键可以退出当前过程或返回DOS。
④ 实现控制变量可以控制不同的效果以及要求,如播放速度,间隔等。
⑤ 界面美观,程序结构化程度高,模块结构合理。
⑥ 设计出相应的音乐取码软件。
3、 实验环境
16位的汇编语言程序设计有几种工作环境,本实验以及所有程序都是通过MASM5.0编译的,MASM5.0一个汇编语言的编译、连接、调试及运行的集成环境。支持标号的快速定位,编译速度快。
三、方案、系统组成框图和工作原理说明
1、方案
基于PC计算机的时钟晶振为1.1931816MHz,利用电脑里面的蜂鸣器发出声音。
各音阶标称频率值:
/*-------------------------------------------------------------*/
音符: 1 2 3 4 5 6 7
(重低音)
对应频率(Hz): 131 147 165 175 196 220 247
(低音)
对应频率(Hz): 262 294 330 349 392 440 494
(中音)
对应频率(Hz): 523 587 659 698 784 880 988
(高音)
对应频率(Hz): 1046 1175 1318 1397 1568 1760 1975
/*-------------------------------------------------------------*/
2、系统组成框图
PC机扬声器电路以及相关接口电路如下:
PC机扬声器电路以及相关接口电路
3、工作原理
PC中的定时电路有三个通道,通道3用于发声,通道1用于控制系统内部的时钟。大家都十分清楚用DOS的"TIME"命令可以观察并修改系统内部的一个时钟,这个时钟之所以能连续运转主要依靠定时器的通道1。
通道1的工作方式和通道3一样,但是系统启动时设定其发出一个频率固定为18.2Hz的信号,这个信号直接送到系统中的"中断控制器"。每一个"Hz"都产生一个硬件中断,一般称这个硬中断为"IRQ0",对应的中断号是08H。也就是说,当计算机启动后,我们的机器看上去十分平静,但实际上CPU非常忙碌。在定时器的控制下每隔55毫秒就要执行一个08H号中断,这个中断的主要工作就是连续地计数。
在内存"0040H:006CH"处有四字节的存储空间专门用于保存计数值,CPU每执行一次08H中断,这四字节的计数值就被加1,不难算出这个计数值每增加1091后时间恰好过了1分钟,每增加65454后时间恰好过了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送缓存区,发出与按键相对应频率的声音,从而实现计算机钢琴功能。并不停地对Esc键、Enter键扫描,当Esc键或Enter键按下时,就退出程序。当按下p时,显示播放音乐目录。当按下数字选择键时,播放程序中预设的曲目。当检测到q时,退出到计算机钢琴演奏状态。
3、程序流程图
开始
显示缓存区,变量初始化
键盘扫描
调用发音子程序
是否Esc或Enter键
是否p键
是否为q键
返回DOS
Y
N
N
Y
Y
N
播放音乐菜单
播放音乐程序
键盘扫描
是否播放完毕
Y
N
五、程序源代码及注释
;/*-------------------------------------------------------------------------------------------*/
;编译环境:MASM5.0
;日期:2009-3-2
;时间:8:03
;数据段定义
data segment ;数据定义段
assume ds:data ;建立数据段寄存器寻址
msg_1 db '<<---Welcome you to this OS.--->> $',0dh,0ah ;定义字节
msg_2 db 0dh,0ah,'In this OS. you can press below keys to enjoy:$'
msg_3 db 0dh,0ah,'Super Low: q-w-e-r-t-y-u$'
msg_4 db 0dh,0ah,' Low: a-s-d-f-g-h-j$'
msg_5 db 0dh,0ah,' Mid: z-x-c-v-b-n-m$'
msg_6 db 0dh,0ah,' Hig: 1-2-3-4-5-6-7$'
msg_7 db 0dh,0ah,'Anytime you can press ''Esc'' or ''Enter'' to exit.$'
msg_8 db 0dh,0ah,'What''s more, you can press ''p'' to play music!$'
msg_9 db 0dh,0ah,'Please select the music(press ''q'' to exit the main menu):$'
msg_10 db 0dh,0ah,'1. Huaxin$'
msg_11 db 0dh,0ah,'2. Jingle bells$'
msg_12 db 0dh,0ah,'3. Happy birthday to you$'
msg_13 db 0dh,0ah,'4. Happy new year$'
msg_21 db 0dh,0ah,' $'
note_t dw 131,147,165,175,196,220,247 ;重低音
dw 262,294,330,349,392,440,494 ;低音
dw 523,587,659,698,784,880,988 ;中音
dw 1046,1175,1318,1397,1568,1760,1975 ;高音
dw 0 ;休止符0
; '1','2','3','4','5','6','7' ;从低到高
key_t db 'q','w','e','r','t','y','u' ;重低音
db 'a','s','d','f','g','h','j' ;低音
db 'z','x','c','v','b','n','m' ;中音
db '1','2','3','4','5','6','7' ;高音
db '0' ;休止符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','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'
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',0
music_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, 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, 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','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',0
music_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, 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, 8, 8, 4, 4, 8, 8, 4, 4, 16, 4, 4
db 8, 8, 4, 4, 8, 8, 4, 4, 8, 8, 4, 4, 32
jiepai db ? ;节拍变量定义
speed db 2 ;播放速度控制
jiange db 1 ;音符间隔停顿时间
data ends ;数据定义段结束
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;代码段定义
code segment ;代码定义段
assume cs:code ;建立代码段寄存器寻址
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;字符显示
show macro str ;宏定义,输入参数:字符串str
lea dx,str ;装入str的有效地址
mov ah,09h ;调用中断21,09h显示字符串
int 21h
endm ;宏定义结束
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;主函数
main proc far ;主函数过程定义
mov ax,data ;取数据段地址
mov ds,ax ;装载数据段寄存器ds,使之指向当前数据段
show msg_21
show msg_1 ;调用宏,显示字符串
show msg_2
show msg_3
show msg_4
show msg_5
show msg_6
show msg_7
show msg_8
show msg_21
mov bx,0 ;设定查表数组下标初值
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;按键扫描
key_scan:
mov al,6
mov jiepai,al ;初始化节拍
mov bx,0000h ;初始化指针
mov ah, 00h ;利用bios的16号中断,扫描键盘按键
int 16h ;AL中返回按键的ASCII码
cmp al, 0dh ;判断是否为Enter键
jz exit ;是回车键就退出
cmp al, 1bh ;判断是否为Esc键
jz exit ;是退出键就退出
cmp al, 'p' ;判断是否为p键
jz play ;是p键就play music
lookup:
cmp key_t[bx],al ;取出对应频率值
je next
inc bx ;指针+1
jmp lookup
next:
shl bx,1 ;指针×2,计算频率表指针
mov cx,note_t[bx];取得对应数组下标值的频率值
call beep ;调用固定频率子程序
jmp key_scan ;否则继续扫描
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
exit: ;退出
mov ah,4ch ;调用中断21,4ch退出系统
int 21h
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;音乐播放菜单
play:
show msg_9
show msg_10
show msg_11
show msg_12
show msg_13
show msg_21
input: mov ah, 00h ;利用bios的16号中断,扫描键盘按键
int 16h ;AL中返回按键的ASCII码
cmp al, 'q' ;判断是否为Enter键
jz start ;是'q'键就退到主菜单
cmp al, '1' ;判断是否为数字1
jz next6 ;是'1'键就播放相对应的歌曲
cmp al, '2' ;判断是否为数字2
jz next7 ;是'2'键就播放相对应的歌曲
jmp input ;否则继续扫描按键
next6: call play_m1
next7: call play_m2
start: call main
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;音乐播放程序1
play_m1 proc near
next5: mov bx,0
next3: mov al,music_n1[bx] ;取出music频率值
push ax
mov al,music_d1[bx] ;取出music节拍
mov jiepai,al
pop ax
cmp al, 0 ;是否为音乐结束标志符
je input ;是则退出play
push bx ;保存bx,bx为music频率指针
mov bx,0
look1: cmp key_t[bx],al ;查表取出对应频率值的指针bx
je next1 ;找到就beep
inc bx ;指针+1
and bx,0ffh
jmp look1 ;未找到则继续查找
next1:
shl bx,1 ;指针×2,计算频率表指针
mov cx,note_t[bx];取得对应数组下标值的频率值
cmp cx,0
je next4
call beep ;调用固定频率子程序
call pause ;调用停顿时间
pop bx ;获得music指针
inc bx ;继续取得下一个音符
jmp next3
next4: call nobeep
call pause ;调用停顿时间
pop bx ;获得music指针
inc bx ;继续取得下一个音符
jmp next3
play_m1 endp
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;音乐播放程序2
play_m2 proc near
nex5: mov bx,0
nex3: mov al,music_n2[bx] ;取出music频率值
push ax
mov al,music_d2[bx] ;取出music节拍
mov jiepai,al
pop ax
cmp al, 0 ;是否为音乐结束标志符
je input ;是则退出play
push bx ;保存bx,bx为music频率指针
mov bx,0
loo1: cmp key_t[bx],al ;查表取出对应频率值的指针bx
je nex1 ;找到就beep
inc bx ;指针+1
and bx,0ffh
jmp loo1 ;未找到则继续查找
nex1:
shl bx,1 ;指针×2,计算频率表指针
mov cx,note_t[bx];取得对应数组下标值的频率值
cmp cx,0
je nex4
call beep ;调用固定频率子程序
call pause ;调用停顿时间
pop bx ;获得music指针
inc bx ;继续取得下一个音符
jmp nex3
nex4: call nobeep
call pause ;调用停顿时间
pop bx ;获得music指针
inc bx ;继续取得下一个音符
jmp nex3
play_m2 endp
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
main endp ;主函数过程结束
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;固定频率响
beep proc near
mov dx,0012h
mov ax,34dch
div cx ;ax为所得分频值
out 42h,al ;输出频率值,低8位
mov al,ah
out 42h,al ;输出频率值,高8位
call spk_on ;开启蜂鸣器
mov ah,00h ;取时钟计数值
int 1ah
mov al,jiepai ;18.2次为1000ms, 2次约为100ms
add al,speed
cbw ;al值转为16位ax
add ax,dx ;加上当前时钟计数值,得到计数终值
mov bx,ax ;计数终值置入bx
delay1: mov ah,00h
int 1ah ;取时钟计数值
cmp bx,dx ;到终值吗?
jnz delay1 ;未到,继续延时
call spk_off ;关闭蜂鸣器
ret
beep endp
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;休止符延迟时间
nobeep proc near
call spk_off ;关闭蜂鸣器
mov ah,00h ;取时钟计数值
int 1ah
mov al,jiepai ;18.2次为1000ms, 2次约为100ms
add al,speed
cbw ;al值转为16位ax
add ax,dx ;加上当前时钟计数值,得到计数终值
mov bx,ax ;计数终值置入bx
delay2: mov ah,00h
int 1ah ;取时钟计数值
cmp bx,dx ;到终值吗?
jnz delay2 ;未到,继续延时
ret
nobeep endp
;/*-------------------------------------------------------------------------------------------*/
;/*-------------------------------------------------------------------------------------------*/
;音符间隔停顿时间
pause proc near
call spk_off ;关闭蜂鸣器
mov ah,00h ;取时钟计数值
int 1ah
mov al,jiange ;18.2次为1000ms, 2次约为100ms
cbw ;al值转为16位ax
add ax,dx ;加上当前时钟计数值,得到计数终值
mov bx,ax ;计数终值置入bx
delay3: mov ah,00h
int 1ah ;取时钟计数值
cmp bx,dx ;到终值吗?
jnz delay3 ;未到,继续延时
ret
pause endp
;/*-------------------------------------------------------------------------------------------*/
;/*-----------
展开阅读全文