📄 电子锁.asm
字号:
ST_ADDR EQU 4000H
ORG ST_ADDR
LJMP MAIN
ORG ST_ADDR+03H ;ST_ADDR+03H是默认的INT0中断入口 见P92
LJMP KEY ;KEY是中断处理程序
ORG ST_ADDR+30H ;主程序从ST_ADDR+30H开始
MAIN: ACALL CLEAR ;CLEAR是设置8279显示功能及清零子程序
MOV TCON,#00H ;设置中断 见P89
SETB EA ;开总中断 见P90
SETB EX0 ;允许外部INT0中断 见P90
SETB IT0 ;设INT0中断为沿触发方式 见P89
MOV P1,#00H ;让P1口灯全灭
MOV A,#08H ;预置密码8
MOV 50H,A
MOV A,#02H ;预置密码2
MOV 51H,A
MOV A,#06H ;预置密码6
MOV 52H,A
MOV A,#03H ;预置密码3
MOV 53H,A
MOV A,#01H ;预置密码1
MOV 54H,A
MOV A,#05H ;预置密码5
MOV 55H,A
SJMP $ ;$表示当前行
;显示子程序
DISP: MOV 60H,R1 ;保存寄存器状态
MOV 61H,R3
MOV 62H,PSW
MOV 63H,A
MOV 64H,DPH
MOV 65H,DPL
ACALL SETDISP ;初始化8279显示状态字
MOV DPTR,#1B30H
MOV R3,#0FFH ;因为8279初始化需要时间,这个循环等待8279初始化完毕
DJNZ R3,$
MOV R1,4FH ;4F记录的是内部存储器中最后一个用户输入字符的地址+1,
;它可能是40H-46H中的任意一个,当它为40H时,
;表示用户已经输入了六个数程序不再处理键盘输入
GO: DEC R1 ;此时R1种存的是用户输入字符的地址
MOV A,@R1 ;把用户输入的字符传给A,准备输出
ACALL TABLE ;查表进行七段译码
MOVX @DPTR,A ;输出字符
MOV R3,#0FFH ;循环等待8279显示完毕
DJNZ R3,$
CJNE R1,#40H,LOOPGO ;当前显示的不是最先输入的字符的时候,循环显示前一个输入的字符
MOV R1,60H ;恢复寄存器状态
MOV R3,61H
MOV PSW,62H
MOV A,63H
MOV DPH,64H
MOV DPL,65H
RET
LOOPGO: AJMP GO
;键盘中断子程序
KEY: MOV DPTR,#1B30H ;从8279读入键盘状态送到A
MOVX A,@DPTR
JB ACC.4,RETURN ;当ACC.4是1时表示输入的字符是G,M,P,R,W,X,Y中的任一个,程序不作处理
ANL A,#0FH ;当输入字符是0-F中的任一个时,把高四位舍弃,只保留低四位
ACALL TABLE1 ;查表,根据键盘编码,决定用户输入的是0-F中的哪一个
CJNE A,#0AH,CHECKB ;当用户输入A时,进行用户输入密码和预置密码的比较
ACALL COMPARE ;调比较函数
AJMP RETURN
CHECKB: CJNE A,#0BH,CHECKC
ACALL INITT ;当用户输入B时,为显示器清零,并作内存初始化
AJMP RETURN
CHECKC: CJNE A,#0CH,CHECKD
ACALL INITT ;当用户输入C时,为显示器清零,并作内存初始化
AJMP RETURN
CHECKD: CJNE A,#0DH,CHECKE
ACALL INITT ;当用户输入D时,为显示器清零,并作内存初始化
AJMP RETURN
CHECKE: CJNE A,#0EH,CHECKF
ACALL INITT ;当用户输入E时,为显示器清零,并作内存初始化
AJMP RETURN
CHECKF: CJNE A,#0FH,KEYNUM
ACALL INITT ;当用户输入F时,为显示器清零,并作内存初始化
AJMP RETURN
KEYNUM: MOV R1,4FH ;如果用户输入已经达到六个字符,则程序不再响应新输入的数字
CJNE R1,#46H,KEYOK
AJMP RETURN
KEYOK: MOV @R1,A ;当一切条件均符合要求时,显示新输入的数字
INC R1
MOV 4FH,R1
ACALL DISP
RETURN: RETI
;用户输入与预置密码比较函数
COMPARE:MOV 70H,R0 ;保存寄存器状态
MOV 71H,R1
MOV 72H,R2
MOV 73H,R3
MOV 74H,A
MOV 75H,PSW
MOV 76H,DPH
MOV 77H,DPL
MOV R3,#06H ;六位密码,共进行六次循环
MOV R0,#50H
MOV R1,#40H
CMPASS: MOV A,@R0 ;单个字符进行比较
MOV R2,A ;R2里存的是预置密码
MOV A,@R1 ;A里存的是用户输入密码
SUBB A,R2 ;两个字符相减,结果存入A
JNZ ERROR ;A不为零时,跳转到错误处理程序
INC R0 ;让R0指向预置密码的下一位
INC R1 ;让R1指向用户输入密码的下一位
DJNZ R3,CMPASS ;没有比够六次时循环比较下一位
SETB P1.0 ;当用户输入密码与预置密码相同时,点亮灯
SJMP RESTORE
ERROR: ACALL CLEAR
RESTORE:MOV R0,70H ;恢复寄存器状态
MOV R1,71H
MOV R2,72H
MOV R3,73H
MOV A,74H
MOV PSW,75H
MOV DPH,76H
MOV DPL,77H
RET
;为显示器清零,并作内存初始化函数
INITT: MOV P1,#00H ;清P1口,让灯全灭
MOV 78H,R3 ;保存寄存器状态
MOV 79H,A
MOV 7AH,PSW
MOV 7BH,DPH
MOV 7CH,DPL
ACALL CLEAR ;清显示器并初始化内存
MOV R3,78H ;恢复寄存器状态
MOV A,79H
MOV PSW,7AH
MOV DPH,7BH
MOV DPL,7CH
RET
;延时子程序
TIME: MOV R5,#0C8H
DEL1: MOV R4,#7EH
DEL2: DJNZ R4,DEL2
DJNZ R5,DEL1
DJNZ R3,TIME
RET
;初始化8279显示状态字
SETDISP:MOV DPTR,#1B31H
MOV A,#0D3H ;清除显示 P180
MOVX @DPTR,A
MOV A,#2AH ;设定扫描频率为1MHz P180
MOVX @DPTR,A
MOV A,#00H ;设置键盘,显示器方式 八个字符显示,从左端进入,编码扫描键盘 P179
MOVX @DPTR,A
MOV A,#90H ;设置每次写入显示RAM后,地址自增1 P180
MOVX @DPTR,A
RET
;为6个显示器清零,并初始化内存
CLEAR: ACALL SETDISP
MOV DPTR,#1B30H
MOV R3,#0FFH
DJNZ R3,$
MOV A,#3FH
MOVX @DPTR,A
MOVX @DPTR,A
MOVX @DPTR,A
MOVX @DPTR,A
MOVX @DPTR,A
MOVX @DPTR,A
MOV 4FH,#40H
MOV 40H,#00H
MOV 41H,#00H
MOV 42H,#00H
MOV 43H,#00H
MOV 44H,#00H
MOV 45H,#00H
RET
;把从8279读入的键盘编码,转化成实际的数值
TABLE1: INC A
MOVC A,@A+PC
RET
DB 08H,09H,0AH,0BH,0CH,0DH
DB 0EH,0FH,00H,01H,02H,03H
DB 04H,05H,06H,07H
;把实际的数值转化成七段译码
TABLE: INC A
MOVC A,@A+PC
RET
DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH
DB 77H,7CH,39H,5EH,79H,71H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -