📄 zh7.asm
字号:
.device AT90S8535
.equ sph =$3E
.equ spl =$3D
.equ PORTA =$1B
.equ DDRA =$1A
.equ PINA =$19
.equ PORTC =$15
.equ DDRC =$14
.equ PINC =$13
.def XL =r26
.def XH =r27
.def ZL =r30
.def ZH =r31
.org $0000
rjmp main
tab: .db $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a
main: ldi r16,$02 ;栈指针置初值
out sph,r16
ldi r16,$5f
out spl,r16
ldi XL,$60
ldi XH,$00
ldi r16,$df
out DDRA,r16
ldi r16,$20
out PORTA,r16
ldi r16,$08 ;密码个数8个
mov r4,r16
ldi r16,$00 ;初始密码0,1,2,3,4,5,6,7
pnext: st X+,r16
inc r16
dec r4
brne pnext
mloop: cbi PORTA,0 ;锁合
sbi PORTA,1 ;锁开
sbi PORTA,2 ;键有效
sbi PORTA,3 ;错误
sbi PORTA,4 ;报警
ldi r16,$03 ;错误次数3次
mov r3,r16
;**********************************************************
;输入密码
getpw: ldi r16,$08 ;密码个数
mov r4,r16
ldi XL,$70 ;输入密码暂存区
ldi XH,$00
again: rcall key
cpi r16,$0a
brne con ;按确认键无效
rjmp again
con: st X+,r16
rcall disp ;按键有效显示
dec r4
brne again
again1: rcall key ;按确认键
cpi r16,$0a
brne again1
rcall disp ;按确认键有效显示
rcall com ;比较密码
sbi PORTA,0 ;熄锁合指示灯
cbi PORTA,1 ;开锁
wait: in r16,PINA ;是否重新上锁
sbrs r16,5
rjmp mloop ;主循环
rcall testk ;是否有键按下,是否修改密码
cpi r16,$f0
breq wait
rcall chpsw ;修改密码子程序
rjmp wait
;**********************************************************
com: ldi r16,$08
mov r4,r16
ldi XL,$70 ;输入密码暂存区
ldi XH,$00
agai: ld r16,X
mov r19,r16
ldi r16,$10
sub XL,r16
ld r16,X+
cpse r16,r19 ;比较
rjmp oncem
ldi r16,$10
add XL,r16
dec r4
brne agai
ret ;正确返回
;**********************************************************
oncem: cbi PORTA,3
rcall delay
sbi PORTA,3
dec r3 ;3次错误输入
brne getpw
cbi PORTA,4 ;声报警
cbi PORTA,3 ;光报警
w: rjmp w
;**********************************************************
chpsw: ldi r16,$07 ;修改密码子程序
mov r4,r16
ldi XL,$68 ;输入密码暂存区
ldi XH,$00
rcall key
cpi r16,$0a
brne con2 ;按确认键无效
rjmp again
;**********************************************************
con2: st X+,r16
rcall disp ;按键有效显示
ano: rcall key
cpi r16,$0a
brne con3 ;按确认键无效
rjmp ano
con3: st X+,r16
rcall disp ;按键有效显示
dec r4
brne ano
again2: rcall key ;按确认键
cpi r16,$0a
brne con2
rcall disp ;按键有效显示
ldi r16,$08
mov r4,r16
ldi XL,$68
ldi XH,$00
change: ld r16,X ;确认后修改密码
mov r19,r16
ldi r16,$08
sub XL,r16
st X+,r19
add XL,r16
dec r4
brne change
ret
;**********************************************************
disp: cbi PORTA,2 ;按键有效显示
rcall delay
sbi PORTA,2
ret
;**********************************************************
testk: ldi r16,$f0 ;判断是否有键按下
out DDRC,r16
out PORTC,r16
in r16,PINC
andi r16,$ff
ret
;**********************************************************
key: ldi r16,$f0 ;取键值子程序,阵列式键盘
out DDRC,r16
out PORTC,r16
l1: in r16,PINC
cpi r16,$f1
brne l2
rcall t1ms
in r16,PINC
cpi r16,$f1
brne l2
ldi r17,$00
rjmp rscan
l2: cpi r16,$f2
brne l3
rcall t1ms
cpi r16,$f2
brne l3
ldi r17,$01
rjmp rscan
l3: cpi r16,$f4
brne key
rcall t1ms
cpi r16,$f4
brne key
ldi r17,$02
rscan: ldi r16,$0f
out DDRC,r16
out PORTC,r16
c1: in r16,PINC
cpi r16,$e0
brne c2
ldi r18,$00
rjmp calcu
c2: cpi r16,$d0
brne c3
ldi r18,$01
rjmp calcu
c3: cpi r16,$b0
brne c4
ldi r18,$02
rjmp calcu
c4: cpi r16,$70
brne key
ldi r18,$03
;**********************************************************
calcu: cpi r17,$00 ;计算键号
brne calcu1
ldi r17,$00
rjmp cb
calcu1: cpi r17,$01
brne calcu2
ldi r17,$04
rjmp cb
calcu2: cpi r17,$02
brne calcu3
ldi r17,$08
rjmp cb
calcu3: ldi r17,$0C
cb: add r17,r18
rcall cqb
rcall w0
ret
;**********************************************************
cqb: ldi ZH,high(tab*2) ;7段码的首址给Z
ldi ZL,low(tab*2)
add ZL,r17 ;首地址+偏移量
lpm ;查表送B口输出
mov r16,r0
ret
;**********************************************************
;等待按键抬起
w0: ldi r20,$f0
out PORTC,r20
w1: in r20,PINC
andi r20,$ff
cpi r20,$f0
brne w2
ret
w2: rjmp w0
;**********************************************************
t1ms: ldi r24,6 ;延时子程序
push r24
del2: push r24
del3: dec r24
brne del3
pop r24
dec r24
brne del2
pop r24
ret
;**********************************************************
;延时500ms
delay: ldi r16,197
push r16 ;进栈需2t
de0: push r16 ;进栈需2t
de1: push r16 ;进栈需2t
de2: dec r16 ;-1需1t
brne de2 ;不为0转,为0顺序执行,需1t/2t
pop r16 ;出栈需2t
dec r16 ;-1需1t
brne de1 ;不为0转,为0顺序执行,需1t/2t
pop r16 ;出栈需2t
dec r16 ;-1需1t
brne de0 ;不为0转,为0顺序执行,需1t/2t
pop r16 ;出栈需2t
ret ;子程序返回需4t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -