微机原理课程设计
------数字时钟
一、设计要求
1.通过 8253 定时器产生秒脉冲定时中断。在中断服务程序中实现秒、分、小时的进位
(24 小时制)。
2.在七段 LED 显示器上显示当前时分秒
3.按“C”设置时钟的时间。
二、具体设计
设计思想:
设置 8253 工作于方式二,输出源作为中断信号与 8259IR7 相连,用 8253 产生的脉
冲作为计时信号。调用中断服务程序,在 LED 上显示时间。
所用主要硬件:
计时器 8253、中断控制器 8259、七段 LED 显示管
程序架构
1)6 字节变量 DBUF:存放当前时间值或对准后的时间值,即要显示的时分秒。
2)主程序:挂中断程序。初始化 8259(选择上升沿触发,自动结束方式,屏蔽 IR7
以外的中断)。初始化 8253(选择计数器 0,方式 2,初值为 9999H)。不断执行循
环体(扫描键盘是否按下‘C’键,若是则重置 DBUF 的内容;显示 DBUF 中的时分
秒)。
3)中断服务程序:按照 24 小时制对 DBUF 加一进位。
4)键盘扫描程序:按列扫描,若无键按下则返回 20H;否则,按行扫描确定位置,
返回相应的键值。
5)七段 LED 显示程序:由左到右依次将 DBUF 中的值查表 LED 转换成对应的字形号,
显示在相应的数码管上。
三、实验连线
8253:OUT0 接 8239 的 IR7,CLK0 接 T7,GATE2 接+5V。接数据总线的 D0~D7。
8259:IR7 接 8253 的 OUT0。接数据总线的 D0~D7。
138 译码器:A、B、C、GS 分别接地址总线的 A2、A3、A4、G。Y0、Y4 分别接 8253、8259
片选信号 CS。
四、功能流程图
主程序
中断程序
开始
关中断
修改中断向量
初始化 8259
初始化 8253
开中断
有 A 键按下?
N
重置时间
Y
显示时间
Y
DBUF[2]>3
Y
N
DBUF[1]置 0
DBUF[0]置 0
N
N
N
N
N
DBUF[5]加 1
DBUF[5]>9
Y
DBUF[5]置 0
DBUF[4]加 1
DBUF[4]>5
Y
DBUF[4]置 0
DBUF[3]加 1
DBUF[3]>9
Y
DBUF[3]置 0
DBUF[2]加 1
DBUF[2]>5
Y
DBUF[2]置 0
DBUF[1]加 1
DBUF[0]>=2
N
DBUF[1]>9
Y
DBUF[1]置 0
DBUF[0]加 1
IRET
对准时间
关中断
0->DBUF[0~5]
DBUF 地址->BX
6->CX
显示时间
有键按下?
Y
键值 AL->[BX]
INC BX
CX-1->CX
CX=0
Y
开中断
RET
N
N
五、源程序
CODE
SEGMENT
ZWK
EQU
0FFDDH
;位控制口/键扫口
ASSUME CS:CODE,DS:CODE,ES:CODE
Port0
EQU
0FFE4H
ORG 3400H
Port1
EQU
0FFE5H
H8:
JMP START
OUTSEG equ
0ffdch
;段控制口
ZXK
EQU
0FFDCH
;段控制口
OUTBIT equ
0ffddh
;位控制口/键扫口
IN_KEY
equ
0ffdeh
;键盘读入口
CALL GETKEY
flag
DB 00h
MOV ah,flag
;键下 C 后,flag 为 0ffh,
LED
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
否则为 00h
DB 88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,0DEH,0F3H
DBUF
DB 1,2,3,4,5,6
;时、分、秒六位
KeyTable:
;键码定义
CMP ah,11h
JB again
MOV
DBUF[SI],al;读取六个数
db
07h,04h,08h,05h,09h,06h,0ah,0bh
db
01h,00h,02h,0fh,03h,0eh,0ch,0dh
MOV CX,100H
loop2: CALL DIS
START:
CLI
MOV AX,OFFSET INTTIM ;挂中断程序
MOV BX,003CH
MOV [BX],AX
MOV BX,003EH
MOV AX,0000H
LOOP loop2
INC si
CMP si,6
JB again
STI
MOV [BX],AX
;挂中断程序
CALL FOR8259
;对 8259 初始化
CALL FOR8253
;对 8253 初始化
SKIP:
CALL DIS
;显示 DBUF 中的时间
JMP CON8
;-------------------------------------
STI
CON8:
MOV AL,0
;判断是否按键“C”赋值
FOR8253:
;8253 初始化
MOV DX,0FFE3H
;计数器 0,先低后高,
CALL GETKEY
CMP AL,0cH
JNZ SKIP
CLI
MOV CX,100H
loop1:
CALL DIS
LOOP loop1
MOV si,00h
again:
CALL DIS
模式 2,二进制
MOV AL,34H
OUT DX,AL
MOV DX,0FFE0H
MOV AL,06FH
OUT DX,AL
MOV AL,06DH
OUT DX,AL
RET
INC BYTE PTR[DBUF+2]
;------------------------------------
CMP BYTE PTR[DBUF+2],5
FOR8259:
;8259 初始化
JBE DONE
MOV AL,13H
MOV DX,Port0
MOV BYTE PTR[DBUF+2],0
INC BYTE PTR[DBUF+1]
OUT DX,AL
;写 icw1,选上升沿触发
CMP BYTE PTR[DBUF],2
MOV AL,08H
MOV DX,Port1
JAE HOUR
CMP BYTE PTR[DBUF+1],9
OUT DX,AL
;写 icw2,
JBE DONE
MOV AL,0FH
MOV BYTE PTR[DBUF+1],0
OUT DX,AL
;写 icw4,自动结束方式
INC BYTE PTR[DBUF]
MOV AL,7FH
JMP DONE
OUT DX,AL
;写 ocw1,屏蔽 IR7 以外的中断
HOUR:
RET
CMP BYTE PTR[DBUF+1],3
JBE DONE
;----------------------------------------
MOV BYTE PTR[DBUF],0
MOV BYTE PTR[DBUF+1],0
INTTIM:
;中断服务程序,对 DBUF 加一计时
DONE:
IRET
INC BYTE PTR[DBUF+5]
CMP BYTE PTR[DBUF+5],9
;------------------------------------
JBE DONE
DIS:
;将 DBUF 中的时分秒转换成对应
MOV BYTE PTR[DBUF+5],0
;各个进位运算
的字型号,并显示出来
INC BYTE PTR[DBUF+4]
CMP BYTE PTR[DBUF+4],5
JBE DONE
MOV BYTE PTR[DBUF+4],0
INC BYTE PTR[DBUF+3]
CMP BYTE PTR[DBUF+3],9
JBE DONE
MOV BYTE PTR[DBUF+3],0
PUSH CX
PUSH BX
PUSH AX
MOV CL,20H
MOV BX,OFFSET DBUF
DIS1:
MOV AL,[BX]
PUSH BX
MOV BX,OFFSET LED
XLAT
POP BX
PUSH CX
MOV CX,100H
LOOP $
POP CX
MOV DX,ZXK
;段控制口
OUT DX,AL
MOV AL,CL
MOV DX,ZWK
;位控制口
OUT DX,AL
CMP CL,01H
JZ EXIT
INC BX
SHR CL,1
JMP DIS1
POP AX
POP BX
POP CX
RET
EXIT:
key1:
mov
al,ah
mov
dx,OUTBIT
out
dx,al
shl
al,1
mov
ah,al
nop
nop
nop
nop
nop
nop
mov
dx,IN_KEY
in
al,dx
not
al
nop
nop
and
al,0fh
jnz
key2
inc
bl
loop key1
nkey:
mov
al,20h
;-------------------------------------
GETKEY:
;键扫子程序
ret
mov BYTE PTR flag, 00h
key2:
test al,1
mov
al,0ffh
;关显示口
mov
dx,OUTSEG
out
dx,al
mov
bl,0
mov
ah,0feh
mov
cx,8
je
key3
mov
al,0
jmp
key6
key3:
test al,2
je
key4
mov
al,8
cmp
al,10h
jnc
fkey
mov
bx,offset KeyTable
xlat
fkey:
mov BYTE PTR flag,0ffh
ret
CODE
ENDS
END H8
jmp
key6
key4:
test al,4
je
key5
mov
al,10h
jmp
key6
key5:
test al,8
je
nkey
mov
al,18h
key6:
add
al,bl
六、结果讨论
本程序共有分端口设置模块,计数模块,显示模块等几个模块。经过调试,程序可以实现题
目的要求。时、分、秒都分两位。个位满十后就向前进一位。分秒的十位满六十后也向前进
一位。显示小时两位在满二十四后重新计数。在置数时,使用者可置任意值,下面对几个重
点部分的调试过程和遇到的问题作一定的讨论:
修改后的中断服务子程序(改变进位的条件)
(1)其中进位的条件判断以及后面的闹铃的程序段位置的设置都与程序结果有很大的关系.
进位判断特别要注意仔细,编程实现前应该画个流程图,直接再源文件上改不但不能节省时
间,反而更加浪费时间.
(2)此中断服务子程序的类型设置为 FAR 调用,这里要特别注意.因为相对于中断发生时的
运行状态,此程序段与之不在同一代码段,所以应该定义为 FAR 类型.这样产生了另外一个问
题,在此程序段中若想调用此 CODE 段中以他过程,则那个过程也应该被定义为 FAR 调用,当然
可以简单的通过不使用过程调用解决.以解决此中断子程序过程和其他普通过程对对应过程
的调用冲突.
七、收获
为期大概四天的微机原理课程设计最终结束了,很累,但也很高兴,因为自己所在小组
的课程设计成果通过了老师的检查,得到了老师的认可,当然最高兴的还是我们小组做出的
属于我们的数字时钟系统。整个过程让我们收益匪浅。