|
|
所有資料下載:
用PIC單片機(jī)設(shè)計(jì)電子密碼鎖.rar
(39.89 KB, 下載次數(shù): 39)
2016-10-18 14:32 上傳
點(diǎn)擊文件名下載附件
微芯公司生產(chǎn)的PIC8位COMS單片機(jī),采用類RISC指令集和哈弗總線結(jié)構(gòu),以及先進(jìn)的流水線時(shí)序,與傳統(tǒng)51單片機(jī)相比其在速度和性能方面更具優(yōu)越性和先進(jìn)性。 PIC單片機(jī)的另一個(gè)優(yōu)點(diǎn)是片上硬件資源豐富,集成常見的EPROM、DAC、PWM以及看門狗電路。這使得硬件電路的設(shè)計(jì)更加簡(jiǎn)單,節(jié)約設(shè)計(jì)成本,提高整機(jī)性能。因此PIC單片機(jī)已成為產(chǎn)品開發(fā),尤其是產(chǎn)品設(shè)計(jì)和研制階段的首選控制器。 本文介紹用PIC16F84單片機(jī)制作的電子密碼鎖。PIC16F84單片機(jī)共18個(gè)引腳,13個(gè)可用I/O接口。芯片內(nèi)有1K×14的FLASHROM程序存儲(chǔ)器,36×8的靜態(tài)RAM的通用寄存器,64×8的EEPROM的數(shù)據(jù)存儲(chǔ)器,8級(jí)深度的硬堆棧。 硬件設(shè)計(jì) 電路原理見圖1。Xx8位數(shù)據(jù)線接4x4鍵盤矩陣電路,面板布局見表1,A、B、C、D為備用功能鍵。RA0、RA7輸出4組編碼二進(jìn)制數(shù)據(jù),經(jīng)74LS139譯碼后輸出逐行掃描信號(hào),送RB4-RB7列信號(hào)輸入端。余下半個(gè)139譯碼器動(dòng)揚(yáng)聲器。RB2接中功率三極管基極,驅(qū)動(dòng)繼電器動(dòng)作。有效密碼長(zhǎng)度為4位,根據(jù)實(shí)際情況,可通過修改源程序增加密碼位數(shù)。產(chǎn)品初始密碼為3345,這是一隨機(jī)數(shù),無特殊意義,目的是為防止被套解。用戶可按*號(hào)鍵修改密碼,按#號(hào)鍵結(jié)束。輸入密碼并按#號(hào)確認(rèn)之后,腳輸出RB2腳輸出高電平,繼電器閉合,執(zhí)行一次開鎖動(dòng)作。 若用戶輸入的密碼正確,揚(yáng)聲器發(fā)出一聲稍長(zhǎng)的“滴”提示聲,若輸入的密碼與上次修改的不符,則發(fā)出短促的“滴”聲。連續(xù)3次輸入密碼錯(cuò)誤之后,程序鎖死,揚(yáng)聲器報(bào)警。直到CPU被復(fù)位或從新上電。 軟件設(shè)計(jì) 軟件流程圖見圖3。CPU上電或復(fù)位之后將最近一次修改并保存到EEPROM的密碼讀出,最為參照密匙。然后等待用戶輸入開鎖密碼。若5分鐘以內(nèi)沒有接受到用戶的任何輸入,CPU自動(dòng)轉(zhuǎn)入掉電模式,用戶輸入任意值可喚醒CPU。 每次修改密碼之后,CPU將新的密碼存入內(nèi)部4個(gè)連續(xù)的EEPROM單元,掉電后該數(shù)據(jù)任有效。每執(zhí)行一次開鎖指令,CPU將當(dāng)前輸入密碼與該值比較,看是否真確,并給出相應(yīng)的提示和控制。 布 局 所有元件均使用SMD表貼封裝,縮小體積,便于產(chǎn)品安裝,60X60雙面PCB板,頂層是一體化輸入鍵盤,底層是元件層。成型后的產(chǎn)品體積小巧,能很方便的嵌入防盜鐵門、保險(xiǎn)箱柜。 | COL0 | COL1 | COL2 | COL3 | ROW0 | 1 | 2 | 3 | A | ROW1 | 4 | 5 | 6 | B | ROW2 | 7 | 8 | 9 | C | ROW3 | * | 0 | # | D |
表1
源程序: - ;鑒于某些原因,本程序僅僅供參考,如有不便請(qǐng)諒解!
- ; 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'
復(fù)制代碼
|
-
|