![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
Fire your professor. He is crazy.
|
|
|
|
|
|
|
(permalink) | |
|
Quote:
Also, I must stress that there are other problems with the program. For example, the routine "update_passcode" must only be called when a key has actually been pressed. Right now, it seems that when the timer overflows, an interrupt is generated and update_passcode is called. This will cause false data to be shifted into entered_pass_code.
__________________
"Having to do with Motion Control" |
||
|
|
|
|
|
(permalink) | |
|
Quote:
__________________
"Having to do with Motion Control" |
||
|
|
|
|
|
(permalink) | |
|
Quote:
I have a question about the rlf, that is a rotate left shift correct? Wouldn't that be different than a regular left shift which I need to perform? |
||
|
|
|
|
|
(permalink) | ||
|
Quote:
|
|||
|
|
|
|
|
(permalink) | ||
|
Quote:
Quote:
Anyway, I normally group the code in bunches so that is best undestood within that context. I also separate the groups by the comment character ';'. It is the same character that terminates a line of code in C. The code group: Code:
bcf status,C
rlf entered_pass_code,f
bcf status,C
rlf entered_pass_code,f
;
Code:
rlf entered_pass_code,f
rlf entered_pass_code,f
movlw b'11111100'
andwf entered_pass_code,f
;
__________________
"Having to do with Motion Control" |
|||
|
|
|
|
|
(permalink) | |
|
Quote:
In that case, my other advice is to be careful with switch bounce. Using interrupts to process key presses, you will definitely have to deal with them. The only reason I see for using interrupts to process keypresses is to save on power by putting the PIC to sleep. You can insert a 20-50msec delay in the interrupt service before clearing INTF. This will cause additional transistions in RB0 caused by switch bounce to be ignored during the delay.
__________________
"Having to do with Motion Control" |
||
|
|
|
|
|
(permalink) |
|
I have a couple questions about some of your code.
Why do you check to see if the password is the supervisor in the update_pass_code subroutine? If you look at my original code under 'endless_loop' I first check to see if the 'Enter' key was pressed and if it is I jump to 'compare_pass_code' and if only a number was pressed I goto 'update_pass_code.' Only when a number is pressed as the last key will it update the code and when enter is pressed it will compare and see if its supervisor mode and if it is the next passcode will be added to the passcode list. Also, why does status,Z determine if supervisor mode is set? Code:
update_pass_code:
movf supervisor_mode,w
btfsc status.Z ; Check if supervisor mode
goto change_user_passcode
bcf status,C
rlf entered_pass_code,f
bcf status,C
rlf entered_pass_code,f
;
movlw b'00000011'
andwf last_key_press,w ; mask out upper bits
addwf entered_pass_code,f ; add to entered pass code
;
return
change_user_passcode:
movf num_pass_codes,w
andlw b'00001111'
addlw passcodes
movwf fsr
;
movf entered_pass_code,w
movwf indf
;
incf num_pass_codes,f
clrf supervisor_mode
;
return
compare_pass_code:
movlw supervisor_code
xorwf entered_pass_code,w ; compare to supervisor code
movlw 0
btfsc status,Z
movlw 1
movwf supervisor_mode
;
; additonal code here to compare with user pass codes
;
return
|
|
|
|
|
|
|
(permalink) | |
|
A couple more questions....sorry for asking so much...
What does the following do? What does the anding of 00000011 with 'last_key_press' accomplish? Code:
movlw b'00000011'
andwf last_key_press,w ; mask out upper bits
addwf entered_pass_code,f ; add to entered pass code
;
return
Quote:
Code:
compare_pass_code:
movlw supervisor_code
xorwf entered_pass_code,w ; compare to supervisor code
movlw 0
btfsc status,Z
movlw 1
movwf supervisor_mode
Thank you so much! |
||
|
|
|
|
|
(permalink) | ||
|
Quote:
Code:
update_passcode:
bcf status,C
rlf entered_pass_code,f
bcf status,C
rlf entered_pass_code,f
;
movlw b'00000011'
andwf last_key_press,w ; mask out upper bits
addwf entered_pass_code,f ; add to entered pass code
;
return
change_user_passcode:
movf num_pass_codes,w
andlw b'00001111'
addlw passcodes
movwf fsr
;
movf entered_pass_code,w
movwf indf
;
incf num_pass_codes,f
clrf supervisor_mode
;
return
compare_pass_code:
movf supervisor_mode,w
btfss status,Z ; Check if supervisor mode
goto change_user_passcode
movlw supervisor_code
xorwf entered_pass_code,w ; compare to supervisor code
movlw 0
btfsc status,Z
movlw 1
movwf supervisor_mode
;
; additonal code here to copare with user pass codes
;
return
Quote:
Code:
movf supervisor_mode,w
btfss status,Z ; Check if supervisor mode
goto change_user_passcode
A simpler test is: Code:
btfsc supervisor_mode,0
goto change_user_passcode
__________________
"Having to do with Motion Control" |
|||
|
|
|
|
|
(permalink) | |
|
Quote:
__________________
"Having to do with Motion Control" |
||
|
|
|
|
|
(permalink) | ||
|
Quote:
|
|||
|
|
|
|
|
(permalink) |
|
This is my new updated code. I have probably have several bugs and incorrect code so if someone can check me starting at update_pass_code that would be help tremendously. The subroutine "compare_to_list" gave me the most trouble so if someone can let me know how to fix it, that'll be great.
Code:
list P=16F84
include P16F84.INC
; Define the direction bit types
f equ 1
w equ 0
; Define the data storage locations
; These locations must NOT be modified!
entered_pass_code equ 0x20 ; the entered passcode - last four keys pressed
num_pass_codes equ 0x21 ; the number of passcodes stored
success equ 0x40 ; grant or deny access
history equ 0x41 ; history of passcodes entered
supervisor_mode equ 0x42 ; supervisor code entered -> adding new pass code to list
status_temp equ 0x4A ; temp storage of STATUS reg during subroutines
w_temp equ 0x4B ; temp storage of W during subroutines
last_key_press equ 0x4F ; last key pressed
new_num_passcodes equ 0x50
counter equ 0x10
temp_passcode equ 0x11
new_loc equ 0x12
org 0x30
passcodes res 16 ; location of the passcodes
; Define the control code for adding new users
control_code equ 0x1B
; start defining the program
; interrupts, so start at 0x30
org 0x00
goto start
; Interrupt Service Routine
org 0x04
movwf w_temp ; store the value of W
movf STATUS, w
movwf status_temp ; store the STATUS register
movf PORTA, w ; get the key pressed
movwf last_key_press; move the captured key press to reg
bcf INTCON, INTF ; clear interrupt flag
movf status_temp, w ; restore the status register's value
movwf STATUS
movf w_temp, w ; restore the W register's value
retfie
; Success or Failure Subroutine
grant_deny
movwf w_temp ; store the value of W
movf STATUS, w
movwf status_temp ; store the STATUS register
btfss success, 0
goto update_history
open_door
movlw 0x8 ; send open door signal -> RA3
movwf PORTA
movlw 0x0
movwf PORTA
update_history
bcf STATUS, 0 ; clear the carry bit to allow for shift thru carry
rlf history, f
movf success, w
addwf history, f
clrf entered_pass_code ; clear last attempt's pass code
clrf success ; clear success flag
movf status_temp, w ; restore the STATUS register
movwf STATUS
movf w_temp, w ; restore the W register
return
; Sleep subroutine
sleep_now
sleep
; nop needed after sleep command for correct interrupt handling
nop
return
; start main program
org 0x30
start
; Set-up Interrupt on RB0
bsf INTCON, GIE ; enable global interrupts
bsf INTCON, INTE ; enable RB0 interrupts
; Set-up Inputs
bsf STATUS, RP0 ; select bank 1
movlw 0x07 ; configure first 3 bits as inputs
; The following instruction generates a MESSAGE[302] warning from MPLAB - this is expected.
movwf TRISA ; load configuration into RA port
bcf STATUS, RP0 ; select bank 0
clrf history ; zero out history of successes
clrf PORTA ; clear the output on PORTA
clrf num_pass_codes ; start out with an empty authorized pass codes list
clrf supervisor_mode
; This is the main program loop that calls your subroutines.
endless_loop
call sleep_now
btfsc last_key_press, 2 ; test for Enter press
goto enter_pressed
call update_pass_code ; update the entered pass code if Enter not pressed
goto endless_loop
enter_pressed
call compare_pass_code
goto endless_loop
; Place your subroutines (compare_code & update_code) here:
update_pass_code:
movf entered_pass_code,w ; move entered passcode into w
movwf temp_passcode ; move entered passcode into new location so it won't be modified
bcf STATUS,C
rlf temp_passcode,f
bcf STATUS,C
rlf temp_passcode,f
;
movf entered_pass_code,w ; move the original entered_pass_code into w
addwf temp_passcode,w ; add to new temp_passcode, gets you the new format
call compare_pass_code
return
compare_pass_code:
movf supervisor_mode,f
btfss STATUS,Z ;check to see if supervisor_mode is 0 or 1
goto not_super
goto super
not_super
movf entered_pass_code,w
sublw 0x1B,f ; subtract entered_pass_code from supervisor's code(0x1B
btfss STATUS,Z ; check to see if they are equal(0 as answer)
call supermode
call compare_to_list
super ;store the new passcode in list
movf passcodes,w
movwf FSR
;
movf entered_pass_code,w
movwf INDF
;
incf num_pass_codes,f
clrf supervisor_mode
;
return
supermode:
movwf supervisor_mode
movlw 0x01 ;insert 1 into supervisor_mode, since the enter_pass_code matched
return
no_match
incf counter,f
incf new_num_passcodes,w
subwf num_pass_codes,f
btfss STATUS,Z
call compare_to_list
call grant_deny
compare_to_list
movlw passcodes ; set passcodes to the value in 0x30
addwf counter,w ; place passcodes into counter
movwf FSR
movf INDF,w ; get the passcode to place in temp register
movwf new_loc ; move into new location
subwf entered_pass_code,f ; compare the entered code to the list
btfss STATUS,Z ; check to see if answer equals 0
call grant_deny
goto no_match
return
|
|
|
|
|
|
|
(permalink) |
|
I'm sorry, but your program is riddled with problems. You really need to scrap it all and start afresh.
What form does the keypad take? Judging from your "code" it has a strobe connected to RB0, and two databits connected to RA0 and RA1. Am I right? If so, what are the other RA pins connected to? You will probably need to ANDLW 0x03 at some point to isolate bits 0 and 1, otherwise, when you attempt to ADD the keycode into the stored code, it won't work as you expect. You've still not fixed your interrupt routine, which trashes the STATUS register. Also, you seem to have copied the faulty context saving into your grant_deny or whatever it's called. This is complete rubbish. Do you actually have the hardware to test this on, or are you just programming into a black hole? If you have the hardware, and a means to program the PIC, then I suggest you start from scratch with something extremely simple, such as operating the door release when the ENTER key is pressed. Then you progress to entering 1234 or something similar. If you have SOMETHING that works, then it'll be far easier to progress. You're not going to get anywhere carrying on in your present manner. I'm sorry if this sounds harsh, but your professor is obviously a moron, so it's not entirely your fault. I've made my living writing code that WORKS for the last 30 years, your professor has obviously not. Who are you going to trust? |
|
|
|
|
|
|
(permalink) | |
|
Quote:
lol. The course I'm taking is just an intro course so alot of the code he provides us has obvious bugs to keep things simple and not to take into account every detail. He's only testing us on certain functions actually functioning. The code I had to write starts at the subroutine "update_pass_code" and ends with "compare_to_list" So those are the only sections I really need help with. They all can't be totally wrong (I hope) |
||
|
|
|