📄 codelock1.asm
字号:
;鉴于某些原因,本程序仅仅供参考,如有不便请谅解!
; HISTORY
;
; 002 - 2000 - original codelock source
; 003 - 2000 - serial terminal version
; 004 - 20010103 - cleaned up version without the serial junk, doesn't use EEPROM
;**********************************************************************
;
; Notes:
;
;PORTA<1:0> out row select (1-4) to MPX
;PORTA2 out LED control
;PORTB3 beeper control output
;PORTB<7:4> in keyboard column status
;PORTB2 relay output
list p=16F84 ; list directive to define processor
#include <p16F84.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ;WDT=watchdog, PWRTE=power on timer, HS=high speed osc
CBLOCK 0x0C
;***** VARIABLE DEFINITIONS
row_cnt ;row counter
column ;keyboard column status
count1 ;column counter for the keyboard handler
count2 ;row counter timing
count3 ;row counter timing
keycode
prevcode
led_ctl ; LED control bits <3:0>
led_tmp ; working register for setting multiplexed LED control pin
keybuf ; keyboard buffer, empty after reading out
key_tmp ; keycode temporary storage
bufptr ; buffer pointer
buffer ; keyboard buffer
buffer2
buffer3
buffer4
buffer5
beeper ; beep time countdown
beepct ; beep
beepcnt ; beep cnt
count10
count20
count30
pass1 ; password
pass2
pass3
pass4
pass5
;**********************************************************************
ENDC
;****************************************************************************
ORG 0 ;RESET
Reset goto main
;****************************************************************************
ORG 4 ;INT
Interrupt retfie
;
keytable ;determine pressed key's real code from scancode
addwf PCL
retlw 60
retlw 31
retlw 32
retlw 33
retlw 61
retlw 34
retlw 35
retlw 36
retlw 62
retlw 37
retlw 38
retlw 39
retlw 63
retlw 90
retlw 30
retlw 91
retlw 64
;
main MOVLW 0c
MOVWF PORTA
MOVLW 0xe8 ; B?1101000?;SET PORT A 0-2,4 out
TRIS PORTA
MOVLW 0
MOVWF PORTB
MOVLW 0xf3 ;B11110011 ;SET PORT B4-7 AS INPUTS
TRIS PORTB
;
BSF STATUS, RP0 ;bank 1
BCF OPTION_REG, NOT_RBPU ;internal pullups on port B enabled
BCF STATUS, RP0 ;bank 0
clrf row_cnt ;row counter ;clrf?
clrf prevcode
clrf keycode
clrf beepct
MOVLW 0xff
MOVWF led_ctl
MOVWF led_tmp
movlw 1
movwf count2
movwf count3
movlw 0xf0
movwf beeper;generate beep on powerup
movlw 0x33 ;inital password
movwf pass1
movwf pass2
movlw 0x34
movwf pass3
movlw 0x35
movwf pass4
;
resetbuf movlw buffer
movwf bufptr
loop clrf keybuf
CALL scantimer
call beepgen;generate beepct if needed
movf keybuf,W
bz loopb
movlw 20
movwf beeper ;turn on soundgen
loopb movf keybuf,W
sublw 90
btfsc STATUS,Z;if Z=0, skip
; goto resetbuf
;old function of key was reset, new function is change code
goto chk0
movf keybuf,W
bz loop2 ;no key was pressed, skip
sublw 91
bnz loop5
;pressed enter, check code
chk0 movf bufptr,W
sublw buffer5
bnz incorrect
movf buffer,W
subwf pass1,W
bnz incorrect
movf buffer2,W
subwf pass2,W
bnz incorrect
movf buffer3,W
subwf pass3,W
bnz incorrect
movf buffer4,W
subwf pass4,W
bnz incorrect
;
;check for the key pressed:enter=generate pulse, otherwise get new passwd
;
movf keybuf,W
sublw 0x90 ;new passwd?
bz setpasswd
movlw 4
movwf PORTB
movlw .30
movwf count30
;
delay21 movlw .250 ;decimal
movwf count10
delay0 movlw .250
movwf count20
delay1 decfsz count20, F
goto delay1
decfsz count10
goto delay0
decfsz count30
goto delay21
;
movlw 0
movwf PORTB
incorrect goto resetbuf
loop5 movf bufptr,W ;store a char in buffer
sublw buffer5 ;is there space for more characters?
bnz loop7;yes
;no, shift all chars by one
movf buffer2,W
movwf buffer
movf buffer3,W
movwf buffer2
movf buffer4,W
movwf buffer3
movf keybuf,W
movwf buffer4
goto loop2
;store character in the buffer
loop7 movf bufptr,W
movwf FSR
movf keybuf,W
movwf INDF
incf bufptr,F
loop2
; clrf keybuf ;loop will clear keybuf
GOTO loop
setpasswd ;set a new code
;
movlw pass1
movwf FSR
setp0 clrf keybuf
call scantimer
call beepgen
movf keybuf,W
bz setp0
sublw 0x90
bz setp0
movf keybuf,W
sublw 0x91
bz setp0
movlw 99
movwf beeper
movf keybuf,W
movwf INDF
incf FSR,f
movf FSR,W
sublw pass5
bnz setp0
;
goto resetbuf
;
scantimer decfsz count2,F ;if count2=0, skip next instr
return
movlw .20
movwf count2;reload count2
decfsz count3,F
return
movlw .50;could be commented
movwf count3
;time to scan again...
;set column on port, set LED status
; movlw 4 ;LED status, ON
movlw 0
rrf led_tmp,F
btfsc STATUS,C ;if C=0, skip
movlw 4;ON
iorwf row_cnt,W
iorlw 08 ;serial TX bit latch should be 1!!!
iorwf beepct,W ;beeper register
MOVWF PORTA ;output row select, LED status and beeper control
return
;get key status
scanx MOVF PORTB,W ;get column status
MOVWF column
SWAPF column,W;swap nibbles
ANDLW 0x0f ;lower 4 bits
MOVWF column
xorlw 0x0f ;check for pressed key
btfsc STATUS,Z ;skip if Z = 0
goto scan0
movf row_cnt,W ; row_cnt->W
movwf key_tmp ;W->key_tmp
bcf STATUS,C
rlf key_tmp, F
rlf key_tmp, F ;row * 4->key_tmp
incf key_tmp ;increase +1
movlw .4 ;scan for 4 bits in the column file register
movwf count1
scan1 rrf column, F ;get the right bit & shift right
btfss STATUS, C ;if 1, skip
goto scan2;found a key pressed
incf key_tmp
decfsz count1, F
goto scan1
scan0 return;no key pressed in this row, code unchanged (init'd zero before first cycle)
scan2 ;found a key pressed
movf key_tmp,W;set keycode
movwf keycode
return;a key was pressed, code=keycode 1-16
scany movf row_cnt,W
sublw .3
btfss STATUS,Z ;if Z=1 , skip (row_cnt=3)
return
;a scan cycle is completed, test for keycode
movf keycode,W
btfsc STATUS,Z ;if Z=0, some key is pressed, skip
;Z=1, keycode=0, no key pressed
goto keyb1
;W=keycode, not zero
subwf prevcode,W;was this key pressed in the previous cycle?
btfsc STATUS,Z ;if Z=0, previous cycle was other code, skip
goto keyb3;same key, no action --but zero keycode for next cycle!!!
;a new key was pressed in the actual cycle
;should check if keybuf is empty, and zero prevkey if buffer full
movf keycode,W
call keytable
movwf keybuf
keyb1 movf keycode,W ;store previous keycode
movwf prevcode
keyb3 movlw 0
movwf keycode ;zero actual keycode for next cycle
; swapf led_ctl,W
; movwf led_tmp ;led control shift register
return
;
beepgen movf beeper,W
bz beepgen0
decfsz beepcnt
return
movlw .40
movwf beepcnt
decf beeper,F
movlw 08
btfsc beeper,0
movlw 0
beepgen0 movwf beepct
movwf PORTB
return
end ; directive 'end of program'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -