⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl2d.asm

📁 A Source code for a combination Lock using a Pic 16F84.
💻 ASM
字号:
;**********************************************************************
;                                                                     *
;    Filename:	    cl2.asm                                           *
;    Date:                                                            *
;    File Version:  Codelock rewritten                                *
;                                                                     *
;    Author:                                                          *
;                                                                     *
;**********************************************************************
;NOTES
;
; the rewritten codelock has the following changes:
;
; - no multiplexer is needed (the old version used a generic devboard)
; - no row diodes needed (rows are never driven HIGH)
; - low power consumption due to keyboard wake-up
; - stores the code in the internal EEPROM
; - user defined codelength and pulse output
; - user adjustable running frequency
; - improved code changing function with a "change" indicator LED
;
; PIC ports used:
; 
; PA0-3 outputs: row select pulldown outputs (tristate or driven LOW)
; PB1 output: code change indicator LED
; PB2 output: output pulse to control a relay
; PB3 output: piezo beeper output
; PB4-PB7 inputs: column inputs with internal pullup
;
;**********************************************************************
;HISTORY
;
; 020-20010929 rewrite started
; 021-20011022 udelay calibrated to 100 usec (4, 10 MHz)
; 022-20011022 scan, input and compare functions work
; 023-20011022 code change function works
; 023c-20030816 Alan Carvalho de Assis add support to 8 passwords 
; 023d-20040609 Melvic S. Punzalan modifies code to use two different
;               codes to activate two pulse outputs
;               The second output is RB0
;**********************************************************************
	list	p=16f84a
	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

#include <p16F84a.inc>

mhz		EQU D'4' ; processor frequency in MHz
pulsewidth	EQU D'150'; delay in 20ms steps (150=3 sec)
clen		EQU  6    ; length of code

; EEPROM contents
		ORG 0x2100
				  ; default codes (8 * clen chars are used)
				  ; which is stored in EEPROM
		de 	"123456"	; password 1
		de	"123457"	; password 2

 
; RAM registers
ram_start	EQU 0x0c
dcnt0		EQU ram_start+1 ; delay counter 0
dcnt1		EQU ram_start+2 ; delay counter 1
dcnt2		EQU ram_start+3 ; delay counter 2
beepcnt		EQU ram_start+4 ; beep cycle counter
keycode		EQU ram_start+5
rowcnt		EQU ram_start+6
colcnt		EQU ram_start+7
colstatus	EQU ram_start+8
melvicntr EQU ram_start+9


cod		EQU ram_start+10 ; actual code

cod_end		EQU cod+(2*clen); 2 password

readlen		EQU cod_end
readbuf		EQU cod_end+1
readbuf_end	EQU readbuf+clen

tmptr		EQU readbuf_end  ; pointer for comparing and copying readbuf
tmbyte		EQU readbuf_end+1; temp storage for comparing and copying

cntpass		EQU readbuf_end+2; counter password
currptr		EQU readbuf_end+3; pointer to current code


vectors		ORG 0
  		goto main
		nop
		nop
		nop
		retfie

keytable	;determine pressed key's real code from scancode
		movf keycode, W
		addwf PCL, F
		dt 0x60
		dt "123a"
		dt "456b"
		dt "789c"
		dt "*0#d"

eep_read	; read EEPROM contents to RAM from cod to cod_end-1
		movlw cod
		movwf FSR
		clrf EEADR

eep_0		;bcf INTCON, GIE
		bsf STATUS, RP0
		bsf EECON1, RD
		bcf STATUS, RP0
		;bsf INTCON, GIE
		movf EEDATA, W
		movwf INDF

		incf FSR, F
		incf EEADR, F

		movlw cod_end
		subwf FSR, W
		bnz eep_0
		return

eep_write	; save RAM contents to EEPROM from cod to cod_end-1
		movlw cod
		movwf FSR
		clrf EEADR

eep_1		;
		movf INDF, W
		movwf EEDATA
		;bcf INTCON, GIE
		bsf STATUS, RP0
		bcf EECON1, EEIF
		bsf EECON1, WREN
		movlw 0x55
		movwf EECON2
		movlw 0xaa
		movwf EECON2
		bsf EECON1, WR

eep_2		; wait for write completition
		bcf STATUS, RP0
		;bsf INTCON, GIE
		nop
		nop
		;bcf INTCON, GIE
		bsf STATUS, RP0
		btfss EECON1, EEIF
		goto eep_2
		bcf STATUS, RP0
		;bsf INTCON, GIE

		incf FSR, F
		incf EEADR, F

		movlw cod_end
		subwf FSR, W
		bnz eep_1
		return

udelay		; delay W * 100 usec
		movwf dcnt0

udelay0		;
		movlw 8 * mhz
		movwf dcnt1

udelay1		
		decfsz dcnt1, F
		goto udelay1

		decfsz dcnt0, F
		goto udelay0

		return

beep		;
		movwf beepcnt
beep0		;
		bsf PORTB, 3 ; beepctl bit
		movlw 3
		call udelay
		bcf PORTB, 3 ; beepctl bit
		movlw 3
		call udelay
		decfsz beepcnt, F
		goto beep0
		return

keyscan		; scan the keyboard
		clrf keycode
		movlw 4
		movwf rowcnt

		movlw 0xfe
		tris PORTA ; select row 0

rowscan		
		movlw 0xa0
		call udelay
		swapf PORTB, W
		movwf colstatus

		movlw 4
		movwf colcnt

