资源描述
功能:
实现一个电子表
按‘A’换小时,按‘B’换小时按,‘C’换小时,按‘D’换小时,每次结束后要按‘F’键
;*********用两个74LS373进行数码管的动态显示;一个做段(要显示的笔画)选,一个做位选
PORTS EQU 211H ;数码管显示地址(选管)
PORTB EQU 210H ;数码管显示内容控制
;*********在8253的定时中断中,通过8255的8个PA口,3个PB口进行扫描
PA EQU 220H ;8255 CS 选择信号端
TC0 EQU 230H ;8253 CS 选择信号端
;*********数据段
DATA SEGMENT
COUNT1 DB 12 ;扫描键盘中断口标志CM读数码管
COUNT2 DB 13 ;延世13次中断标志
KREP DB 0 ;防止连击标志, krep=0:无键按下
KSHAKE DB 0 ;键盘防抖
KFLAG DB 0 ;功能键标志位kflag=1,2,3--key(A\B\C)pressed,4--key(F)pressed
SYMBL DB 0 ;显示标志位0--display bufer,1--display temp
FIRST DB 0 ;修改标志位check 2 digit 0--hight,1--low
ENTER DB 0 ;在缓冲区里有新的数字?有则为1
TABL DW 57FH,5BFH,5DFH,5EFH,5FEH,5FDH,5FBH,5F7H
DW 67FH,6BFH,6DFH,6EFH,6FEH,6FDH,6FBH,6F7H
DW 37FH,3BFH,3DFH,3EFH,3FEH,3FDH,3FBH,3F7H
;键盘扫描码
ASCI DB "0123456789ABCDEFGMPRWXYS"
;键盘顺序码
MASEG DB "THE KEY_PREESED IS ERROR!",13,10,'$'
;按键出错提示字符串
NUMERR DB 13,10,"THE ENTERED DIGIT IS ERROR,INPUT AGAIN!",13,10,'$'
;无效时间提示字符串
LED8 DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,67H
DB 77H,7CH,39H,5EH,79H,71H,80H,76H,38H,05CH
;显示编码表
POINT DW ?
ORDER DW 0
BUFER DB 11H,0EH,12H,12H,0H,13H
;hh:mm:ss;'HELLOo'-at start s;LED初始显示状态
TEMP DB 6 DUP(0) ;时间缓存区
SELECT DB 1,2,4,8,10H,20H
OLDSEG DW 0 ;保持初始中断向量段地址
OLDOFF DW 0 ;保存偏移地址
DATA ENDS
;*********** ***代码段********************
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA
MAIN: MOV AX,DATA
MOV DS,AX
MOV DX,PORTB
MOV AL,00
OUT DX,AL ;熄灭所有数码管
MOV AH,35H ;保存原来的中断向量
MOV AL,11
INT 21H
MOV OLDSEG,ES
MOV OLDOFF,BX
MOV AX,SEG KEYLED ;写入新的中断向量
MOV DS,AX
LEA DX,KEYLED ;取偏移地址
MOV AL,11 ;IRQ3中断向量类型号
MOV AH,25H
INT 21H ;写入IRQ3中断向量
STI
MOV AX,DATA ;CSH 数据段
MOV DS,AX
MOV ES,AX ;CSH 堆栈段(in HDY movsb 要重新设定堆栈段)
MOV DX,PA+3 ;8255 控制字
MOV AL,10010000B ;PA口 输入,PB 口输出
OUT DX,AL
MOV POINT,OFFSET TEMP ;输入 HCQ
IN AL,21H ;读8259中断寄存器
AND AL,0F7H ;1111 1011b
OUT 21H,AL ;开IRQ3
MOV DX,TC0+3 ;8253定时寄存器初始化
MOV AL,01010110B ;xuan TD 1,xie yige di ZJ,gongzuo fangshi 3
OUT DX,AL
MOV DX,TC0+1 ;TD1,wei ding shi qi fu chu zhi
MOV AL,5 ;LS393 OUT 8M/8K,T1 OUT 200HZ
OUT DX,AL ;tc1low8=10
STEP: MOV AH,1 ;按任意键退出
INT 16H
JZ STEP
MOV DX,OLDOFF ;恢复IRQ3中断向量
MOV AX,OLDSEG
MOV DS,AX
MOV AL,11
MOV AH,25H
INT 21H ;重新写入原来的IRQ3的中断向量地址
MOV AH,4CH
INT 21H
;***********************中断子程序,进行键盘扫描及显示*********************
KEYLED PROC FAR ;每72ms进入一次键盘扫描程序
PUSH AX ;寄存器A压栈
STI ;开中断
DEC COUNT1 ;-1 ,到72ms的话要扫描键盘
JZ SCANK ;到72ms的话进行键盘扫描
JMP DISP ;否则进行显示
SCANK: MOV COUNT1,12 ;72ms初始化数字,为下次扫描键盘准备
DEC COUNT2 ;72*13ms=1s?N 扫描
JNZ KSCAN ;去扫描键盘
MOV COUNT2,13 ;恢复count2,为下次读实时时间准备
;*******通过BIOS功能调用读系统时间,并处理后的ASCII数值放入BUFER缓冲区
READT: MOV AH,2 ;读BIOS中系统的时间
INT 1AH ;(CH:CL)=时:分,(DH:DL)=秒:1/100秒
MOV AX,CX ;放到AX中,
MOV DI,OFFSET BUFER ;DI指向时间缓冲区
MOV CL,4
ROL AX,CL ;循环左移,使得小时高位现在为最低位
MOV BL,AL ;保存到BL中
AND BL,0FH ;处理,得到小时的高位
MOV [DI],BL ;将小时的高位放入缓冲区中
INC DI
ROL AX,CL ;小时的低位处理,放入缓冲
MOV BL,AL
AND BL,0FH
MOV [DI],BL
INC DI
ROL AX,CL ;分钟的高位处理,放入缓冲区
MOV BL,AL
AND BL,0FH
MOV [DI],BL
INC DI
ROL AX,CL ;分钟的低位处理,放入缓冲区
MOV BL,AL
AND BL,0FH
MOV [DI],BL
INC DI
MOV AX,DX ;秒的高位处理,放入缓冲区
ROL AX,CL
MOV BL,AL
AND BL,0FH
MOV [DI],BL
INC DI
ROL AX,CL ;秒的低位处理,放入缓冲区
MOV BL,AL
AND BL,0FH
MOV [DI],BL
;****** ****键盘扫描
KSCAN: MOV COUNT1,12 ;SMJP CX duan
MOV DX,PA+1 ;利用线路翻转法扫描键盘
MOV AL,0 ;PB口输出低电平
OUT DX,AL
MOV DX,PA ;读PA口
IN AL,DX
CMP AL,0FFH ;AL=0FFH?是的话没有按键,否则有键按下
JNE PRE ;不相等,说明有键按下
MOV KREP,0 ;按键被释放,置KREP=0
JMP DISP ;无键按下,停止扫描,继续显示
;***********判断是否进行过防抖处理,如果KREP为0且有键按下,则下次中断扫描键盘要防抖动
PRE: CMP KSHAKE,1
JE SCAN ;已经进行过防抖处理?
MOV KSHAKE,1
JMP DISP ;没有进行过防抖处理,则设立防抖处理标志,并跳出进行显示
;***************判断是否是重复按键,防止误操作
SCAN: CMP KREP,1 ;是否有键按下?
JNE SCAN1 ; 有键按下转移到SCAN1
JMP DISP ;没有,上次按键已被释放
SCAN1: MOV KREP,1 ;另一键按下,置标志位KREPanother key is pressed
MOV KSHAKE,0 ;清重复按键及防抖标志
MOV CX,3 ;有键按下,扫描列三次SOME KEY PREESED,SCAN CO
MOV BL,0FEH ;PB口一位置0。逐次从低位到高位'0'FROM LOW BIT T
NEXT: MOV AL,BL
MOV DX,PA+1
OUT DX,AL
MOV DX,PA ;写PB(一位为0) OUT
IN AL,DX ;读PA
CMP AL,0FFH ;如果PA=FF,这一列无键按下
JNE KEYON
ROL BL,1 ;扫描下一列
LOOP NEXT
JMP DISP ;一次循环扫描结束ONE CIRCLE SCAN END
KEYON: AND BL,7
MOV AH,BL ;组合键码AX=PRESSED KEY CODE
EFECT: LEA DI,TABL ;查表得到键码地址SEARCH PRESSED KEY' LOC
CLD ;清除方向标志
MOV CX,24
REPNE SCASW
JE l1
JMP ERR ; 提示出错NOTHING FOUND
l1: SUB DI,2
SUB DI,OFFSET TABL
SHR DI,1 ;逻辑右移DI/2
MOV AL,ASCI[DI] ;得到键码GET PRESSED KEY' ASCII
;*************宏,将BUFER中的内容移动到TEMP中去
BUFMOV MACRO
MOV SI,OFFSET BUFER
MOV DI,OFFSET TEMP
MOV CX,6
CLD
REP MOVSB
MOV SYMBL,1 ;symbl=1,display the temp
ENDM
MOV DL,AL
MOV AH,2
INT 21H ;得到按键,并在屏幕上显示相应的ASCII
;键盘处理子程序,处理各个按键
; KFLAG------有键按下标志,如果有键按下为1
; FIRST------上次有键按下?
; SYMBL------显示内容选择,1时显示TEMP,0时显示BUFER内容
KA: CMP AL,'A' ;按下A键?调整小时
JNE KB
MOV KFLAG,1
MOV FIRST,0 ;判断修改高位
CMP SYMBL,0 ;判断显示BUFER/TEMP
JNE N1 ;如果显示TEMP,不要capyBUFER内容到TEMP
BUFMOV
N1: MOV TEMP,10H ;HH=..
MOV TEMP+1,10H
JMP DISP
KB: CMP AL,'B' ;按下B键?调整分钟
JNE KC
MOV KFLAG,2
MOV FIRST,0
CMP SYMBL,0
JNE N2
BUFMOV
N2: MOV TEMP+2,10H ;MM=..
MOV TEMP+3,10H
JMP DISP
KC: CMP AL,'C' ;按下C键?调整秒
JNE KF
MOV KFLAG,3
MOV FIRST,0
CMP SYMBL,0
JNE N3
BUFMOV
N3: MOV TEMP+4,10H ;SS=..
MOV TEMP+5,10H
JMP DISP
KF: CMP AL,'F' ;按下F键?结束修改
JNE K4
MOV KFLAG,4
MOV SYMBL,0 ;symbl=0,display bufer
JMP REFCMOS
K4: CMP AL,'9' ;按下的数字键?
JBE CHECK
JMP DISP
CHECK: MOV DI,OFFSET TEMP
AND AL,0FH
JNE MM CMP KFLAG,1
HH: CMP FIRST,0 ;从高到低修改两个数码管
JE FIR
INC DI
MOV FIRST,0
MOV ENTER,1 ;enter=1 there is entered digit in temp
JMP H12
FIR: MOV FIRST,1
H12: MOV [DI],AL
JMP DISP
MM: CMP KFLAG,2
JNE SS0
ADD DI,2
CMP FIRST,0 ;从高到低修改两个数码管
JE FIR1
INC DI
MOV FIRST,0
MOV ENTER,1
JMP M12
FIR1: MOV FIRST,1
M12: MOV [DI],AL
JMP DISP
SS0: CMP KFLAG,3
JE YES
JMP DISP
YES: ADD DI,4 ;从高到低修改两个数码管
CMP FIRST,0
JE FIR2
INC DI
MOV FIRST,0
MOV ENTER,1
JMP S12
FIR2: MOV FIRST,1
S12: MOV [DI],AL
JMP DISP
;**********写入新时间******************
REFCMOS:CMP ENTER,1 ;是否有新时间写入?
JNE DONT
LEA DI,TEMP ;修改时间
MOV AH,[DI]
MOV CL,4
SHL AH,CL
INC DI
MOV AL,[DI]
AND AL,0FH
OR AH,AL
CMP AH,24H
JB HOK
JMP SHOWERR ;提示出错
HOK: INC DI
MOV BH,[DI] ;M1
SHL BH,CL
INC DI
MOV BL,[DI] ;M2
AND BL,0FH
OR BH,BL
CMP BH,60H ;MM<=60?
JB MOK
JMP SHOWERR
MOK: INC DI
MOV DH,[DI] ;S1
SHL DH,CL
INC DI
MOV DL,[DI] ;S2
AND DL,0FH
OR DH,DL
CMP DH,60H ;SS<=60?
JB SOK
JMP SHOWERR
SOK: MOV CH,AH
MOV CL,BH
MOV AH,3
INT 1AH ;向CMOS写入实时时钟
MOV KFLAG,0
MOV ENTER,0
JMP DISP ;键盘处理程序完成,跳出显示
;几种错误的情况,在屏幕上显示错误
SHOWERR:MOV AH,9 ;时间无效字符串显示
LEA DX,NUMERR
INT 21H
MOV KFLAG,0
MOV ENTER,0 ;无字符串按下,无新时间修改
DONT: JMP DISP
ERR: MOV AH,9 ;显示按键出错的错误提示信息
LEA DX,MASEG
INT 21H
;*****************显示*************************
;显示模块,每次显示一位数码管
;ORDER内容为当前要显示的数码管的位置,是第一个还是第二个~~~~~第六个
DISP: CMP SYMBL,1 ;显示内容选择,1则TEMP负责BUFER
JE TEMPDIS ;SYMBL=1,跳到显示时钟
MOV SI,OFFSET BUFER ;SYMBL=0,显示BUFER内容
JMP DIS
TEMPDIS: MOV SI,OFFSET TEMP ;显示TEMP的内容
DIS: ADD SI,ORDER ;SI指向要显示的内容
MOV DI,ORDER ;DI为要显示的数的位置
MOV DX,PORTB ;位选数码管
MOV AL,SELECT[DI] ;AL中为选中该数码管时需要的输出数据
OUT DX,AL ;
MOV AL,[SI] ;取出显示内容
MOV AH,0 ;
MOV DI,AX ;
MOV AL,LED8[DI] ;从表中取得显示该内容需要的笔形码
MOV DX,PORTS ;
OUT DX,AL ;送到数码管进行显示
INC ORDER ;
CMP ORDER,6 ;已经显示到最后一个?
JNE QUIT ;
MOV ORDER,0 ;
QUIT: MOV AL,20H ;EOI中断
OUT 20H,AL
POP AX ;寄存器A出栈
IRET ;中断返回
KEYLED ENDP
CODE ENDS
END MAIN
展开阅读全文