Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Thread Tools Display Modes
Old 24th November 2004, 04:25 PM   (permalink)
Default

Fire your professor. He is crazy.
JohnBrown is offline   Reply With Quote
Old 24th November 2004, 09:58 PM   (permalink)
Default

Quote:
Would you setup another FSR and INDF type thing? ...
Yes. I leave this to you to finish.

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"
motion is offline   Reply With Quote
Old 25th November 2004, 02:08 AM   (permalink)
Default

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.
On the other hand, putting the PIC to sleep would shut off the clocks and so the timers will also stop. The PIC would be unable to wake from sleep.
__________________
"Having to do with Motion Control"
motion is offline   Reply With Quote
Old 29th November 2004, 04:53 AM   (permalink)
Default

Quote:
Originally Posted by motion
I have several issues with your code so I don't think it will work as smoothly as predicted. Anyway as I understand it, here is some code to start the discussion:

Code:
update_passcode:
    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

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?
asmpic is offline   Reply With Quote
Old 29th November 2004, 05:01 AM   (permalink)
Default

Quote:
Originally Posted by motion
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.
On the other hand, putting the PIC to sleep would shut off the clocks and so the timers will also stop. The PIC would be unable to wake from sleep.
I'm not sure I'm understanding what you're saying. The interrupt service I have will detect the key pressed and wake the PIC from sleep mode. Also, the Watch Dog Timer (WDT) that will cause an interrupt will be disabled within MPLAB.
asmpic is offline   Reply With Quote
Old 29th November 2004, 07:26 AM   (permalink)
Default

Quote:
I have a question about the rlf, that is a rotate left shift correct?
It is "Rotate Left f through Carry". It's in the PIC16F84 datasheet.

Quote:
Wouldn't that be different than a regular left shift which I need to perform?
I don't know where you're coming from but in the PIC16F84 instruction set, RLF is the only "regular left shift" instruction. My advice is to try to understand what RLF exactly does and code accordingly. Don't get hung up on another processor's instruction set.

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 
;
can also be coded as follows with the same result:

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"
motion is offline   Reply With Quote
Old 29th November 2004, 07:55 AM   (permalink)
Default

Quote:
I'm not sure I'm understanding what you're saying. The interrupt service I have will detect the key pressed and wake the PIC from sleep mode.
Sorry. I may have mistook INTE for T0IE in the same register.

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"
motion is offline   Reply With Quote
Old 30th November 2004, 12:38 AM   (permalink)
Default

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
asmpic is offline   Reply With Quote
Old 30th November 2004, 05:44 AM   (permalink)
Default

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
And what does this subroutine do? Again, I'm not understanding the 00001111 part. Also, what does 'passcodes' do?

Quote:
Originally Posted by motion
Code:
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
For the last part, why are you using the xorwf to compare the entered passcode to the supervisor? Can't you just subtract the two (subwf) and see if the result is zero?
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!
asmpic is offline   Reply With Quote
Old 1st December 2004, 03:37 AM   (permalink)
Default

Quote:
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.
Oops. I think the intended code should be as follows:

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:
Also, why does status,Z determine if supervisor mode is set?
Oops again. Another bug. I am not used to coding this way. I normally use the macro SKPZ in my programs. It should be as follows:

Code:
    movf   supervisor_mode,w
    btfss   status,Z               ; Check if supervisor mode
    goto   change_user_passcode
The status,Z is altered when the preceding instruction "movf supervisor_mode,w" is executed. The instruction btfss status,Z tests the zero flag.

A simpler test is:

Code:
    btfsc  supervisor_mode,0
    goto   change_user_passcode
__________________
"Having to do with Motion Control"
motion is offline   Reply With Quote
Old 1st December 2004, 03:47 AM   (permalink)
Default

Quote:
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
I assume the keycode is found in lowest 2 bits in the last_key_press. Since it was read off PORTA in the ISR, the upper bits can take any value and should be masked out and they will not interfere when added to the entered_pass_code.
__________________
"Having to do with Motion Control"
motion is offline   Reply With Quote
Old 1st December 2004, 05:07 PM   (permalink)
Default

Quote:
Originally Posted by motion
Quote:
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
I assume the keycode is found in lowest 2 bits in the last_key_press. Since it was read off PORTA in the ISR, the upper bits can take any value and should be masked out and they will not interfere when added to the entered_pass_code.
I'm having trouble understanding what the subroutine "change_user_passcode" does. Does it simply store the new passcode into the passcode list?
asmpic is offline   Reply With Quote
Old 1st December 2004, 07:37 PM   (permalink)
Default

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
asmpic is offline   Reply With Quote
Old 1st December 2004, 08:20 PM   (permalink)
Default

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?
JohnBrown is offline   Reply With Quote
Old 1st December 2004, 09:41 PM   (permalink)
Default

Quote:
Originally Posted by JohnBrown
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?

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)
asmpic is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes




All times are GMT. The time now is 02:37 AM.


Electronic Circuits  |  Electronics Wiki
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.