电子闹钟接线图
设计原理:
计时功能:
用到的8254的功能只是相当于一个分频计,输入一定频率的脉冲信号使每隔一秒就会在OUT0端产生0到1的跃变,作为中断IRQ的请求信号。由于秒、分的进制形式不同,可通过中断程序控制,由此完成计时功能。
显示功能:
可以用四位二进制码分别对应表示X4X3X2X1的逻辑值(1--高电平,0--低电平),实现时钟的显示功能。具体操作:首先将秒的个位数据通过8255的B端口送给数码管,同时将二进制码“0111”通过8255的A端口送给小键盘X4X3X2X1,这样通过计算机的扫描后,就会在数码管4上显示秒的个位值;接着将秒的十位数据送给数码管,同时将二进制码“1011”送给小键盘X4X3X2X1,这样就会在数码管3上显示相应的数值;同样的道理,分别将分的个位、十位送给数码管,“1101” 、“1110”送给小键盘X4X3X2X1,就会依次在数码管2、1上显示分的个位、十位数值。特别注意分秒的间隔点,由于数码管共阴极,将数码二进制最高位置1,其他为置0即可。
按键功能:
由于X1,X2,X3,X4低电平显示相应的数码管,利用读回的Y1,Y2逻辑值辨别究竟按下哪个键,并通过相应的编程来完成不同键的按键功能。
(1)1键清除功能的设置:
在判别了按键的逻辑值为01110后,将存储时间的每一个内存单元赋0,这样在数码管显示的就是00.00,便达到了清除功能的目的。
(2)2键启动、3键停止计时功能的设置:
在进行2键和3键功能设置之前,我们必须定义一个暂停标志位:PAUSE,它用标准的逻辑值(0、1)来表示,假如PAUSE=0,在进行计时设置的时候,让其自动加1,依次显示时间的各位;假如PAUSE=1,我们就将其返回,停止加1,即暂停计时。
接着,假如我们判别的是2键被按下,就令PAUSE=0,让计数器计时,自动加1;假如我们按下的是3键,就令PAUSE=1,让计数器暂停计时,即停止加1。
(3)4键终止程序功能的设置:
从上面的分析,我们已经知道,只有同时将对应键盘X列的低电平送到相应的数码管才会使得数码管亮,所以我们在判别了是4键被按下后,只要将键盘对应的二进制码全部赋高电平,并送到数码管,同时结束程序,就可以实现熄灭数码管、退出程序的功能。
(4)5键重置初始值功能的设置:
在这里我们设置了两个标志位:调整位标志ADJUST和闪烁标志FLASH。它们的具体设置如下:
ADJUST初始设置为00H,表示非调整状态,01H表示调整秒的个位,02H表示调整秒的十位,03H表示调整分的个位,04H表示调整分的十位。
FLASH设置为逻辑值,初始设置为00H,表示非闪烁状态,0FFH表示闪烁,其闪烁功能实现的过程为:假如FLASH=0FFH,则将00H送给数码管,让数码管不显示。然后,在中断计时程序里面,加入FLASH取反语句,由于计时程序每秒加1循环一次,这样FLASH也实现了每秒改变逻辑值一次。也就是说,数码管闪烁的周期是1秒。当然,闪烁标志位只是在有对应位需要调整的时候才用的着。
要实现5键设置初始时间的功能,我们就必须增加一个键(6键)来控制时间的增加。
(5)6键时间位加1功能的设置
这里,我们再引进一个标志位:按键标志KEYMARK。其设置为逻辑值,初始设置为0,表示允许响应此次按键,并在响应过后,将其置1;KEMARK为1时,表示不响应此次按键。之所以要设置此标志位,是因为键盘扫描的速度非常快,假如我按下6键需要调整时间加1,我按下的时间再怎么短,计算机一定已经扫描了无数次,这样一来,我只按了一次,时间位就会响应无数次,实现了无数次的加1,从而无法实现6键的功能。
汇编源程序:
INTCSR_BYTE0 EQU 9438H
INTCSR_BYTE1 EQU 9439H
INTCSR_BYTE2 EQU 943AH
INTCSR_BYTE3 EQU 943BH
IMB4_BYTE3 EQU 941FH
MY8254_COUNT0 EQU 9C40H
MY8254_COUNT1 EQU 9C41H
MY8254_COUNT2 EQU 9C42H
MY8254_MODE EQU 9C43H
MY8255_A EQU 9C60H
MY8255_B EQU 9C61H
MY8255_C EQU 9C62H
MY8255_MODE EQU 9C63H
IRQ EQU 01C8H
DATA SEGMENT
CSBAK DW ?
IPBAK DW ?
MKBAK DB ?
ADJUST DB 00H ;调整位标志
FLASH DB 00H ;闪烁标志位
PAUSE DB 0B ;暂停标志位
KEYMARK DB 0B ;按键标志位
INKEY DB 00H ;按键
SECONDA DB 00H ;秒个位
SECONDB DB 00H ;秒十位
MINUTEA DB 00H ;分个位
MINUTEB DB 00H ;分十位
LED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;数码管0-9的编码
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
CLI
MOV AX,DATA
MOV DS,AX
MOV DX,INTCSR_BYTE0
MOV AL,00H
OUT DX,AL
MOV DX,INTCSR_BYTE1
MOV AL,1FH
OUT DX,AL
MOV DX,INTCSR_BYTE2
MOV AL,3FH
OUT DX,AL
MOV DX,INTCSR_BYTE3
MOV AL,00H
OUT DX,AL
MOV AX,0000H
MOV ES,AX
MOV DI,01ccH ;保存系统中断矢量
MOV AX,ES:[DI]
MOV IPBAK,AX
MOV AX,OFFSET MYINT
CLD
STOSW
MOV AX,ES:[DI]
MOV CSBAK,AX
MOV AX,SEG MYINT ;设置中断矢量
STOSW
IN AL,0A1H
MOV MKBAK,AL
AND AL,0F7H
OUT 0A1H,AL
STI ;开中断
MOV DX,MY8254_MODE ;8254初始化
MOV AL,15H ; 00010101:计数器0,只读低八位,方式2分频器,十进制
OUT DX,AL
MOV DX,MY8254_COUNT0
MOV AL,0
OUT DX,AL
MOV DX,MY8255_MODE ;8255初始化
MOV AL,81H ;10000001:A口:方式0,输出,B口:方式 0 ,
;输出,C口:低四位输入,高四位输出
OUT DX,AL
A1: NOP ;等待
MOV CX,32H
A2: MOV DX, MY8255_B
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET LED
MOV AL,SECONDA
XLAT LED
CMP ADJUST,01H ;是否调整秒的个位
JNE DIS_SECONDA
CMP FLASH,0FFH ;是否闪烁
JNE DIS_SECONDA
AND AL,00H ;熄灭数码管(若FLASH=1)
DIS_SECONDA: ;显示秒的个位
OUT DX, AL
MOV DX,MY8255_A
MOV AL,0111B
OUT DX,AL
CALL KEYCTR ;调用按键处理程序
CALL DELAY ;调用延迟程序
MOV DX,MY8255_B
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET LED
MOV AL,SECONDB
XLAT LED
CMP ADJUST,02H ;是否调整秒的十位
JNE DIS_SECONDB
CMP FLASH,0FFH
JNE DIS_SECONDB
AND AL,00H
DIS_SECONDB: ;显示秒的十位
OUT DX,AL
MOV DX,MY8255_A
MOV AL,1011B
OUT DX,AL
CALL KEYCTR
CALL DELAY
MOV DX,MY8255_B
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET LED
MOV AL,MINUTEA
XLAT LED
CMP ADJUST,03H ;是否调整分的个位
JNE DIS_MINUTEA
CMP FLASH,0FFH
JNE DIS_MINUTEA
AND AL,00H
DIS_MINUTEA: ;显示分的个位
ADD AL,80H ;显示XX.XX中的点“.”
OUT DX,AL
MOV DX,MY8255_A
MOV AL,1101B
OUT DX,AL
CALL KEYCTR
CALL DELAY
MOV DX,MY8255_B
MOV AX,DATA
MOV DS,AX
MOV BX , OFFSET LED
MOV AL, MINUTEB
XLAT LED
CMP ADJUST,04H ;是否调整分的十位
JNE DIS_MINUTEB
CMP FLASH,0FFH
JNE DIS_MINUTEB
AND AL,00H
DIS_MINUTEB: ;显示分的十位
OUT DX,AL
MOV DX,MY8255_A
MOV AL , 1110B
OUT DX,AL
CALL KEYCTR
CALL DELAY
LOOP SK1
JMP SK2
SK1: JMP A2
SK2: JMP A1
MYINT: PUSH DS
PUSH AX
PUSH DX
MOV DX,IMB4_BYTE3
IN AL,DX
MOV DX,INTCSR_BYTE2
MOV AL,3FH
OUT DX,AL
;清8259中断标志
MOV AL,63H ;根据中断号修改
OUT 0A0H,AL
MOV AL,62H
OUT 20H,AL
MOV AX,DATA
MOV DS,AX
NOT FLASH ;中断处理程序
MOV KEYMARK,0B
CMP PAUSE,0B
JNE L1
INC SECONDA
CMP SECONDA,0AH
JC L1
MOV SECONDA,00H
INC SECONDB
CMP SECONDB,06H
JC L1
MOV SECONDB,00H
INC MINUTEA
CMP MINUTEA,0AH
JC L1
INC MINUTEB
MOV MINUTEA,00H
CMP MINUTEB,06H
JC L1
MOV MINUTEB,00H
L1: POP DS
POP AX
POP DX
IRET
KEYCTR PROC NEAR
MOV INKEY,AL
MOV DX,MY8255_C
IN AL,DX
AND AL,03H ;高六位清零
CMP AL,10B ;是否按下Y1行
JNE INY2
ADD INKEY,00H
JMP JUDGKEY
INY2: CMP AL,01B ;是否按下Y2行
JNE SKIP
ADD INKEY,10000B
JUDGKEY:
CMP INKEY,01110B ;是否按下1键
JNE KEY2
AND SECONDA,00H ;时间位清零
AND SECONDB,00H
AND MINUTEA,00H
AND MINUTEB,00H
SKIP: JMP BACK
KEY2: CMP INKEY,01101B ;是否按下2键
JNE KEY3
AND PAUSE,0B ;启动计时
JMP BACK
KEY3: CMP INKEY,01011B ;是否按下3键
JNE KEY4
MOV PAUSE,1B ;暂停计时
JMP BACK
KEY4: CMP INKEY,00111B ;是否按下4键
JNE KEY5
MOV DX,MY8255_A
MOV AL,0FFH ;熄灭数码管,程序退出
OUT DX,AL
CALL DELAY
MOV AX,4C00H
INT 21H
JMP BACK
KEY5: CMP INKEY,11110B ;是否按下5键
JNE KEY6
CMP KEYMARK,0B
JNE KEY6
MOV KEYMARK,1B
MOV PAUSE,1B
CMP ADJUST,04H ;是否已调整完分的十位
JE TL
INC ADJUST
JMP BACK
TL: AND ADJUST,00H
JMP BACK
KEY6: CMP INKEY,11101B ;是否按下6键
JNE BACK
CMP KEYMARK,0B
JNE BACK
MOV KEYMARK,1B
CMP ADJUST,01H ;是否调整秒的个位
JNE AD1
INC SECONDA ;秒的个位加1
CALL OUTCLEAR ;判断溢出
JMP BACK
AD1: CMP ADJUST,02H ;是否调整秒的十位
JNE AD2
INC SECONDB
CALL OUTCLEAR
JMP BACK
AD2: CMP ADJUST,03H ;是否调整分的个位
JNE AD3
INC MINUTEA
CALL OUTCLEAR
JMP BACK
AD3: CMP ADJUST,04H ;是否调整分的十位
JNE BACK
INC MINUTEB
CALL OUTCLEAR
BACK: RET
KEYCTR ENDP
OUTCLEAR PROC NEAR ;溢出清零程序
CMP SECONDA,0AH
JC Q1
AND SECONDA,00H
Q1: CMP SECONDB,06H
JC Q2
AND SECONDB,00H
Q2: CMP MINUTEA,0AH
JC Q3
AND MINUTEA,00H
Q3: CMP MINUTEB,06H
JC Q4
AND MINUTEB,00H
Q4: RET
OUTCLEAR ENDP
DELAY: PUSH CX ;延迟程序
MOV CX,1111H
DXMS: LOOP DXMS
POP CX
RET
CODE ENDS
END START