黄金会员
主题
回帖0
积分9861
阅读权限40
注册时间2009-11-11
最后登录1970-1-1
在线时间 小时
|
楼主 |
发表于 2011-5-31 19:28
|
显示全部楼层
本帖最后由 WOSS1001 于 2011-6-1 07:21 编辑
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;1602密码锁;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
db07 equ p0;;;;
rs bit p0.3;;;;LCD硬件定义
e bit p0.2;;;;;
DSX EQU 31H ;延时值存放单元
DSY EQU 32H ;
BJYS EQU 50H; 报警延时存储
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;24C01硬件定义;;;;;;;;;
SDA24 EQU P0.1
SCLK24 EQU P0.0
;;;;;;;;;;;;;;;;;;;;;;;;;;;
KEYJK EQU P2;键盘接P3口
JL4 BIT P2.0;键第4列(第一列是P2.3,所以NEXT程序中是RR A 既从左往右)
JH1 BIT P2.7;键第1行
JH2 BIT P2.6;键第2行
JH3 BIT P2.5;键第3行
JH4 BIT P2.4;键第4行
;;;;;;;;;;;;;;;;;;;;;
;R0 暂保留
;R1 键盘输入密码的储存地址
;R2 行值暂存
;R3 1602每写一次的字符数
;R4 列值暂存(第1列00H,第2列01H,第3列03H,第4列04H)
;R5 光标地址储存
;R6 定时标志
;R7 24C01读写用,
;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;
org 0000H
ajmp 0030h
org 000bh
ajmp dingshi
org 0030h
;;;;;;;;;;;;;;;;;;;;
;;;;;程序开始;;;;;;;
start0:mov tmod,#01h
mov tl0,#0b0h
mov th0,#3ch
setb ea
setb et0
clr tr0
setb p1.3
mov r6,#00h
mov sp,#60h
mov r1,#40h; 键盘输入密码的储存首址
ACALL LCDCSH
mov a,#80h ;第一行显示首址
acall xzl
mov dptr,#tab;指定写表1内容
acall xpm;调用写屏子程序
mov a,#0c0h ;第二行显示首址
acall xzl
mov dptr,#tab1
acall xpm
mov a,#0c5h;光标到密码输入首址
ACALL XZL
MOV R5,#0C5H;光标地址送R5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main:
lcall k1 ;调用键盘扫描程序
cjne a,#0a5h,pppp
ajmp main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; 判断键值 ;;;;
pppp: mov dptr,#JZTAB ;将表头放入DPTR
movc a,@a+dptr ;查表后将键值送入ACC
CJNE A,#0Eh,sr ;是否清除键?
CJNE R5,#0C5H,XC;光标还在0C5H位既没输入密码,清除键无效
acall bbb
acall ys500ms
acall bbb
ajmp main ;清除键无效
XC: dec r1 ;存储地址减一
DEC R5 ;光标不在第一位,光标左移一位
MOV A,R5
ACALL XZL
MOV A,#"?" ;*改成? ;
ACALL XSJ
MOV A,R5 ;光标返回修改位
ACALL XZL
acall bbb
AJMP MAIN
;;;;;;;;非清除键部分;;;;;;;;;;;;
sr: cjne a,#0Fh,sr0 ;是否确认键?
cjne r5,#0cbh,bbb2
ajmp MMBJ ;转密码比较
bbb2:acall bbb
acall ys500ms
acall bbb
ajmp main
sr0:cjne r5,#0cbh,sr1;输入超6位则输入无效
acall bbb
acall ys500ms
acall bbb
ajmp main
sr1:mov @R1,a ;储存
inc r1 ;储存地址加1
MOV A,#"*" ;有输入,显示*
ACALL XSJ ;指向下一位
INC R5
acall bbb
AJMP MAIN
;;;;;;;;;;;;;;;;;;; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;按钮扫描 ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
K1: acall ks
jnz kk1
MOV A,#0A5H
RET ;无键按下则返回
kk1:acall ys500ms
acall ks
jnz k2
mov a,#0a5h ;无效标志送A
RET ;无键按下则返回
;;;; 开始行扫描 ;;;;;
k2:
MOV R2,#0F7H ;将扫描值送入 R2暂存
MOV R4,#00H ;将第一列值送入R4暂存(第1列00H,第2列01H,第3列03H,第4列04H)
K3: MOV KEYJK,R2 ;将R2的值送键盘接口,#01111111B既第一列为0
L6: JB JH1,L1 ; 第一行等于1(没键按下)跳转到L1 扫描第2行
MOV A,#00H ;将第一行值送入ACC
AJMP LK ;跳转到键值处理程序
L1: JB JH2,L2 ;第2行等于1跳转到L2
MOV A,#04H ;将第二行的行值送入ACC
AJMP LK ;跳转到键值理程序进行键值处理
L2: JB JH3,L3 ;第3行等于1跳转到L3
MOV A,#08H ;将第三行的行值送入ACC
AJMP LK ;跳转到键值处理程
L3: JB JH4,NEXT ;第4行等于1跳转到NEXT处
MOV A,#0cH ;将第四行的行值送入ACC
;;;计算键值及等待按钮释放;;;;;;
LK:
ADD A,R4 ;行值与列值相加后的键值送入A
PUSH ACC ;将A中的值送入堆栈暂存
K4: LCALL DELAY2 ;调用延时去抖动程序
LCALL KS ;调用按键检测程序
JNZ K4 ;按键没有松开继续返回检测
POP ACC ;将堆栈的值送入A
mov r6,#00H;定时标志清零
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NEXT:
INC R4 ;将列值加一
MOV A,R2 ;将R2的值送入A
JNB JL4,WX1 ;扫描完至KEY处进行下一扫描
RR A ;因为是从P2。7-P2。4既左往右,所以是RR A
MOV R2,A ;将ACC的值送入R2暂存
AJMP K3 ;跳转到K3继续下一列扫描
;扫完返回
WX1:mov a,#0a5h ;无效标志送A
ajmp main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KS: MOV KEYJK,#0F0H ;将P3口高四位置1低四位值0
MOV A,KEYJK ;读P3口
XRL A,#0F0H ;将A中的值与11110000相异或
RET ;子程序返回
;;;;;;;;;;;;;;;;;;;;;;
BJ: acall stop ;密码错,报警
clr p1.0
MOV A,#080H
ACALL XZL
MOV DPTR,#TAB3
ACALL XPM
mov bjys,#100
bj1: acall ys500ms
djnz bjys,bj1
setb p1.0
ajmp start0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;密码比较;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;读2401 00H-05H内容并与单片机40H-45H单元内容比较
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MMBJ: ACALL STAR ;
MOV A,#0A0H
ACALL WT
MOV A,#00H
ACALL WT
ACALL STAR
MOV A,#0A1H ;
ACALL WT
acall rd24
CJNE a,40H,BJ
acall xack
acall rd24
CJNE a,41H,BJ
ACALL XACK
ACALL RD24
CJNE A,42H,BJ
ACALL XACK
acall rd24
CJNE a,43H,BJ
acall xack
acall rd24
CJNE a,44H,BJ
ACALL XACK
ACALL RD24
CJNE a,45H,BJ
ACALL STOP
clr p1.3 ;密码正确
acall bbb
acall ys500ms
acall bbb
yyy: MOV A,#080H
ACALL XZL
MOV DPTR,#TAB2
ACALL XPM
mov a,#0c0h
acall xzl
mov dptr,#tab4
acall xpm ;显示设置和锁菜单
setb tr0 ;启动1分钟定时
acall ys500ms
acall bbb
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;检测有无设置键或锁键按下;;;;;;;;;;;;;
syb: acall k1
cjne a,#0a5h,xyb;有键按下,转XYB步判断
cjne r6,#250,dsds
ajmp start0
dsds: ajmp syb
xyb: mov dptr,#jztab
movc a,@a+dptr
cjne a,#0eh,pdqr;不是CLR键转判断是否ENT
SETB P1.3 ;锁并返回
acall bbb
AJMP START0
pdqr: cjne a,#0fh,syb
MOV A,#80H
ACALL XZL
MOV DPTR,#TAB5
ACALL XPM
mov a,#0c0h
acall xzl
mov dptr,#tab6
acall xpm ;显示输入新密码
acall bbb
MOV R5,#0C5H
MOV A,R5
ACALL XZL
MOV R1,#40H
mov r6,#00h
XIUGAI: acall k1 ;键盘扫描
;;; 密码修改部分 ;;;;
cjne a,#0a5h,pppp0
cjne r6,#250,opop
ajmp start0
opop: ajmp xiugai
pppp0:;mov r6,#00h
mov dptr,#JZTAB ;将表头放入DPTR
movc a,@a+dptr ;查表后将键值送入ACC
CJNE A,#0Eh,s0r ;是否清除键?
CJNE R5,#0C5H,XC0;光标还在0C5H位既没输入密码,清除键无效
acall bbb
acall ys500ms
acall bbb
ajmp XIUGAI ;清除键无效
XC0: dec r1 ;存储地址减一
DEC R5 ;光标不在第一位,光标左移一位
MOV A,R5
ACALL XZL
MOV A,#"?" ;*改成? ;
ACALL XSJ
MOV A,R5 ;光标返回修改位
ACALL XZL
acall bbb
AJMP XIUGAI
;;;;;;;;非清除键部分;;;;;;;;;;;;
s0r:cjne a,#0Fh,s0r0 ;是否确认键?
cjne r5,#0cbh,b0bb2
ACALL BBB
ajmp MMCC ;转密码储存
b0bb2:acall bbb
acall ys500ms
acall bbb
ajmp XIUGAI
s0r0:cjne r5,#0cbh,s0r1;输入超6位则输入无效
acall bbb
acall ys500ms
acall bbb
ajmp xiugai
s0r1:mov @R1,a ;储存
inc r1 ;储存地址加1
MOV A,#"*" ;有输入,显示*
ACALL XSJ ;指向下一位
INC R5
acall bbb
AJMP xiugai
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;将输入的密码存入24C01;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MMCC: mov r6,#00h
ACALL STAR
MOV A,#0A0H
ACALL WT
MOV A,#00H
ACALL WT
MOV A,40H
ACALL WT
MOV A,41H
ACALL WT
MOV A,42H
ACALL WT
MOV A,43H
ACALL WT
MOV A,44H
ACALL WT
MOV A,45H
ACALL WT
ACALL STOP
acall delay ;这个延时很重要
mov a,#80h
acall xzl
mov dptr ,#tab7
acall xpm ;显示密码已修改
mov a,#0c0h
acall xzl
mov dptr,#tab8
acall xpm
mov r6,#00h
yyyy: ACALL K1
CJNE A,#0A5H,XYCD;有输入转XYCD
cjne r6,#250,yuyu
ajmp start0
yuyu: ajmp yyyy
xycd:mov dptr,#jztab ;读出键值
movc a,@a+dptr
cjne a,#0eh,yyyy1 ;是否CLR键
acall bbb
acall ys500ms
ajmp start0 ;是,上锁
yyyy1:cjne a,#0fh,yyyy ; 是否ENT
ajmp yyy ;返回 "ENT=SET CLR=LOCK" 菜单
dingshi:mov tl0,#0b0h
mov th0,#3ch
inc r6
reti
;;;;;;;;;;;;;;;;;;;;;;;
xpm: mov r3,#00h ;写屏幕,共16个字符
loop:mov a,r3
movc a,@a+dptr
acall xsj
inc r3
cjne r3,#16,loop;
RET
;;;;;LCD 用子程序;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
LCDCSH:ACALL delay2 ;lcd初始化
MOV a,#03H
acall xzl
MOV a,#33H
acall xzl
MOV a,#02H
acall xzl
mov a,#101000b ;4BIT ,2行显示
acall xzl
mov a,#01h ;清屏
acall xzl
mov a,#00000010b ;光标复位
acall xzl
MOV A,#00000110B ;地址增量1,字符不移动
acall xzl
mov a,#00001111b ;显示开,光标有,光标闪
acall xzl
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
xzl:mov 30h,a
orl a,#0fh ;LCD写指令
mov db07,a
acall xzl0
mov a,30h
swap a
orl a,#0fh
mov db07,a
xzl0:clr rs
clr e
acall delay
setb e
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
xsj:mov 30h,a ;LCD写数据
orl a,#0fh
mov db07,a
acall xsj1
mov a,30h
swap a
orl a,#0fh
mov db07,a
xsj1:setb rs
clr e
acall delay1
setb e
ret
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;读2401子程序,出口A
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RD24: MOV R7,#8 ;8个位
CLR A
SETB SDA24 ;设置SDA4口为输入状态
RD000:SETB SCLK24
MOV C,SDA24
acall DELAY0
CLR SCLK24
RLC A
DJNZ R7,RD000
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;开始条件
star: setb SDA24 ;时钟线高电平时,数据线由高到低跳变
setb SCLK24
clr SDA24
acall DELAY0
clr SCLK24
ret
;;;;;;;;;;;;;;;;;;;;;;;;;
;停止条件
STOP: clr SDA24 ;时钟线高电平时,数据线由低到高跳变
setb SCLK24
setb SDA24
acall DELAY0
RET
;;;;;;;;;;;;;;;;;;;;;;;;
;;判断2401有无应答信号
;;;;;;;;;;;;;;;;;;;;;;;;;;
ACK: setb sda24 ;设P0.0为输入
setb SCLK24
JB SDA24,$ ;判断2401有无应答信号
clr SDA24
clr SCLK24
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;
XACK: clr sda24 ;给2401一个应答信号
setb sclk24
acall DELAY0
clr sclk24
ret
;;;;;;;;;;;;;;;;;;;;;;;;;
;;写2401子程序,入口A
;;;;;;;;;;;;;;;;;;;;;;;;
WT: mov r7,#8
clr c
WT1: rlc a
mov SDA24,c
SETB SCLK24
acall DELAY0
CLR SCLK24
djnz r7,WT1
acall ack
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
;;;按键滴声;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
bbb:clr p1.0
acall ys500ms
setb p1.0
ret
;;;;;;;;;;;;;;;;;;;;;;;;
DELAY0: NOP ;延时
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay:mov DSX,#100 ;这是初始化操作1602的延时程序
d10: mov DSY,#15
djnz DSY,$
djnz DSX,d10
ret
delay1:mov DSX,#10 ;这是初始化完成后正常操作1602的延时程序
d11: mov DSY,#10
djnz DSY,$
djnz DSX,d11
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY2: ;40ms延时去抖动子程序
MOV DSX,#08H
L7: MOV DSY,#0FAH
L8: DJNZ DSY,L8
DJNZ DSX,L7
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;
YS500MS:MOV DSX,#200
YS5001: MOV DSY,#200
djnz DSY,$
DJNZ DSX,YS5001
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;
JZTAB:DB 1,2,3,0Ch,4,5,6,0Dh,7,8,9,0Eh,0Ah,0,0Bh,0Fh
TAB:db" Qing Shu Mi Ma "
TAB1:DB" ?????? "
TAB2:DB " Huan Ying ! "
TAB3:DB " Mi Ma Cuo Wu ! "
TAB4:DB"ENT=SET CLR=LOCK"
tab5:db"Shu Ru Xin Mi Ma"
tab6:db" ?????? "
tab7:db"Mi Ma Yi Xiu Gai"
tab8:db"CLR=LOCK NET= <-"
END
|
|