六、程序清单:
各芯片地址:8259 30H 8255 60H 8253 20H 存储器 2000H
DATAS SEGMENT ;程序初始化 AGAIN DB '0','0','0','0','0','0' DATA2 DB 6 DUP (?) DATA3 DB 6 DUP (?) DATAS ENDS
STACKS SEGMENT STA DB 100 DUP(?) STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:DATAS START:
MOV AX,DATAS MOV DS,AX
MOV AX,STACKS MOV SS,AX
MOV AX,0 ;初始化中断向量表 MOV ES,AX
MOV BX,84H ;IR1中断类型码21h*4=84h MOV AX,OFFSET INPUT MOV ES:[BX],AX
MOV AX,SEG INPUT ;段地址 MOV ES:[BX+2],AX
MOV AL,90H ;8255初始化,A口方式0,输入;B、c口方式0,输出
OUT 63H,AL
MOV AL,36H ;8253初始化,方式0 OUT 23H,AL
MOV AL,13H ;8259A初始化,ICW1 OUT 30H,AL
MOV AL,20H ;ICW2 OUT 31H,AL
MOV AL,01 ;ICW4 OUT 31H,AL
MOV AL,00 ;OCW1 OUT 31H
MOV CX,06H ;从RAM里读出密码到DATA2,密码为6位 MOV SI,2000H
MOV DI,OFFSET DATA2 LP1:MOV AL,[SI] MOV [DI],AL INC SI
INC DI
LOOP LP1 ;读入密码结束
MOV BX,00H ;输入密码次数计数器初始值 RE: MOV AL,03H OUT 62H,AL
MOV AL,71H ;未开锁,B口输出显示FF OUT 61H,AL
MOV CX,06H
MOV SI,OFFSET DATA2 ;定义SI、DI MOV DI,OFFSET DATA3 HLT
STI ;停机,开中断,等待密码输入 CLD
INC BX ;输入密码次数加1
REPE CMPSB ;将输入六位数码与密码比较 CMP CX,00
JE OPEN ;相等则转到开锁
CMP BX,06H ;输入错误且累积未够6次,重新输入 JNE RE
MOV AL,07H ;若错误次数累积够6次,触发蜂鸣器报警
OUT 62H,AL
MOV AL,71H ;B口输出FF OUT 61H,AL
MOV AL,2048H ;报警铃响计时,90秒后关断蜂鸣器,保持显示FF OUT 20H,AL MOV AL,03H OUT 62H,AL
JMP DOON ;跳到结束
OPEN:MOV AL,0BH ;开锁,并显示00 OUT 62,AL MOV AL,3FH OUT 61H C1: IN AL,60H
CALL D20MS ;去抖动 CMP AL,00H JE C1
CMP AL,0AH ;扫描键盘,是否有修改密码建(10)输入 JNE DOON ;没有则结束
C0: MOV SI,OFFSET DATA2 ;重新定义SI、DI MOV DI,OFFSET DATA3 MOV CX,06H HLT
STI ;开中断,输入修改程序 C2: MOV AL,[DI] MOV [SI],AL INC SI
INC DI
LOOP C2 ;输入密码转移到data2
IN AL,60H ;扫描键盘,若有修改密码键输入则重新修改 CALL D20MS CMP AL,0AH JE C0
C3: MOV SI,OFFSET DATA2 ;再次输入密码确认 MOV DI,OFFSET DATA3 MOV CX,06H HLT STI
REPE CMPSB
CMP CX,00 ;若data2与data3不相等则从新输入 JNE C3
MOV CX,06H ;若相等,则从DATA2写密码到RAM MOV SI,2000H
MOV DI,OFFSET DATA2 C4: MOV AL,[DI] MOV [SI],AL INC SI INC DI
LOOP C4 ;转存密码结束
CALL RING2 ;蜂鸣三次,表示修改好了
IN AL,60H ;扫描键盘,若有修改密码键输入则重新修改 CALL D20MS CMP AL,0AH JE C0
JMP DOON ;修改完毕,转到结束
中断子程序
INPUT: PUSH AX ;保护现场 PUSH DS PUSH BX PUSH CX PUSH DI PUSH SI
MOV AL,1020H ;8253开始一分钟输入限制计时 OUT 20H,AL
IN1: IN AL,60H ;读A口 CALL D20MS ;去抖动 CMP AL,10H
JE IN1 ;若无按键按下,则重新扫描
CMP AL,0AH ;若有按键按下,比较是否为复位键 JNE IN3
CALL RING1 ;为复位键则输出按键有效提示音并重新输入
MOV CX,06H
MOV DI,OFFSET DATA3 JMP IN1
IN3: CALL RING1 ;若不是复位键,则把键值送到data3 MOV [DI],AL INC DI
LOOP IN1 ;循环,扫描下一次按键,直到输入够6位密码 MOV AL,01 OUT 30,AL
POP SI ;中断结束恢复现场 POP DI POP CX POP BX POP DS POP AX
CLI IRET
DOON: MOV AH,4CH INT 21H
20ms延时子程序
D20MS PROC NEAR PUSH CX
MOV CX,0080H D1: DEC CX
LOOP D1 POP CX
RET D20MS ENDP
输入按键响应子程序
RING1 PROC NEAR PUSH AX PUSH CX
MOV CX,05H MOV AL,07H OUT 62H,AL MOV AL,40H OUT 61H,AL R1: CALL D20MS LOOP R1
MOV AL,00H OUT 62H,AL POP CX POP AX
RET ;关中断 ;中断返回 ;循环 ;返回
;保护AX\\CX ;设置提示音为0.1秒 ;输出显示“- -”字样 ;数码管灭 ;返回