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

📄 codelock1.asm

📁 PIC单片机设计电子密码锁
💻 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 + -