📄 clock.txt
字号:
;****************************************************************************************
; 微机接口课程设计程序
; 电子钟
;
;
;8255用作读键盘信息,cs为220h
;8253提供时钟信号,cs为230h
;led采用动态显示,cs为210h
;
;文件名 :clock.asm
;作者 :吴光文
;版本 : 0.6
;2006年12月27日
;
;相对与版本0.5有以下改进:
;将压缩BCD码表示的时、分、秒十进制数分解到六个字节中,用了更加简洁的算法。
;****************************************************************************************
csledslc equ 210h ;数码管选择位
csledword equ 211h ;数码管笔形码输出地址
cs8255a equ 220h ;8255的a口地址
cs8255b equ 221h ;8255的b口地址
cs8255ctr equ 223h ;8255的控制字地址
cs8253t0 equ 230h ;8253的t0地址
cs8253t1 equ 231h ;8253的t1地址
cs8253ctr equ 233h ;8253的控制字地址
.model small
.stack 50
;****************************************************************************************
;数据段
;****************************************************************************************
.data
buf db 0,0,0,0,0,0 ;显示缓冲区
;数码管笔形码
led db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,80h
hour db 08h ;时缓冲单元
min db 30h ;分缓冲单元
sec db 30h ;秒缓冲单元
msec db 0 ;毫秒缓冲单元
dex db 0 ;笔形码索引值
;键盘编码表
keytab dw 57fh,5bfh,5dfh,5efh,5feh,5fdh,5fbh,5f7h
dw 67fh,6bfh,6dfh,6efh,6feh,6fdh,6fbh,6f7h
keyend dw 7ffh
agekey db 12 ;键龄
oldkey dw 0 ;键码字保存
keynum db 0 ;键号
keyok db 0 ;按键响应标记
state db 0 ;系统状态,0-运行态;1-修改态
keymd db 0 ;修改键标记,A-修改时;B-修改分;C-修改秒
stime db 0 ;时间设定单元,保存键盘输入的时间
;****************************************************************************************
;代码段
;****************************************************************************************
.code
;****************************************************************************************
;主程序:
;
;实现8253的设置,中断向量的设置,检测系统大键盘信号,有按键就结束程序返回系统。
;****************************************************************************************
main proc far
start: mov ax,@data ;设置数据段和附加段
mov ds,ax
mov es,ax
cli ;关中断
;设置8253,t1,方式2,输入250kHz,输出200Hz
mov dx,cs8253ctr
mov al,74h
out dx,al
mov dx,cs8253t1
mov ax,1250
out dx,al
mov al,ah
out dx,al
;保存原中断向量
mov al,0bh
mov ah,35h
int 21h
push es
push bx
push ds
;设置新中断向量
mov dx, offset intpro
mov ax,seg intpro
mov ds,ax
mov al,0bh
mov ah,25h
int 21h
;打开中断屏蔽
pop ds
in al,21h
and al,0f7h
out 21h,al
sti ;开中断
;等待按键,返回系统
wat: mov ah,1
int 16h
jz wat
;回复中断向量
pop dx
pop ds
mov al,0bh
mov ah,25h
int 21h
;退出程序,返回系统
mov ax,4c00h
int 21h
;****************************************************************************************
;中断子程序:
;
;完成时钟处理、键盘监控和显示功能
;****************************************************************************************
intpro proc near
push ds ;保存寄存器
push ax
push cx
push dx
mov ax,@data ;设置数据段和代码段寄存器
mov ds,ax
mov es,ax
cmp state,1 ;不是修改状态才走时钟
jne clk
jmp next
;****************************************************************************************
;时钟处理模块,以5毫秒为单位调整时、分、秒。
;****************************************************************************************
clk: inc msec
cmp msec,200
jne next
mov msec,0
mov al,sec
add al,1
daa
mov sec,al
cmp sec,60h
jne next
mov sec,0
mov al,min
add al,1
daa
mov min,al
cmp min,60h
jne next
mov min,0
mov al,hour
add al,1
daa
mov hour,al
cmp hour,24h
jne next
mov hour,0
;****************************************************************************************
;键盘监控模块
;****************************************************************************************
next: dec agekey
jz next1
jmp dsp
next1: mov agekey,12
mov dx,cs8255ctr ;设置PA输出,PB输入
mov al,82h
out dx,al
mov al,0 ;A口输出低电平,读B口
mov dx,cs8255a
out dx,al
mov dx,cs8255b
in al,dx
mov bh,al
mov dx,cs8255ctr ;设置PB输出,PA输入
mov al,90h
out dx,al
mov al,0 ;b口输出低电平,读a口
mov dx,cs8255b
out dx,al
mov dx,cs8255a
in al,dx
mov bl,al ;读键结束,BX中保存为键码
and bx,7ffh ;去除键码中无用位数
cmp bx,7ffh
jne keyon ;有按键则进入按键处理
mov keyok,0 ;无按键则清除响应标志退出按键处理
jmp dsp
keyon: cmp bx,oldkey
je keyon1 ;已经去抖动则直接处理按键
mov agekey,4 ;有新按键则设置键龄退出中断
mov keyok,0
mov oldkey,bx
jmp dsp
keyon1: cmp keyok,1
jne l1 ;按键已响应则退出键盘处理
jmp dsp
l1: mov keyok,1 ;设立按键响应标记
std
lea di,keyend ;指向键码表
mov ax,bx ;读取键号,地址递减,cx的值为键号
mov cx,17
repne scasw
je keyon2
jmp dsp
keyon2: mov keynum,cl ;保存键号
cmp state,0 ;系统在修改态否?
jne keyon3 ;跳到修改态的处理
cmp keynum,0ah ;为A键否
jne keyb
mov keymd,1 ;作a键修改标志
mov hour,0aah ;小时显示为..
mov state,1 ;进入修改态
jmp dsp
keyb: cmp keynum,0bh ;为B键否
jne keyc
mov keymd,2 ;作b键修改标志
mov min,0aah ;分钟显示为..
mov state,1 ;进入修改态
jmp dsp
keyc: cmp keynum,0ch ;为c键否
je keyc1
jmp dsp
keyc1: mov keymd,3 ;作c键修改标志
mov sec,0aah
mov state,1 ;秒显示为..
jmp dsp
keyon3: cmp keynum,9 ;在修改态,判断是否为数字键
jbe keyn ;<=9则认为是数字键
jmp keyen ;否则判断是否为确定键
keyn: mov al,stime ;读取输入时间,十进制格式
mov cl,4
shl al,cl ;在确定以前最后输入的两个十进制数有效
or al,keynum
mov stime,al
jmp dsp
keyen: cmp keynum,0fh ;处理f键
je keyen1
jmp dsp
keyen1: mov state,0 ;恢复到运行态
cmp keymd,1 ;将修改内容送小时单元
jne keyen2
mov keymd,0 ;清除修改小时标志
cmp stime,24h ;判断输入时间是否>=24
jb keyen3
mov hour,0 ;大于24时,输入为0
mov stime,0 ;清除时间单元
jmp dsp
keyen3: mov al,stime
mov hour,al ;小于24时,输入设定时间
mov stime,0 ;清除时间单元
jmp dsp
keyen2: cmp keymd,2 ;将修改分钟标志
jne keyen4
mov keymd,0 ;清除修改分钟标志
cmp stime,60h
jb keyen5
mov min,0
mov stime,0
jmp dsp
keyen5: mov al,stime
mov min,al
mov stime,0
jmp dsp
keyen4: cmp keymd,3 ;将修改秒
jne dsp
mov keymd,0
cmp stime,60h
jb keyen6
mov sec,0
mov stime,0
jmp dsp
keyen6: mov al,stime
mov sec,al
mov stime,0
;****************************************************************************************
;显示模块
;****************************************************************************************
;将时、分、秒信号拷贝到显示缓冲区
dsp: mov si,0
mov di,0
mov cl,4
lp1: mov al,byte ptr hour[si]
mov ah,0
ror al,cl
shr ah,cl
mov word ptr buf[di],ax
inc si
inc di
inc di
cmp si,3
jne lp1
mov cl,dex ;显示数码管的某一位
mov al,1
rol al,cl
mov dx,csledslc
out dx,al
mov al,dex
mov ah,0 ;0扩展到ax
mov si,ax
mov bl,buf[si]
mov bh,0
mov al,led[bx]
mov dx,csledword
out dx,al
inc dex
cmp dex,6
jne exit
mov dex,0
exit: mov al,20h
out 20h,al
pop dx
pop cx
pop ax
pop ds
iret
intpro endp
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -