数字密码锁程序
基于单片机控制的数字密码锁
总电路图:
程序:
;=====================定义
=============================
LED_ON BIT 00H;数码管亮暗标志(1为亮,0为暗) KEYCARD BIT 01H;按键标志
PWD_RIGHT BIT 02H;密码是否正确(1 为正确,0为错误) KEY_LOCK BIT 03H;键盘锁定(1为锁,0为开) SOND BIT P1.4;蜂鸣器
GREEN BIT P1.5;绿灯
RED BIT P1.6;红灯
LED1 EQU 50H;数码管自动变暗时间数1 KEYS EQU 53H;按键键值
KEY1 EQU 54H;按键行值
PWD1 EQU 56H;存密码1
PWD2 EQU 57H;存密码2
PWD3 EQU 58H;存密码3
PWD4 EQU 59H;存密码4
SHOW1 EQU 5AH;显示1
SHOW2 EQU 5BH;显示2
SHOW3 EQU 5CH;显示3
SHOW4 EQU 5DH;显示4
SHOW0 EQU 5EH;临时用
;====================程序开始==============================
ORG 0000H
AJMP INIT ;=====================初始化===============================
ORG 0030H INIT:
MOV P0, #40H
MOV P2, #0FH
MOV P3, #00H
MOV LED1, #3FH
MOV KEYS, #00H
MOV KEY1, #00H
MOV SHOW0,#00H
MOV SHOW1,#00H
MOV SHOW2,#10H
MOV SHOW3,#20H
MOV SHOW4,#30H
LCALL PWD_INIT
SETB LED_ON
CLR PWD_RIGHT
SETB SOND
SETB RED
SETB GREEN
CLR KEY_LOCK
CLR KEYCARD
AJMP MAIN
;===========================================================主程序=====
=================================================
MAIN:
MOV P2,#0FH
MOV P3,#00H
LCALL KEY_FIRST ;调用键盘程序
JNB KEYCARD,MAIN ;KEYCARD=0时,无键按下跳回MAIN
LCALL KEY_MAIN ;KEYCARD=0时,调用键盘处理程序
JNB KEYCARD,MAIN
LJMP MKEY_FUNCTION ;跳到主程序键盘各按键处理程序 ;============================================================END=====
===================================================
;=====================检测按键第一次按下========================
KEY_FIRST:
JNB LED_ON,KEY_LOOP
MOV A, P2 ;数码管亮时扫描
ANL A, #0FH ;屏敝掉高4位
CJNE A, #0FH,KEY_SECOND ;判断是否有键按下
CLR KEYCARD ;无键则KEYCARD置0
LCALL LED_DISPLAY ;调用显示子程序
DJNZ LED1, ESC
CLR LED_ON
MOV LED1, #03FH
ESC:
RET
KEY_LOOP: ;数码管暗时扫描
MOV A, P2
ANL A, #0FH
CJNE A, #0FH,KEY_SECOND
CLR KEYCARD
RET
;=======================检测按键第二次按下=================
KEY_SECOND:
LCALL BEEP1 ;按键响声
JNB LED_ON,KEY_EXIT1 ;如果LED是暗的,则置LED_ON为1
MOV LED1, #03FH
LCALL DELAY10MS ;去抖,延时10ms
MOV A, P2 ;重新扫描键盘
ANL A, #0FH
CJNE A, #0FH,KEY_EN ;有键按下,则置KEYCARD为1
CLR KEYCARD ;无键按下,则置KEYCARD为0
RET
KEY_EXIT1:
LCALL KEY_RELEASE
SETB LED_ON
RET
KEY_EN:
SETB KEYCARD ;置KEYCARD为1
RET
;===============================================KEY_MAIN=============
====================================
KEY_MAIN:
MOV R3,#0EH
MOV R4,#04H ;循环次数
KEY_ROW:
MOV P3,R3
MOV A,P2
ANL A,#0FH
MOV KEY1,R3 ;将行信息存到KEY1中
CJNE A,#0FH,KEY_WORD ;是该行则跳到键值计算程序
MOV A,R3
SETB C
RLC A ;带进位循环左移
ANL A,#0FH
MOV R3,A
DJNZ R4, KEY_ROW
CLR KEYCARD
RET
;================键值计算========================
KEY_WORD:
SWAP A
ORL A,KEY1 ;列,行,键值
MOV KEYS,A ;键值存到KEYS中
RET
;==================================主程序各按键功能=====================
================== MKEY_FUNCTION:
MOV KEYS,A ;键值赋给A
MK0:
CJNE A,#0EEH,MK1
CLR KEYCARD
MOV SHOW1,#0BH
MOV SHOW2,#1BH
MOV SHOW3,#2BH
MOV SHOW4,#3BH
LCALL KEY_RELEASE ;按键松开程序
MOV R5,#05H
MOV R6,#03H
CLR KEY_LOCK
LOGIN_MAIN: ;输入密码主程序
MOV P2, #0FH
MOV P3, #00H
LCALL KEY_FIRST ;调用键盘扫描程序
JNB KEYCARD,LOGIN_MAIN
LCALL KEY_MAIN ;调用键盘处理程序
LJMP LKEY_FUNCTION ;跳到输密码时各键功能处理程序 MK1:
LCALL KEY_RELEASE
LJMP MAIN
;========,,,,,,,,=========================END==================
==================
;==========================出厂密码============================
PWD_INIT:
MOV PWD1, #01H
MOV PWD2, #02H
MOV PWD3, #03H
MOV PWD4, #04H
RET
;======================================输入密码时各按键功能=============
======================= LKEY_FUNCTION:
MOV A,KEYS
;=================无效键============================
LK0:
CJNE A,#0EEH,LK1
LCALL LAMP_RED ;闪红灯
LCALL KEY_RELEASE
LJMP LOGIN_MAIN ;返回输入密码主程序 LK1:
CJNE A,#0EDH,LK2
LCALL LAMP_RED
LCALL KEY_RELEASE
LJMP LOGIN_MAIN LK2:
CJNE A,#0EBH,LK3
LCALL LAMP_RED
LCALL KEY_RELEASE
LJMP LOGIN_MAIN ;=================退出键==================
LK3:
CJNE A,#0E7H,LK4
MOV SHOW1,#00H
MOV SHOW2,#10H
MOV SHOW3,#20H
MOV SHOW4,#30H
CLR KEY_LOCK
LJMP MAIN ;返回主程序
;===============清除键=========================
LK4:
CJNE A,#07BH,LK5
MOV SHOW1,#0BH
MOV SHOW2,#1BH
MOV SHOW3,#2BH
MOV SHOW4,#3BH
MOV R5, #05H
LCALL KEY_RELEASE
LJMP LOGIN_MAIN ;================确定键=========================
LK5:
CJNE A,#077H,LK6
LCALL PWD_COMPARE ;调用密码检测子程序
LCALL KEY_RELEASE
JB PWD_RIGHT,SYS_LOGIN ;PWD_RIGHT为1时表示密码正确,跳到SYS_LOGI
N
DJNZ R6,LK5_EXIT ;否则将输入次数R6减1
INC R6 ;若输入次数已经是3次了,就保持R6为1
SETB KEY_LOCK ;置KEY_LOCK为1 LK5_EXIT:
MOV SHOW1,#0BH
MOV SHOW2,#1BH
MOV SHOW3,#2BH
MOV SHOW4,#3BH
MOV R5, #05H
LK5_ESC:
LCALL KEY_RELEASE
LJMP LOGIN_MAIN ;返回输入密码主程序 ;=============0-9数字键========================
LK6:
MOV R0,#00H
JB KEY_LOCK,LK6_EXIT ;置KEY_LOCK为1时锁定数字键
DJNZ R5,LKEY_NUM ;输入个数满4个则锁定数字键,否则R5减1
INC R5 ;若输入个数已经是4个了,就保持R5为1 LK6_EXIT:
LCALL BEEP2 ;误操作键盘发声
AJMP LK6_ESC
LKEY_NUM:
MOV A,R0
INC R0
MOV DPTR,#KEY_VALUE
MOVC A,@A+DPTR
CJNE A,KEYS,LKEY_NUM
DEC R0
MOV A,R0
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV KEYS,A
ORL A,#30H
MOV SHOW0,A
LCALL LED_MOVE ;调用左移功能
MOV SHOW4,SHOW0 LK6_ESC:
ACALL KEY_RELEASE
LJMP LOGIN_MAIN
;=======================================END==========================
======================= ;================================登陆系统==============================
==========
SYS_LOGIN:
MOV SHOW1,#01H
MOV SHOW2,#11H
MOV SHOW3,#21H
MOV SHOW4,#31H
CLR GREEN ;绿灯亮表示开锁成功 SYS_MAIN: ;开锁状态主程序
MOV P2, #0FH
MOV P3, #00H
LCALL KEY_FIRST ;调用键盘扫描程序
JNB KEYCARD,SYS_MAIN
LCALL KEY_MAIN ;调用键盘处理程序
LJMP SYSKEY_FUNCTION ;==================================登陆系统后各键功能===================
================
SYSKEY_FUNCTION:
MOV A,KEYS
;================修改密码键===============
SYSK1:
CJNE A,#0EDH,SYSK2 SET_PWD:
MOV R5,#05H
CLR KEY_LOCK
MOV SHOW1,#0AH
MOV SHOW2,#1AH
MOV SHOW3,#2AH
MOV SHOW4,#3AH SETPWD_MAIN: ;修改密码主程序
MOV P2, #0FH
MOV P3, #00H
LCALL KEY_FIRST ;调用键盘扫描程序
JNB KEYCARD,SETPWD_MAIN
LCALL KEY_MAIN ;调用键盘处理程序
LJMP SKEY_FUNCTION ;================恢复出厂设置=========== SYSK2:
CJNE A,#0EBH,SYSK3
LCALL PWD_INIT
LCALL KEY_RELEASE
LJMP SYS_MAIN ;=================退出键==================
SYSK3:
CJNE A,#0E7H,SYSK4
MOV SHOW1,#00H
MOV SHOW2,#10H
MOV SHOW3,#20H
MOV SHOW4,#30H
CLR KEY_LOCK
SETB GREEN ;关绿灯
LJMP MAIN ;跳回主程序
;==================无效键==================
SYSK4:
LCALL BEEP2
LCALL KEY_RELEASE
LJMP SYS_MAIN ;==================================END===============================
=================== ;=================================修改密码各键功能======================
==================== SKEY_FUNCTION:
MOV A,KEYS
;=================无效键=====================
SK0:
CJNE A,#0EEH,SK1
LCALL LAMP_RED
LCALL KEY_RELEASE
LJMP SETPWD_MAIN SK1:
CJNE A,#0EDH,SK2
LCALL LAMP_RED
LCALL KEY_RELEASE
LJMP SETPWD_MAIN SK2:
CJNE A,#0EBH,SK3
LCALL LAMP_RED
LCALL KEY_RELEASE
LJMP SETPWD_MAIN
;=================退出修改密码================ SK3:
CJNE A,#0E7H,SK4
MOV SHOW1,#01H
MOV SHOW2,#11H
MOV SHOW3,#21H
MOV SHOW4,#31H
LCALL KEY_RELEASE
LJMP SYS_MAIN
;==================清除键=====================
SK4:
CJNE A,#07BH,SK5
MOV SHOW1,#0AH
MOV SHOW2,#1AH
MOV SHOW3,#2AH
MOV SHOW4,#3AH
MOV R5,#05H
LCALL KEY_RELEASE
LJMP SETPWD_MAIN
;=================确认键======================
SK5:
CJNE A,#077H,SK6
LCALL KEY_RELEASE
CJNE R5,#01H,SETPWD_FAIL ;当输入个数小于4个,则密码修改不成功
LCALL SETPWD_SUCCESS ;成功调用SETPWD_SUCCESS
LJMP SYS_MAIN
;================0-9数字键================= SK6:
MOV R0,#00H
DJNZ R5,SKEY_NUM
INC R5
LCALL BEEP2
AJMP SK6_ESC
SKEY_NUM:
MOV A,R0
INC R0
MOV DPTR,#KEY_VALUE
MOVC A,@A+DPTR
CJNE A,KEYS,SKEY_NUM
DEC R0
MOV A,R0
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV KEYS,A
ORL A,#30H
MOV SHOW0,A
LCALL LED_MOVE
MOV SHOW4,SHOW0 SK6_ESC:
ACALL KEY_RELEASE
LJMP SETPWD_MAIN
;===========================================END======================
======================= ;====================================修改密码失败=======================
=============
SETPWD_FAIL:
LJMP SET_PWD
;====================================修改密码成功=======================
===========
SETPWD_SUCCESS:
ANL SHOW1,#0FH
ANL SHOW2,#0FH
ANL SHOW3,#0FH
ANL SHOW4,#0FH
MOV PWD1,SHOW1
MOV PWD2,SHOW2
MOV PWD3,SHOW3
MOV PWD4,SHOW4
MOV SHOW1,#01H
MOV SHOW2,#11H
MOV SHOW3,#21H
MOV SHOW4,#31H
LCALL LAMP_GREEN ;闪绿灯
RET
;=====================================左移功能=========================
===================== LED_MOVE:
CLR C
MOV A, SHOW2
SUBB A,#10H
MOV SHOW1,A
CLR C
MOV A, SHOW3
SUBB A,#10H
MOV SHOW2,A
CLR C
MOV A, SHOW4
SUBB A,#10H
MOV SHOW3,A
RET
;======================================密码检测========================
================
PWD_COMPARE:
MOV A, SHOW1
ANL A, #0FH
CJNE A, PWD1,PWD_EXIT
MOV A, SHOW2
ANL A, #0FH
CJNE A, PWD2,PWD_EXIT
MOV A, SHOW3
ANL A, #0FH
CJNE A, PWD3,PWD_EXIT
MOV A, SHOW4
ANL A, #0FH
CJNE A, PWD4,PWD_EXIT
SETB PWD_RIGHT
AJMP PWD_ESC
PWD_EXIT:
CLR PWD_RIGHT
PWD_ESC:
RET
;======================================判断键是否释放===================
=================
KEY_RELEASE:
MOV P3,#00H
KEY_LOSEN:
MOV A,P2
ANL A,#0FH
LCALL LED_DISPLAY
CJNE A,#0FH,KEY_LOSEN
RET
;=======================================LED显示=======================
=========
LED_DISPLAY:
JNB LED_ON,LED_OFF
MOV P0, SHOW1
LCALL DELAY10MS
MOV P0, SHOW2
LCALL DELAY10MS
MOV P0, SHOW3
LCALL DELAY10MS
MOV P0, SHOW4
LCALL DELAY10MS LED_OFF:
MOV P0, #4FH
RET
;========================正常按键响声===========================
BEEP1:
CLR SOND
LCALL DELAY1
SETB SOND
RET
;========================非法按键响声============================
BEEP2:
CLR SOND
LCALL DELAY100MS
LCALL DELAY100MS
SETB SOND
RET
;=========================操作有误闪红灯================================
=
LAMP_RED:
MOV R2,#06H
MOV R1,#0FFH LAMP_LOOP:
DJNZ R1,LAMP_LOOP
CPL RED
MOV R1,#0FFH
DJNZ R2,LAMP_LOOP
SETB RED
RET
;==========================修改密码成功闪绿灯===========================
===============
LAMP_GREEN:
MOV R2,#06H
MOV R1,#0FFH LAMP_LOOP1:
DJNZ R1,LAMP_LOOP1
CPL GREEN
MOV R1,#0FFH
DJNZ R2,LAMP_LOOP1
CLR GREEN
RET
;========================10MS延时===========================
DELAY10MS:
MOV R2,#04H LOOP3:
MOV R1,#0F9H LOOP4:
DJNZ R1,LOOP4
DJNZ R2,LOOP3
RET
;========================100MS延时===========================
DELAY100MS:
MOV R2,#0FFH LOOP7:
MOV R1,#0FFH
LOOP8:
DJNZ R1,LOOP8
DJNZ R2,LOOP7
RET
;=========================声音延时=========================== DELAY1:
MOV R2,#0FFH
LOOP5:
MOV R1,#03FH
LOOP6:
DJNZ R1,LOOP6
DJNZ R2,LOOP5
RET
;==========================键值表=========================== KEY_VALUE: DB 0EEH,0EDH,0EBH,0E7H,0DEH,0DDH,0DBH,0D7H,0BEH,0BDH,0BBH,0
B7H,07EH,07DH,07BH,077H
;==========================数字表=========================== TAB: DB 00H,00H,00H,00H,00H,01H,02H,03H,04H,05H,06H,07H,08H,09H
实际电路图: