一、设计时间
2011 年 6 月 13 日-----6 月 16 日
二、设计地点
三、设计目的
1、了解计算机发声原理。
2、学习 8086 与 8253 的连接方法及编程方法。
3、学习 8086 对 8255A 的控制方法及编程方法。
4、学会在汇编程序中运用中断的控制。
四、设计小组成员
五、指导老师
六、设计课题
经过小组组员的讨论,决定选取选题:电子琴。
理由: 检验和提高我们在原理与接口综合应用方面分析问题与解决问题的能
力,同时也给我提供更多、更好的训练机会。根据设计要求,尽可能完成设
计要求的功能,选择最合适的器件,构成最有效的硬件电路来完成
七、基本思路及关键问题的解决方法:
基本思路:构造一简易电子琴:选择利用8253A、8255A以及中断控制扬声器
发声以及利用键盘1、2、3、4、5、6、7、8设计一个电子琴,通过按数字键
响相应的乐符1、2、3、4、5、6、7、i,使能演奏简单的乐曲
关键问题解决方法:在读入键盘并由按键控制相应音符的发音时跳转指令太
多,导致后面几个音发不出来,因此就把跳转指令移到前面,先检测是不是
那个按键,是的话就跳转到具体的指令代码
八、算法及流程图
开始
键盘读入一个字符
是 ESC 键吗?
N
N
是数字 1~8 键吗?
Y
求出音阶值保存
赋 相 应 频 率
延时
Y
返回 DOS
九、调试过程中出现的问题及相应解决办法
硬件问题:开始时运行程序后按键盘 1~8 只能发出难听的闷箱声 虽然有音
调但声音完全不对。
解决办法:换一个实验箱。
软件问题:在读入键盘并由按键控制相应音符的发音时跳转指令太多,导
致后面几个音发不出来。
解决办法:把跳转指令移到前面,先检测是不是那个按键,是的话就跳转
到具体的指令代码。
十、课程设计心得体会
这次微机实验课程设计,使我对微机软硬件结合有了进一步的了解。原来
并不太清楚是什么意思,一直都很模糊,听课本也是很迷茫;而之前的那
些单元实验,也没有都做好。之前做的实验,由于大部分是验证性的,所
以就很被动地去做,甚至并没有想为什么要那样连电路,内部的代码更没
有认真看。这次课程设计,因为要自己去设计整个过程,所以就不得不去
了解学习自己原来并没有真正弄懂的东西。比如一些程序的代码的意思,
汇编语言的逻辑,比如一些芯片的用途。使我对前面所做的实验有了原理
性的了解,回头看一些实验,也知其然其所以然了。同时对课本上讲的一
些内容,不再像以前那样觉得抽象,通过这次设计,有了具体的理解。
与此同时,我们小组分工明确,提高了课程设计的效率,很好地发扬了团
队精神,希望能再接再厉。
十一、源程序
;8255 命令口
;8253 的 2 号计数器端口
;8253 命令口
db 'Press 1,2,3,4,5,6,7,8,ESC:',0dh,0ah,'$'
303h
306h
307h
equ
equ
equ
segment
stack1 segment
dw 200 dup(?)
stack1 ends
ctr155
timer2
timctl
data
msg
old_seg dw ?
old_off dw ?
data
code
assume
charout proc near
ends
segment
cs:code, ds:data
push
mov
cx
cx,10000
loop
gg
cx
ret
gg:
pop
charout
endp
sing proc near
mov
mov
out
mov
mov
out
mov
out
ret
sing
main
endp
proc
mov
mov
begin:
dx,timctl
al,0b6h
dx,al
dx,timer2
ax,bx
dx,al
al,ah
dx,al
far
ax,data
ds,ax
call sing
mov
mov
out
mov
out
dx,303h
al,80h
dx,al
al,0dh
dx,al
mov dx,offset msg
;延时
;返回
;8253-5 计数初值计算与装入子程
;8253-5 命令口
;8253-5 初始化命令
;8253-5 计数器 2 的端口
;取计数初值
;装计数初值低字节
;装计数初值高字节
;返回
;发音主程序
;调用 8253-5 的 sing 子程序
;初始化 8255A
;置 PC6=1,打开 8253-5 的 GATE2,开始输出方波
ah,9
mov
int 21h
;显示提示信息
checkkey:mov
int
cmp
Je
mov
int
ah,0bh
21h
al,0
checkkey
ah,01
21h
;按键发送
;有键按下?
;若有键按下,则从 KB 读入,并在 CRT 上显示
mov
bl,al
;保存键值,以备发送
;关闭 8253 的 T2
;关闭喇叭
;寄存器出栈
;寄存器压栈
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
;关闭喇叭(8255 的 PC0=0)
cmp al,1bh
je quit
jne next1
quit:
mov dx, 303h
mov al, 0ch
out dx, al
mov al, 00h
out dx, al
pop bx
pop bp
pop si
pop di
mov ah,4ch
int 21h
next1:
cmp al,'1'
je key1
jne next2
key1: push di
push si
push bp
push bx
mov al,0ch
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,262
jmp pp
next2:
cmp al,'2'
je key2
jne next3
key2: push di
;寄存器压栈
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
;关闭喇叭(8255 的 PC0=0)
push si
push bp
push bx
mov al,0ch
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,294
jmp pp
next3:
cmp al,'3'
je key3
cmp al,'4'
je key4
cmp al,'5'
je key5
cmp al,'6'
je key6
cmp al,'7'
je key7
cmp al,'8'
je key8
jne checkkey
key3:
push di
;寄存器压栈
push si
push bp
push bx
mov al,0ch
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,330
jmp pp
key4: push di
push si
push bp
push bx
mov al,0ch
mov dx,303h
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
;关闭喇叭(8255 的 PC0=0)
;寄存器压栈
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,349
jmp pp
key5: push di
push si
push bp
push bx
;关闭喇叭(8255 的 PC0=0)
;寄存器压栈
mov al,0ch
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,392
jmp pp
key6: push di
push si
push bp
push bx
mov al,0ch
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,440
jmp pp
key7: push di
push si
push bp
push bx
mov al,0ch
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,494
jmp pp
key8: push di
push si
;关闭喇叭(8255 的 PC0=0)
;寄存器压栈
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
;关闭喇叭(8255 的 PC0=0)
;寄存器压栈
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
;关闭喇叭(8255 的 PC0=0)
;寄存器压栈
push bp
push bx
mov al,0ch
mov dx,303h
out dx,al
mov al,00h
mov dx,303h
out dx,al
mov di,523
jmp pp
pp:
mov dx,12h
mov ax,34dch
div di
mov dx,306h
out dx,al
mov al,ah
out dx,al
mov dx,303h
mov al,01h
out dx,al
mov al,0dh
out dx,al
mov bx,3
call time_delay
mov dx,303h
mov al,0ch
out dx,al
mov al,00h
out dx,al
jmp checkkey
endp
main
new_intr proc
dec bx
iret
new_intr endp
time_delay proc near
pushf
push ds
push es
push bx
mov ah,35h
mov al,1ch
int 21h
;关闭 8253 的 T2 计数器(8255 的 PC6=0)
;关闭喇叭(8255 的 PC0=0)
;计算音符的频率所对应的 8253 计数初值
;1.19318MHz
;向 8253 装入计数初值
;先装低字节
;再装高字节
;打开喇叭(8255 的 PC0=1)
;打开 8253 的 T2(PC6=1),开始发声
;取 1 个音符的延时次数→bx
;调用延时子程
;关闭 8253 的 T2(PC6=0)
;关闭喇叭(PC0=0)
;新中断服务程序
;该服务程序只将延时次数-1
;延时子程序
;压栈
;取原中断(INT1CH)的向量,并保存
mov old_off, bx
mov bx, es
mov old_seg, bx
pop bx
pop es
mov ah, 25h
mov al, 1ch
mov dx, seg new_intr
mov ds,dx
lea dx, new_intr
int 21h
pop ds
cmp bx,0h
jnz TD
push ds
TD:
;设置新中断服务程序的向量 4
;延时次数已到?
;未到,则继续
mov ah,25h
;已到,则恢复原中断向量
mov al,1ch
mov dx,old_seg
push dx
mov dx,old_off
pop ds
int 21h
pop ds
popf
ret
time_delay endp
code
ends
end
main
十二、参考文献
(1) 《微机原理与接口技术项目教程》杨居易编著 清华大学出版社
(2) 32 位微机实验指导书.