;******************************************** ;********* 电子密码锁 ********* ;******************************************** ;********* 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 PS7 EQU 63H PS8 EQU 62H ;AT24C02读取缓冲区 AT1 EQU 63H AT2 EQU 62H AT3 EQU 61H AT4 EQU 60H AT5 EQU 5FH AT6 EQU 5EH AT7 EQU 5BH AT8 EQU 5AH ;按键标志位 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_ACK 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 复制代码
帮你贴出来