;********************************************
;********* 电子密码锁 *********
;********************************************
;********* 2005/12/24 *********
;********************************************
;显示缓冲区
;LED1 EQU 6FH
BUFF EQU 6EH
TIMERS1 EQU 6DH ;输入回车的次数
TIMERS2 EQU 6CH ;报警的次数
TIMERS EQU 6BH ;输入数字的位数
;LED6 EQU 6AH
;密码缓冲区
PS1 EQU 69H
PS2 EQU 68H
PS3 EQU 67H
PS4 EQU 66H
PS5 EQU 65H
PS6 EQU 64H
;AT24C02读取缓冲区
AT1 EQU 63H
AT2 EQU 62H
AT3 EQU 61H
AT4 EQU 60H
AT5 EQU 5FH
AT6 EQU 5EH
;按键标志位
F_1 BIT 20H
F_2 BIT 21H
F_3 BIT 22H
F_4 BIT 23H
BUF_FULL BIT 24H ;密码已经够六位的标志位,为1表示满
CH_STATE BIT 25H ;系统更改的状态标志位,为1表示busy
FLAG1 BIT 26H ;功能键标志位,为1表示功能按键。
F_F1 BIT 27H
F_F2 BIT 28H
PSW_F BIT 29H ;密码是否正确的标志位
;口资源定义
SPK BIT P2.1
JDQ BIT P2.3
SDA BIT P2.4 ;定义串口数据端
SCL BIT P2.5
;发光二极管灯
L1 BIT P1.0
L2 BIT P1.1
L3 BIT P1.2
;
ORG 0000H
AJMP MAIN
ORG 000BH
;AJMP TIMER0
ORG 001BH
;AJMP TIMER1
ORG 0030H
MAIN:MOV SP, #70H
MOV TMOD, #11H
MOV TH0, #3CH
MOV TL0, #0B0H
MOV TH1, #3CH
MOV TL1, #0B0H
CLR F_1 ;清除标志位
CLR F_2
CLR F_3
CLR F_4
CLR BUF_FULL
CLR CH_STATE
CLR FLAG1
CLR F_F1
CLR F_F2
CLR PSW_F
MOV BUFF,#00H ;调用
LCALL INITPS ;初始化环境
LCALL INITAT
LCALL XSA ;调用默认显示
MOV TIMERS1,#00H
NOP
MOV PS1, #11H ;初始化密码830620
MOV PS2, #0AH
MOV PS3, #02H
MOV PS4, #13H
MOV PS5, #0BH
MOV PS6, #02H
START:NOP ;程序开始
LCALL CH_KEY ;检查键盘
AJMP START ;返回
CH_KEY:LCALL KS ;检查有没有按键按下
JNZ LK1
AJMP CH_KEY
LK1:
LCALL T12MS
ACALL KS
JNZ LK2
RET
LK2:
NOP
LCALL SBIE ;按键识别子程序
MOV BUFF, A ;送缓冲区以识别是数字键还是功能键?
LCALL CH_KF ;判断按键功能。
JB FLAG1 ,KEY_FUN ;标志为1,则为功能键
;***********数字按键输入并且存放到缓冲区内等待比较***********
KEY_DIG:NOP ;设一标志,辨别输入是否满
;SETB TR0
INC TIMERS ;输入数字的位数
MOV A, TIMERS
CLR C
SUBB A, #01H
JNZ PS_2
MOV PS1, BUFF ;依照顺序存放密码
AJMP NEXT
PS_2:MOV A, TIMERS
SUBB A, #02H
CLR C
JNZ PS_3
MOV PS2, BUFF
AJMP NEXT
PS_3:MOV A, TIMERS
CLR C
SUBB A, #03H
JNZ PS_4
MOV PS3, BUFF
AJMP NEXT
PS_4:MOV A, TIMERS
CLR C
SUBB A, #04
JNZ PS_5
MOV PS4, BUFF
AJMP NEXT
PS_5:MOV A, TIMERS
CLR C
SUBB A, #05
JNZ PS_6
MOV PS5, BUFF
AJMP NEXT
PS_6:MOV A, TIMERS
CLR C
SUBB A, #06H
JNZ CH_KEY
MOV PS6, BUFF
NEXT:LCALL XSC
MOV R7, TIMERS ;比较输入的次数。
CJNE R7, #06H ,FULL
FULL:JC NEXT9
SETB BUF_FULL
MOV TIMERS,#06H
CLR L3
NOP
CLR P2.1
LCALL T100MSD
SETB P2.1
NOP
AJMP CH_KEY
NEXT9:CLR P2.1 ;密码输入一位,鸣叫一声。
CLR L3
LCALL T100MSD ;延时100ms
SETB L3
SETB P2.1
AJMP CH_KEY
;*****************功能按键比较并且跳转*************
KEY_FUN:
CLR FLAG1
CLR C
MOV A, BUFF
SUBB A, #03H ;按键CL跳转
JNZ EN_C
AJMP CL
EN_C:CLR C
MOV A, BUFF ;按键EN跳转
SUBB A, #00H
JNZ F1_C
AJMP EN
F1_C:CLR C
MOV A, BUFF
SUBB A, #1BH
JNZ F2_C
AJMP FU1
F2_C:CLR C
MOV A, BUFF
SUBB A, #1AH
JNZ F3_C
AJMP FU2
F3_C:CLR C
MOV A, BUFF
SUBB A, #19H
JNZ F4_C
AJMP FU3
F4_C:CLR C
MOV A, BUFF
SUBB A, #18H
JZ FU4
EXIT8:NOP
LJMP CH_KEY
;***************开门子程序 ********************************
CL:NOP
SETB L3
MOV BUFF, #00H ;消密码缓冲
MOV TIMERS,#00H
LCALL INITPS ;消除AT缓冲,加调电存储后一定要加上
LCALL XSC
LCALL BP
LCALL BP
LCALL T100MSD
LCALL BP
CLR FLAG1
AJMP CH_KEY
FU4:NOP
LCALL BP
LCALL T100MSD
LCALL BP
LCALL T100MSD
LCALL BP
LCALL T100MSD
LCALL BP
LCALL T100MSD
LCALL BP
CLR FLAG1
AJMP CH_KEY
FU3:NOP
LCALL BP
LCALL T100MSD
LCALL BP
LCALL KILLXS ;关闭显示
CLR FLAG1
AJMP CH_KEY
FU1:NOP
LCALL XSC
JB F_F1, NEXT_F1
CLR L1
LCALL BP
SETB F_F1
AJMP CH_KEY
NEXT_F1:SETB L1
LCALL BP
CLR F_F1
;LCALL CH_STATE ;查看现在的状态以防误按
;SETB TR1 ;报警限制暂时不开
;INC F_F1
CLR FLAG1
AJMP CH_KEY
FU2:NOP
JB F_F2, NEXT_F2
CLR L2
LCALL BP
SETB F_F2
AJMP CH_KEY
NEXT_F2:SETB L2
LCALL BP
CLR F_F2
CLR FLAG1
AJMP CH_KEY
;***************按键的功能描述*************************
EN:NOP
JB BUF_FULL, GOON
AJMP EXIT
GOON:CLR BUF_FULL
JB F_F2, AT_WRON ;F2按键标志,若为1,则调用修改密码子程序。
LCALL AT_RADE
LCALL C_PSW ;比较密码子程序
JB PSW_F,OPEN ;密码比较正确,则调用开锁子程序
LCALL XSD
INC TIMERS2
MOV R7,TIMERS2 ;密码错误,调入输入密码输入次数,准备锁定键盘
CJNE R7,#03H,D0
D0:JC NEXT1 ;错误次数小3次
LCALL XSE ;锁定5分钟
LCALL WARN2S
LCALL LOCK_1M
NEXT1:LCALL WARN2S ;报警2分钟
LCALL XSA
EXIT:LCALL INITPS
MOV BUFF, #00H
CLR FLAG1
MOV TIMERS, #00H
AJMP CH_KEY ;跳出
AT_WRON:LCALL AT_WR
LCALL XSF
LCALL BP
LCALL T100MSD
LCALL BP
LCALL T500MSD
LCALL KILLXS
LCALL T500MSD
LCALL XSF
LCALL T500MSD
LCALL KILLXS
LCALL T500MSD
LCALL XSF
LCALL T500MSD
NOP
NOP
LCALL XSA
AJMP EXIT
OPEN:MOV A, TIMERS1
CJNE A, #09H,CLT1
CLT1:JC GOON1
MOV TIMERS1,#00H
GOON1:INC TIMERS1 ;输入回车的次数
MOV TIMERS2,#00H
SETB L3
CLR PSW_F
LCALL XSB
CLR JDQ ;开门
LCALL BP
LCALL BP
LCALL BP
LCALL BP
LCALL SEC
LCALL SEC
LCALL SEC
LCALL SEC
LCALL SEC
LCALL SEC
LCALL SEC
LCALL SEC
SETB JDQ
LCALL XSA
NOP
AJMP EXIT
;**************各类子程序********************************
;**** 注意清楚缓冲区时AT1...AT6不应在初始化中执行,以 ***
;**** 防两缓冲区都为0,相同开锁 ***
;********************************************************
CLR_BUF:MOV R7, #06H
MOV R0, #6FH
LOOP1:MOV A, #00H
MOV @R0, A
DEC R0
DJNZ R7,LOOP1
RET
;*************初始化显示缓冲区以及其他缓冲区**************
INITPS:PUSH ACC
PUSH PSW
MOV R7, #06H
MOV R1, #PS1
MOV A, #00H
INIT_PS:MOV @R1, A
DEC R1
DJNZ R7, INIT_PS
POP PSW
POP ACC
NOP
RET
INITAT:PUSH ACC
PUSH PSW
MOV R7,#06H
MOV R1,#AT1
MOV A, #00H
INIT_AT:MOV @R1, A
DEC R1
DJNZ R7, INIT_AT
MOV TIMERS,#00H ;密码输入的次数清零。
POP PSW
POP ACC
RET
;************* 按键识别子程序 ***************************
SBIE:MOV R2, #0EFH ;识别按键子程序,数据送A保存,课本P146页。
MOV R4, #00H
LK4:MOV A, R2
MOV P0, A
NOP
MOV A, P0
JB ACC.0,LONE
MOV A, #00H
AJMP LKP
LONE:JB ACC.1,LTWO
MOV A, #08H
AJMP LKP
LTWO:JB ACC.2,LTHR
MOV A, #10H
AJMP LKP
LTHR:JB ACC.3,NEXTT ;判断下一列
MOV A, #18H
LKP:ADD A, R4
PUSH ACC
LK3:ACALL KS
JNZ LK3
POP ACC
RET
NEXTT:INC R4
MOV A, R2
JNB ACC.7,KND
RL A
MOV R2, A
AJMP LK4
KND:AJMP CH_KEY
KS:MOV P0, #0FH
NOP
MOV A, P0
CPL A
ANL A, #0FH
NOP
RET
CH_KF:CLR C
MOV A, BUFF ;判断是数字按键还是功能按键,为1表示功能键
CJNE A, #17H, KY
KY:JC SET_CH ;假若是数字按键则标志置为0
SETB FLAG1 ;假若是功能按键则标志置为1
AJMP CHKE_END
SET_CH:CLR C
MOV A, BUFF
SUBB A, #00H
JNZ EN_CH
SETB FLAG1
AJMP CH_END
EN_CH:MOV A, BUFF
SUBB A, #03H
JNZ DIG
SETB FLAG1
AJMP CH_END
DIG:CLR FLAG1
CH_END:NOP
CHKE_END:RET
T12MS:MOV R7, #18H
TM1:MOV R6, #0FFH
TM66:DJNZ R6, TM66
DJNZ R7, TM1
RET
;****************检验密码正误******************************
C_PSW:PUSH PSW
PUSH ACC
MOV R2,#06H
MOV R0,#PS1
MOV R1,#AT1
C_P:CLR C
MOV A,@R0
SUBB A,@R1
JNZ RETURN
DEC R0
DEC R1
DJNZ R2,C_P
NOP
SETB PSW_F
AJMP EXIT7
RETURN:CLR PSW_F
EXIT7:NOP
POP ACC
POP PSW
RET
;×××××××××××××××××锁定,鸣笛子程序××××××××××××
LOCK_1M:MOV R4,#3CH ;锁定1分钟
M1_LOOP:LCALL SEC
DJNZ R4,M1_LOOP
NOP
RET
WARN2S:PUSH PSW
PUSH ACC
MOV R5, #14H ;调用20次BP,报警2s
WARN:LCALL BP
DJNZ R5,WARN
NOP
POP ACC
POP PSW
NOP
RET
BP:CLR SPK ;鸣笛子程序
LCALL T100MSD
SETB SPK
NOP
RET
;***************************
;***** 显示子程序 ********
;***************************
;功能:分五屏幕显示数据,分别是XSA,XSB,XSC,XSD,XSE.代表六种状态。
;锁定状态显示。
XSA:PUSH ACC
PUSH PSW
MOV A, TIMERS1
MOV DPTR, #TAB
MOVC A, @A+DPTR
MOV SBUF, A ;送已经输入密码的次数
JNB TI, $
CLR TI
MOV SBUF, #0FEH ;送短线
JNB TI, $
CLR TI
MOV SBUF, #0FEH ;送短线
JNB TI, $
CLR TI ;送F
MOV SBUF, #78H
JNB TI, $
CLR TI
MOV SBUF, #78H
JNB TI, $
CLR TI
MOV SBUF, #11H
JNB TI, $
CLR TI
POP PSW
POP ACC
RET
;成功开锁状态显示
XSB:PUSH ACC
PUSH PSW
MOV A, TIMERS1
MOV DPTR, #TAB
MOVC A, @A+DPTR
MOV SBUF, A
JNB TI, $
CLR TI
MOV SBUF, #0FEH
JNB TI, $
CLR TI
MOV SBUF, #0FEH
JNB TI, $
CLR TI
MOV SBUF, #10H
JNB TI, $
CLR TI
MOV SBUF, #10H
JNB TI, $
CLR TI
MOV SBUF, #10H
JNB TI, $
CLR TI
POP PSW
POP ACC
RET
;密码输入及修改状态
XSC:PUSH ACC
PUSH PSW
LCALL KILLXS
SETB RS1 ;切换到第三组寄存器。防止操作数读取错误。
MOV R6, TIMERS
MOV A, R6
SUBB A, #01H
JNC SC0
JZ SC1
SC0:MOV SBUF, #0FEH
JNB TI, $
CLR TI
SC1:MOV A, R6
SUBB A, #02H
JNC SC11
JNZ SC2
SC11:MOV SBUF,#0FEH
JNB TI, $
CLR TI
SC2:MOV A, R6
SUBB A, #03H
JNC SC22
JNZ SC3
SC22:MOV SBUF, #0FEH
JNB TI, $
CLR TI
SC3:MOV A, R6
SUBB A, #04H
JNC SC33
JNZ SC4
SC33:MOV SBUF, #0FEH
JNB TI, $
CLR TI
SC4:MOV A, R6
SUBB A, #05H
JNC SC44
JNZ SC5
SC44:MOV SBUF, #0FEH
JNB TI, $
CLR TI
SC5:MOV A, R6
SUBB A, #06H
JNC SC55
JNZ SC6
SC55:MOV SBUF, #0FEH
JNB TI, $
CLR TI
SC6:MOV A, R6
SUBB A, #07H
JNC SC66
JNZ EXIT_C
SC66:MOV SBUF, #0FEH
JNB TI, $
CLR TI
NOP
NOP
EXIT_C:NOP
CLR RS1
POP PSW
POP ACC
NOP
RET
;密码输入错误的提示
XSD:PUSH ACC
PUSH PSW
MOV SBUF, #98H
JNB TI, $
CLR TI
MOV SBUF, #79H
JNB TI, $
CLR TI
MOV SBUF, #11H
JNB TI, $
CLR TI
MOV SBUF, #79H
JNB TI, $
CLR TI
MOV SBUF, #79H
JNB TI, $
CLR TI
MOV SBUF, #38H
JNB TI, $
CLR TI
POP PSW
POP ACC
RET
;锁定状态显示
XSE:PUSH ACC
PUSH PSW
MOV SBUF, #0FEH
JNB TI, $
CLR TI
MOV SBUF, #54H
JNB TI, $
CLR TI
MOV SBUF, #39H
JNB TI, $
CLR TI
MOV SBUF, #11H
JNB TI, $
CLR TI
MOV SBUF, #3DH
JNB TI, $
CLR TI
MOV SBUF, #0FEH
JNB TI, $
CLR TI
POP PSW
POP ACC
RET
XSF:PUSH ACC
PUSH PSW
MOV SBUF, #98H
JNB TI, $
CLR TI
MOV SBUF, #38H
JNB TI, $
CLR TI
MOV SBUF, #39H
JNB TI, $
CLR TI
MOV SBUF, #39H
JNB TI, $
CLR TI
MOV SBUF, #3DH ;U
JNB TI, $
CLR TI
MOV SBUF, #98H
JNB TI, $
CLR TI
POP PSW
POP ACC
RET
KILLXS:PUSH ACC
PUSH PSW
MOV R7, #06H
LOOP_XS:MOV SBUF, #0FFH
JNB TI, $
CLR TI
DJNZ R7,LOOP_XS
NOP
POP PSW
POP ACC
RET
TAB: DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D1H,10H,90H ,0FFH
;****************************************************************
;******* 24C02读写程序 ×××××××
;****************************************************************
AT_RADE:PUSH PSW
PUSH ACC
MOV R0,#AT1 ;CPU首地址
MOV R6,#06H ;8字节
MOV R5,#08H ;8位
MOV R7,#00H ;24C02首地址
LCALL READ ;读数据
NOP
NOP
POP ACC
POP PSW
RET
AT_WR:
PUSH PSW
PUSH ACC
MOV R0,#PS1 ;CPU RAM首地址
MOV R6,#06H ;8字节
MOV R5,#08H ;8 BIT
MOV R7,#00H ;24C02 RAM 首地址
LCALL WRT ;先写进
NOP
NOP
POP ACC
POP PSW
RET
;---------------------
;读串行器件 R0:RAM的起始地址,R5:位计数器,
;R6:读的字节数,R7:读的起始地址
READ: NOP
NOP
LCALL START0
MOV A,#0A0H
LCALL WRB
LCALL ACK
JB F0,RD_FAIL
MOV A,R7
LCALL WRB
LCALL CHK
JB F0,RD_FAIL
LCALL START0
MOV A,#0A1H
LCALL WRB
LCALL CHK
JB F0,RD_FAIL
RD_N: NOP
NOP
LCALL RDB
MOV @R0,A
DJNZ R6,GO_A, CK
LCALL N_ACK
RD_FAIL:NOP
LCALL STOP
MOV A,#0FFH
RET;*************read
GO_ACK: NOP
NOP
DEC R0
LCALL ACK
JMP RD_N
;写串行器件 R0:RAM的起始地址,R5:位计数器,
;R6:写的字节数(页),R7:写的起始地址
WRT: NOP
NOP
LCALL START0
MOV A,#0A0H
LCALL WRBYT
LCALL CHK
JB F0,WR_FAIL
MOV A,R7
LCALL WRBYT
LCALL CHK
JB F0,WR_FAIL
WR_N: NOP
NOP
MOV A,@R0
LCALL WRBYT
LCALL CHK
JB F0,WR_FAIL
DEC R0
DJNZ R6,WR_N
WR_FAIL:NOP
LCALL STOP
MOV A,#0FFH
RET;*********wrt
;--------------------
START0: NOP
NOP
SETB SDA
SETB SCL
NOP
NOP
CLR SDA
NOP
NOP
CLR SCL
NOP
RET
;-------------------
STOP: NOP
NOP
CLR SDA
SETB SCL
NOP
NOP
SETB SDA
NOP
NOP
CLR SCL
NOP
RET
;--------------------
ACK: NOP
NOP
CLR SDA
SETB SCL
NOP
NOP
CLR SCL
SETB SDA
NOP
RET
;--------------------
N_ACK: NOP
NOP
SETB SDA
SETB SCL
NOP
NOP
CLR SCL
CLR SDA
NOP
RET
;--------------------
CHK: NOP
NOP
SETB SDA
NOP
NOP
SETB SCL
NOP
NOP
MOV C,SDA
MOV F0,C
CLR SCL
NOP
NOP
RET
;---------------------
RDB: NOP
NOP
SETB SDA
MOV R5,#8
RD_B: NOP
NOP
CLR SCL
NOP
NOP
SETB SCL
NOP
NOP
MOV C,SDA
RLC A
NOP
NOP
SETB SDA
CLR SCL
DJNZ R5,RD_B
NOP
RET
;一字节数据发送子程序
WRBYT: MOV R5,#8
WLP: RLC A
JC WR1
CLR SDA
SETB SCL
NOP
NOP
CLR SCL
DJNZ R5,WLP
RET
WR1: SETB SDA
SETB SCL
NOP
NOP
CLR SCL
CLR SDA
DJNZ R5,WLP
RET
;--------------------
WRB: NOP
NOP
MOV R5,#8
WR_B: NOP
NOP
SETB SDA
RLC A
JC WR_1
CLR SDA
NOP
WR_1: SETB SCL
NOP
NOP
CLR SCL
NOP
CLR SDA
NOP
DJNZ R5,WR_B
NOP
RET
;***********************************************************************************************
;************* 毫秒延时程序 ********************************************
;***********************************************************************************************
T10MSD:SETB RS0
MOV R4, #12
TM:MOV R3, #128
TM6:DJNZ R3, TM6
DJNZ R4, TM
CLR RS0
RET
T100MSD:MOV R3, #200
D11:MOV R4, #125
D12:DJNZ R4, D12
DJNZ R3, D11
RET
T500MSD:LCALL T100MSD
LCALL T100MSD
LCALL T100MSD
LCALL T100MSD
LCALL T100MSD
NOP
RET
SEC:SETB RS1
MOV R7, #0AH
SEC_LP:LCALL T100MSD
DJNZ R7,SEC_LP
NOP
CLR RS1
RET
END