I have made a well functioning electronic combination lock, with a lot of help from Nigel's page: http://www.winpicprog.co.uk/. Well, the thing is, that I made it work perfectly until one thing, that seems to annoy me.
To simulate an unlock/lock stage I "make" the PIC jump from one place in the code to another place.
What happens is that when you start the PIC, it will start up with a text displaying that says "Enter Code" in english (I know it is not what says in the text, but it is in Danish). I enter the code and it works all well. Then I make it jump and it says "Locked: Enter code". You will therefore have to enter the code once again to unlock (or the right word should be jump) the pic and it should jump back and display "Enter code". It all works well, except that when it says "Locked...." you have to enter any 4 bit code, but the right code to unlock it, and if you enter the right code it keeps on jumping back. So you see it works quite well, except that it should work the other round, so when you enter the wrong code it keeps on looping and says "Locked: Enter code" and when the right code is entered it will jump And say "Enter code:"....
I make it jump by writing:
Where init2 is the locked stage, it is actually an exact copy of the init, and does the same thing. Except that when wrong code is entered it should jump back to init2 and when correct it should jump to init.
Why does it not work?
Where did I go wrong?
You can see what I have done in the code given below:
To simulate an unlock/lock stage I "make" the PIC jump from one place in the code to another place.
What happens is that when you start the PIC, it will start up with a text displaying that says "Enter Code" in english (I know it is not what says in the text, but it is in Danish). I enter the code and it works all well. Then I make it jump and it says "Locked: Enter code". You will therefore have to enter the code once again to unlock (or the right word should be jump) the pic and it should jump back and display "Enter code". It all works well, except that when it says "Locked...." you have to enter any 4 bit code, but the right code to unlock it, and if you enter the right code it keeps on jumping back. So you see it works quite well, except that it should work the other round, so when you enter the wrong code it keeps on looping and says "Locked: Enter code" and when the right code is entered it will jump And say "Enter code:"....
I make it jump by writing:
Rich (BB code):
Correct_Wait call Delay255
call Delay255
call Delay255
call Delay255
goto Init2
Why does it not work?
Where did I go wrong?
You can see what I have done in the code given below:
Rich (BB code):
LIST p=16F628 ;Her fortælles til assembler hvilken chip der bruges
include "P16F628.inc" ;Her defineres hvad der skal inkluderes til chippen
;hvilket er nogle standarder som programmet kan gå ud fra
;når chippen skal programmeres
ERRORLEVEL 0, -302 ;suppress bank selection messages
__config 0x3D18
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
tmp1 ;temporary storage
tmp2
templcd ;temp store for 4 bit mode
templcd2
key ;which key was pressed
rows ;counter for number of rows
code1 ;registers for secret code
code2
code3
code4
key1 ;registers for keyed attempts
key2
key3
key4
endc
LCD_PORT Equ PORTA
LCD_TRIS Equ TRISA
LCD_RS Equ 0x04 ;LCD handshake lines
LCD_RW Equ 0x06
LCD_E Equ 0x07
KEY_PORT Equ PORTB ;keypad port
KEY_TRIS Equ TRISB
Col1 Equ 0 ;pins used for keypad inputs
Col2 Equ 1
Col3 Equ 2
Col4 Equ 3
org 0x0000
goto Start
Key_Table ADDWF PCL , f ;translation table for keypad
RETLW 0x31 ;1
RETLW 0x34 ;4
RETLW 0x37 ;7
RETLW 0x2a ;*
RETLW 0x32 ;2
RETLW 0x35 ;5
RETLW 0x38 ;8
RETLW 0x30 ;0
RETLW 0x33 ;3
RETLW 0x36 ;6
RETLW 0x39 ;9
RETLW 0x23 ;#
RETLW 0x43 ;C
RETLW 0x44 ;D
RETLW 0x45 ;E
RETLW 0x46 ;F
HEX_Table ADDWF PCL , f ;hex table for LCD routines
RETLW 0x30
RETLW 0x31
RETLW 0x32
RETLW 0x33
RETLW 0x34
RETLW 0x35
RETLW 0x36
RETLW 0x37
RETLW 0x38
RETLW 0x39
RETLW 0x41
RETLW 0x42
RETLW 0x43
RETLW 0x44
RETLW 0x45
RETLW 0x46
Text addwf PCL, f
retlw 'S'
retlw 'k'
retlw 'r'
retlw 'i'
retlw 'v'
retlw ' '
retlw 'k'
retlw 'o'
retlw 'd'
retlw 'e'
retlw ':'
retlw 0x00
Text2 addwf PCL, f
retlw 'L'
retlw 'a'
retlw 'a'
retlw 's'
retlw 't'
retlw ':'
retlw ' '
retlw 'S'
retlw 'k'
retlw 'r'
retlw 'i'
retlw 'v'
retlw 0x00
Wrong_Text addwf PCL, f
retlw 'F'
retlw 'o'
retlw 'r'
retlw 'k'
retlw 'e'
retlw 'r'
retlw 't'
retlw ' '
retlw 'k'
retlw 'o'
retlw 'd'
retlw 'e'
retlw 0x00
Correct_Text addwf PCL, f
retlw 'K'
retlw 'o'
retlw 'r'
retlw 'r'
retlw 'e'
retlw 'k'
retlw 't'
retlw ' '
retlw 'k'
retlw 'o'
retlw 'd'
retlw 'e'
retlw 0x00
Start movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
Initialise movlw '0' ;set 4 digit secret code
movwf code1
movlw '0'
movwf code2
movlw '0'
movwf code3
movlw '0'
movwf code4
SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0x00 ;make all pins outputs
movwf LCD_TRIS
movlw 0x0F ;set keypad pins
movwf KEY_TRIS ;half in, half out
movwf TRISB
bcf STATUS, RP0 ;select bank 0
Init call LCD_Init ;setup LCD
clrf count ;set counter register to zero
Message movf count, w ;put counter value in W
call Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Main
call LCD_Char
incf count, f
goto Message
Wrong call LCD_Clr
clrf count ;set counter register to zero
Message1 movf count, w ;put counter value in W
call Wrong_Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Wrong_Wait
call LCD_Char
incf count, f
goto Message1
Wrong_Wait call Delay255
call Delay255
call Delay255
call Delay255
goto Init
Correct call LCD_Clr
clrf count ;set counter register to zero
Message2 movf count, w ;put counter value in W
call Correct_Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Correct_Wait
call LCD_Char
incf count, f
goto Message2
Correct_Wait call Delay255
call Delay255
call Delay255
call Delay255
goto Init2
Init2 call LCD_Init ;setup LCD
clrf count ;set counter register to zero
Messagelaas movf count, w ;put counter value in W
call Text2 ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Main
call LCD_Char
incf count, f
goto Messagelaas
Wrong2 call LCD_Clr
clrf count ;set counter register to zero
Messagelaas1 movf count, w ;put counter value in W
call Wrong_Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Wrong_Wait2
call LCD_Char
incf count, f
goto Messagelaas1
Wrong_Wait2 call Delay255
call Delay255
call Delay255
call Delay255
goto Init
Correct2 call LCD_Clr
clrf count ;set counter register to zero
Messagelaas2 movf count, w ;put counter value in W
call Correct_Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Correct_Wait2
call LCD_Char
incf count, f
goto Messagelaas2
Correct_Wait2 call Delay255
call Delay255
call Delay255
call Delay255
goto Init2
Main movlw d'1'
call LCD_Line2W ;move to 2nd row, 2nd column
call LCD_CurOn
call Chk_Keys ;wait for key
movwf key1 ;store first digit
call LCD_Char
call Chk_Keys ;wait for key
movwf key2 ;store second digit
call LCD_Char
call Chk_Keys ;wait for key
movwf key3 ;store third digit
call LCD_Char
call Chk_Keys ;wait for key
movwf key4 ;store fourth digit
call LCD_Char
call LCD_CurOff
Chk_Code movf code1, w ;test first digit
subwf key1, w
btfss STATUS, Z
goto Wrong
movf code2, w ;test second digit
subwf key2, w
btfss STATUS, Z
goto Wrong
movf code3, w ;test third digit
subwf key3, w
btfss STATUS, Z
goto Wrong
movf code4, w ;test fourth digit
subwf key4, w
btfss STATUS, Z
goto Wrong
goto Correct