colscan		
		incf keycode, F
		rrf colstatus, F
		btfss STATUS, C
		goto keytable ; a key was found

		decfsz colcnt, F
		goto colscan

		bsf STATUS, C

		bsf STATUS, RP0
		rlf TRISA, F ; select next row
		bcf STATUS, RP0

		decfsz rowcnt, F
		goto rowscan
		retlw 0 ; no key was found

main		; program starts here
		clrf PORTA
		clrw
		tris PORTA ; porta all output
		clrf PORTB
		movlw 0xf0 ; pb4-7 inputs
		tris PORTB
		bsf STATUS, RP0 ; bank 1
		bcf OPTION_REG, NOT_RBPU ;internal pullups on port B enabled
		bcf STATUS, RP0 ;bank 0


warm		
		movlw 0xf0
		call beep
		call eep_read ; read code from eeprom to ram at cod

loop		clrf PORTB ; clear output

		movlw .1
		movwf melvicntr


		call read ; read code from keyboard into readbuf
		movlw cod
		call compbuf ; compare code in readbuf with code at cod
		bnz loop ; the code is different

		; the code matches, check which enter (#*) was pressed

		movlw '*'
		subwf keycode, W ; * changes code
		bz codechange

		movf melvicntr,w
		sublw .1
		bnz pulseout2

		

pulseout	; # operates output
		movlw 0x04 ; RB2 is output
		movwf PORTB

		movlw pulsewidth
		movwf dcnt2

out0		movlw d'200'
		call udelay
		decfsz dcnt2, F
		goto out0

		goto loop


	
pulseout2	; # operates 2nd output
		movlw 0x01 ; RB0 is output
		movwf PORTB

		movlw pulsewidth
		movwf dcnt2

		call out0


codechange	movlw 2     	; * changes code
		movwf PORTB 	; indicate changing the code
		call read   	; read new code into readbuf


		;;movlw cod
		call copybuf ; copy new code into cod

		call read ; read new code twice

		movlw cod ; and check if the new code is confirmed
		call compbuf ; wrong code entry, restart with the original code
		bnz warm

		; new code is comfirmed twice, store into eeprom
		call eep_write
		goto loop

read		clrf readlen

readloop	; wait until no key is pressed
		clrw
		tris PORTA ; porta all LOW
		movf PORTB, W
		andlw 0xf0 ; keymask
		xorlw 0xf0
		btfss STATUS, Z
		goto readloop

		movlw  0xf0  ; wait 24 ms
		call udelay  ; (debounce)

		; no key pressed, go to sleep
		movf PORTB, W
		movlw 1<<RBIE ; enable RB port change wake-up
		movwf INTCON
		sleep

key_pressed
		call keyscan
		andlw 0xff
		movwf keycode
		bz readloop

		movlw 0xf0   ; wait 24 ms
		call udelay  ; (debounce)

		; check if the buffer is full
		movlw clen
		subwf readlen, W
		bnz read_notfull

		; buffer is full, can return if an enter key (*#) is pressed

		; check for ENTER
		call read_chkenter
		bnz read_notenter

		; enter is pressed, return
		movlw 0x40
		call beep
		movf keycode, W
		return

read_notenter
		; buffer is full, but more characters entered
		; shift the buffer
		movlw readbuf+1
		movwf FSR

read_shift	movf INDF, W
		decf FSR, F
		movwf INDF
		incf FSR, F
		incf FSR, F
		movlw readbuf_end
		subwf FSR, W
		bnz read_shift

		decf readlen, F

read_notfull	call read_chkenter ; if the buffer is not full and an
		bz read ; enter key (*#) is pressed, clear buffer

		movlw 0x40
		call beep

		movlw readbuf
		addwf readlen, W
		movwf FSR
		movf keycode, W
		movwf INDF
		incf readlen, F
		goto readloop

read_chkenter	; check if a * or # is pressed which indicates
		; the end of entry
		movlw '#'
		subwf keycode, W
		btfsc STATUS, Z
		return ; Z=1, enter
		movlw '*'
		subwf keycode, W
		return

compbuf		; compare read buffer to a code in RAM at W
		movwf tmptr    	; compare pointer

		clrf readlen   	; compare index starts from 0

		movlw 2		; counter password decrement from 2
		movwf cntpass   

		goto comp0

comp_next_pass

		incf melvicntr,w
		movwf melvicntr
		movlw clen	; add clen to tmptr to get next password
		addwf tmptr
		
		clrf  readlen	; compare index starts from 0 again

		decfsz  cntpass	;decrement password counter, if 0 return
		goto comp0

		movlw 255	;wait
		call udelay

		movlw 0xF0	;listen password incorrect
		call beep
		
		bcf STATUS, Z	; Z=1: the code is different
		return

comp0	movlw readbuf
		addwf readlen, W
		movwf FSR
		movf INDF, W
		movwf tmbyte ; the read byte which is compared

		movf tmptr, W
		addwf readlen, W
		movwf FSR
		movf INDF, W ; the byte readbuf is compared to
		subwf tmbyte, W
		btfss STATUS, Z
		goto comp_next_pass	;the current is diferent, test next password

		incf readlen, F
		movlw clen
		subwf readlen, W
		bnz comp0 ; compare next character
		; Z=0: the code is the same]
		
		
		
		return

copybuf		; copy readbuf to RAM at W
		;;movwf tmptr    ; copy pointer
		clrf readlen   ; copy index starts from 0

copy0		movlw readbuf
		addwf readlen, W
		movwf FSR
		movf INDF, W
		movwf tmbyte ; the read byte which is copied

		movf tmptr, W
		addwf readlen, W
		movwf FSR
		movf tmbyte, W ; the byte from readbuf
		movwf INDF

		incf readlen, F
		movlw clen
		subwf readlen, W
		bnz copy0 ; copy next character

		return

		end


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -