I have a programming assignment that I believe to be pretty hard. I have to make a PIC microcontroller program for a Keypad Entry Access Control System. The access control system consists of a five-button keypad (1,2,3,4 and enter), an electronically controlled door lock, and a PIC microcontroller. The control logic for the system will be inside the microcontroller. So the code below is what I have as of now, but I'm having trouble coming up with two last subroutines(update_passcode and compare_pass_code).
Update_passcode is supposed to update the code stored in location 0x20 using a specific method. The updating process simply left shifts the entered pass code by 2 bits and adds this number to the 2-bits representing the last key pressed. When the Enter key is pressed, the program does not update the entered pass code, but instead compares the entered pass code first to the supervisor’s code (0x1B). If the entered code is not the supervisor’s code then the entered pass code is compared to each entry in its list of authorized pass codes, which begins at location 0x30. I can't assume that there will be at least one authorized pass code as the authorized pass code list will be empty upon power-up.
The inputs for the update_passcode will be:
"last_key_pressed" stored at location 0x4F (The interrupt handling routine places the number pressed at the location 0x4F).
It will output:
"entered_pass_code" stored at location 0x20 - The updated pass code (in the format described above) should be placed at location 0x20.
The second subroutine I'm having trouble with is compare_pass_code. This is supposed to compare the entered pass code, stored at location 0x20, first to the supervisor’s pass code (0x1B) and then, assuming the supervisor’s code was not entered and that num_pass_codes > 0, to each of the authorized pass codes beginning at location 0x30. If the entered pass code is the supervisor’s code, then the supervisor_mode flag output is set to 0x01. This subroutine will use this flag to recognize that the next entered pass code should be added to the authorized pass code list instead of being compared to the entries in the list.
The inputs will be:
"entered_pass_code" at locations 0x20 - The entered pass code is stored at location 0x20.
"num_pass_codes" stored at location 0x21 - The number of authorized pass codes is stored at location 0x21.
"auth_pass_codes" stored at location 0x30 - Authorized pass codes are stored beginning at location 0x30.
"supervisor_mode" stored at location 0x42 - Your compare_pass_code subroutine may use the value of location 0x42 to determine if the entered pass code should be added to the authorized pass code list.
Outputs:
"success" stored at location 0x40 - A one (0x01) should be stored at location 0x40 if the entered pass code is found in the list of authorized pass codes. Otherwise the location 0x40 should be cleared.
"supervisor_mode" stored at location 0x42 - A one (0x01) should be stored in location 0x42 if the entered pass code equals the supervisors pass code (0x1B).
Again, I think this program is extremely hard so I understand if you guys don't understand how to do this. Let me know if you need any more information. I appreciate all the help anyone gives me.
Update_passcode is supposed to update the code stored in location 0x20 using a specific method. The updating process simply left shifts the entered pass code by 2 bits and adds this number to the 2-bits representing the last key pressed. When the Enter key is pressed, the program does not update the entered pass code, but instead compares the entered pass code first to the supervisor’s code (0x1B). If the entered code is not the supervisor’s code then the entered pass code is compared to each entry in its list of authorized pass codes, which begins at location 0x30. I can't assume that there will be at least one authorized pass code as the authorized pass code list will be empty upon power-up.
The inputs for the update_passcode will be:
"last_key_pressed" stored at location 0x4F (The interrupt handling routine places the number pressed at the location 0x4F).
It will output:
"entered_pass_code" stored at location 0x20 - The updated pass code (in the format described above) should be placed at location 0x20.
The second subroutine I'm having trouble with is compare_pass_code. This is supposed to compare the entered pass code, stored at location 0x20, first to the supervisor’s pass code (0x1B) and then, assuming the supervisor’s code was not entered and that num_pass_codes > 0, to each of the authorized pass codes beginning at location 0x30. If the entered pass code is the supervisor’s code, then the supervisor_mode flag output is set to 0x01. This subroutine will use this flag to recognize that the next entered pass code should be added to the authorized pass code list instead of being compared to the entries in the list.
The inputs will be:
"entered_pass_code" at locations 0x20 - The entered pass code is stored at location 0x20.
"num_pass_codes" stored at location 0x21 - The number of authorized pass codes is stored at location 0x21.
"auth_pass_codes" stored at location 0x30 - Authorized pass codes are stored beginning at location 0x30.
"supervisor_mode" stored at location 0x42 - Your compare_pass_code subroutine may use the value of location 0x42 to determine if the entered pass code should be added to the authorized pass code list.
Outputs:
"success" stored at location 0x40 - A one (0x01) should be stored at location 0x40 if the entered pass code is found in the list of authorized pass codes. Otherwise the location 0x40 should be cleared.
"supervisor_mode" stored at location 0x42 - A one (0x01) should be stored in location 0x42 if the entered pass code equals the supervisors pass code (0x1B).
Again, I think this program is extremely hard so I understand if you guys don't understand how to do this. Let me know if you need any more information. I appreciate all the help anyone gives me.
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
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
update_passcode
compare_pass_code
end