Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Still Stuck on inputs

Status
Not open for further replies.

Darkstar64

New Member
Hey everyone once again this is related to the Cube project im working on im trying to do some switch inputs to run some code and have been following a few tutorials for debounce of a switch and the assembly code to read the bit of a pin here is what I have so far should it work fine or can I make improvments ?


Code:
;******** Main Code

start
		movlw	b'101000'	; Configure only GP3 and GP5 as a input
		tris	GPIO
		
loop

waitdn	btfsc	GPIO,3		; Wait untill button is pressed on GP3 ( GP3 low )
		goto	waitdn

		call	Cycle		; Cycle Rubroutine

		movlw	.2
		pagesel delay10
		call	delay10		; Delay of 20ms to debounce GP3 ( GP3 low )
		pagesel $

waitdn2	btfsc	GPIO,5		; Wait untill button is pressed on GP5 ( GP5 low )
		goto	waitdn2

		call	Rain		; Rain Subroutine

		movlw	.2
		pagesel delay10
		call	delay10		; Delay of 20ms to debounce GP5 ( GP5 low )
		pagesel $

		goto	loop
 
You would need to handle the case of someone (you) pushing the button for say a 1/4 of a second. Unless your CYCLE and RAIN take more than that time, -- which presumably they don't because you come BACK from them and stick in 20ms delay... then you are basically ignoring debounce because cycle and rain take care of that.

I would think on return from your routine, you would want to check for button UP, in a loop, that way it STOPS while the button is pushed, THEN do your 20ms delay, THEN loop back.

Also just to check your logic, you WANT to wait for button 3, ignoring button 5, THEN wait for button 5, ignoring button 3? That's OK if that's what you want. If they must be done alternately, you're fine.

In many cases it might be testing of "any" button, in which case you don't loop, but basically, "test button 1, skip if up", <go to button 1 routine> then "test button 2, skip if up" <go to button 2 routine> etc.

As I believe was previously mentioned, you could set up the ports to "interrupt on change" but that's certainly more advanced programming, wait for another time to try that ;-)

You MIGHT also add -- just for grins - a test if BOTH buttons are pressed, that does a "reset" - returns to some known state, etc. Then if you want to "go nuts" you could do diff things based upon how LONG a button was pressed (Tap? or PUSHHHH?), but perhaps not needed for THIS example.

Good luck!
 
Let me start with some questions:

1. You don't need to debounce the pushbuttons if your subroutines (Cycle, Rain) take so long that for sure the pushbutton is released. So are they long routines? (like they start LEDs flashing in a certain way, and do so for 20 seconds etc)

2. If you must do CYCLE then RAIN then CYCLE then RAIN then your code is good, you don't need any debounce, because you'll be changing buttons so you could hold one for 15 seconds, and it wouldn't matter (because after running that part, it waits for the OTHER button and could care less if the first button is still down).

3. IF you want to run EITHER routine, then you'd do something like:

Code:
start
        movlw   b'101000'       ; Configure only GP3 and GP5 as a input
        tris    GPIO

        goto    testbut

loop
waitup  movlw   .2
        call    delay10         ; Delay of 20ms to debounce EITHER switch
        btfsc   GPIO,3          ; Is switch 3 pressed?
        goto    waitup          ;       Yes, wait 20ms and test again
        btfsc   GPIO,5          ; Is switch 5 pressed?
        goto    waitup          ;       Yes, wait 20ms and test again
                                 ; At this point both switches are up

testbut btfss   GPIO,3          ; skip if button NOT pressed on GP3 ( GP3 low )
        goto    got3
        btfsc   GPIO,5          ; skip if button IS pressed on GP5 ( GP5 low )
        goto    testbut         ;       Otherwise wait for either button


got5    call    Rain            ; Rain Subroutine
        goto    waitup          ;       ensure button up on return from RAIN

got3    call    Cycle           ; Cycle Rubroutine

        goto    waitup          ;       ensure button up on return from CYCLE


        goto    loop
 
Ok thanks for all the help to make this project a reality this is the code I have so far it complies fine can you just check to make sure lets say button 1 is pressed then released right after it runs the counter witch runs the rain subroutine 13 times and when button 2 is pressed it runs counter2 witch runs Sam 13 times I am starting to get how everything is done on the PIC and I am a really fast leaner as long as I understand how its being done its very eay for me to understand it and rewrite something too do something ealse and this is my first PIC project so im very happy with the resualts just want to make sure everything is going to work properly here is the final code

Code:
    	list	p=12F509	; list directive to define processor
#include	<p12F509.inc> 		; processor specific variable definitions

		__config _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

; '__CONFIG' directive is used to embed configuration word within .asm file.  
; The lables following the directive are located in the respective .inc file.   
; See respective data sheet for additional information on configuration word.  


		cblock	0x07
;***** VARIABLE DEFINITIONS  
dc1		; Delay Loop Counters
dc2		
dc3
cv1		; Loop Counter Variables
cv2
cv3
shadow	; Shadow variable used in rain to keep all top leds on or for cycle to resest all bits to 0
delaytime	; Adjustable delay variable		
		endc


;************************************************* *********************  
; Internal RC calibration value is placed at location 0x3FF by Microchip  
; as a movlw k, where the k is a literal value.  

		org	0
MAIN		
		movwf	OSCCAL		; update register with factory cal value 


;******** Main Code

start
        movlw   b'101000'       ; Configure only GP3 and GP5 as a input
        tris    GPIO

        goto    testbut

loop
waitup  movlw   .2
        call    delay10         ; Delay of 20ms to debounce EITHER switch
        btfsc   GPIO,3          ; Is switch 3 pressed?
        goto    waitup          ;       Yes, wait 20ms and test again
        btfsc   GPIO,5          ; Is switch 5 pressed?
        goto    waitup          ;       Yes, wait 20ms and test again
                                 ; At this point both switches are up

testbut btfss   GPIO,3          ; skip if button NOT pressed on GP3 ( GP3 low )
        goto    got3
        btfsc   GPIO,5          ; skip if button IS pressed on GP5 ( GP5 low )
        goto    testbut         ;       Otherwise wait for either button


got5    call    counter            ; Calls counter Subroutine that loops the subroutine X number of times
        goto    waitup          ;       ensure button up on return from counter

got3    call    counter2           ; Calls counter2 Subroutine that loops the subroutine X number of times

        goto    waitup          ;       ensure button up on return from counter2


        goto    loop

;******************* Loops the code X # of times to change the loop amout change .13 or # to amount of times you want looped

counter
		movlw	.13		; Loops 13 times
		movwf	cv1		; Writes 13 to cv1
cv5		call	Rain	; Calls the Rain Subroutine
		decfsz	cv1,f	; Decrement counter is set to 13
		goto	cv5	    ; If Decrement counter is not 0 then repeats loop

counter2
		movlw	.13		; Loops 13 times
		movwf	cv3		; Writes 13 to cv1
cv4		call	Sam	    ; Calls the Sam Subroutine
		decfsz	cv3,f	; Decrement counter is set to 13
		goto	cv4	    ; If Decrement counter is not 0 then repeats loop





;******** Main Subroutine's / Effects

Cycle
		movlw	.5
		movwf	delaytime
		movlw	b'000000'
		movwf	shadow
		call	lightledA
		call	lightledB
		call	lightledC
		call	lightledD
		call	lightledE
		call	lightledF
		call	lightledG
		call	lightledH
		call	lightledI
		call	lightledJ
		call	lightledK
		call	lightledL
		goto	Cycle

Rain

		movlw	b'000000'
		movwf	shadow
		movlw	.2
		movwf	delaytime
		call	lightledA
		call	lightledD
		call	lightledG
		call	lightledJ
		movlw	.9
		call	delay10
		movlw	.3
		movwf	delaytime
		call	lightledC
		call	lightledF
		call	lightledI
		call	lightledL
		movlw	.9
		call	delay10
		movlw	.9
		call	delay10
		movlw	.9
		movwf	delaytime
		call	lightledA
		call	lightledD
		call	lightledG
		call	lightledJ
		movlw	.9
		call	delay10
		movlw	.9
		call	delay10
		movlw	.9
		call	delay10
		movlw	.4
		movlw	delaytime
		call	lightledB
		call	lightledE
		call	lightledH
		call	lightledK
		goto	Rain

Sam

		movlw	b'000000'
		movwf	shadow
		movlw	.1
		movwf	delaytime
		call	lightledC
		call	lightledB
		call	lightledA
		call	lightledD
		call	lightledG
		call	lightledG
		call	lightledH
		call	lightledI
		call	lightledJ
		call	lightledK
		call	lightledL
		movlw	.9
		call	delay10
		call	lightledB
		call	lightledD
		call	lightledF
		call	lightledG
		call	lightledI
		call	lightledH
		call	lightledJ
		call	lightledL
		movlw	.9
		call	delay10
		call	lightledJ
		call	lightledG
		call	lightledD
		call	lightledA
		call	lightledE
		call	lightledC
		call	lightledF
		call	lightledI
		call	lightledL
		goto	Sam
		

	
;************* Subroutines

;****************** Delay Subroutine ( 10 ms )

delay10					; Delay W x 10ms 
		movwf	dc3		; Delay = 1 + W x (3 + 10009 + 3) - 1 + 4 -> W x 10.015ms
dly2	movlw	.13		; Repeat inner loop 13 times
		movwf	dc2		; -> 13 x (767 + 3) - 1 = 10009 cycles
		clrf	dc1		; Inner loop = 256 x 3 - 1 = 767 cycles
dly1		decfsz	dc1,f
		goto	dly1
		decfsz	dc2,f		; End middle loop
		goto	dly1
		decfsz	dc3,f		; End outer loop
		goto	dly2
		retlw	0

;****************** LED Subroutines 

lightledA
		movlw	b'111010'	; Configure GP4 and GP1 as input
		tris	GPIO
		movlw	b'000001'	; Change corresponding bit of GP0 to 1
		movwf	GPIO		; Writes 1 to GP0
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change corresponding bit of GP0 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO			; Write 0 to GP0
		retlw	0

lightledB
		movlw	b'001110'	; Configure GP1 and GP2 as inputs
		tris	GPIO
		movlw	b'000001'	; Change corresponding bit of GP0 to 1
		movwf	GPIO		; Writes 1 to GP0
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP1 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledC
		movlw	b'001110'	; Configure pins GP1 and GP2 to inputs
		tris	GPIO
		movlw	b'010000'	; Change corresponding bit of GP4 to 1
		movwf	GPIO		; Writes 1 to GP4
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP4 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledD
		movlw	b'011001'	; Configure pins GP1 and GP4 to inputs
		tris	GPIO
		movlw	b'000100'	; Change corresponding bit of GP2 to 1
		movwf	GPIO		; Writes 1 to GP2
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP2 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledE
		movlw	b'011001'	; Configure pins GP0 and GP4 to inputs
		tris	GPIO
		movlw	b'000010'	; Change corresponding bit of GP1 to 1
		movwf	GPIO		; Writes 1 to GP1
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP2 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledF
		movlw	b'001101'	; Configure pins GP0 and GP2 to inputs
		tris	GPIO
		movlw	b'010000'	; Change corresponding bit of GP4 to 1
		movwf	GPIO		; Writes 1 to GP4
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP4 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledG
		movlw	b'011100'	; Configure pins GP2 and GP4 to inputs
		tris	GPIO
		movlw	b'000010'	; Change corresponding bit of GP1 to 1
		movwf	GPIO		; Writes 1 to GP1
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP0 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledH
		movlw	b'011001'	; Configure pins GP0 and GP4 to inputs
		tris	GPIO
		movlw	b'000100'	; Change corresponding bit of GP2 to 1
		movwf	GPIO		; Writes 1 to GP2
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP2 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledI
		movlw	b'001011'	; Configure pins GP0 and GP1 to inputs
		tris	GPIO
		movlw	b'000110'	; Change corresponding bit of GP1 to 1
		movwf	GPIO		; Writes 1 to GP1
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP1 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledJ
		movlw	b'011100'	; Configure pins GP2 and GP4 to inputs
		tris	GPIO
		movlw	b'001001'	; Change corresponding bit of GP0 to 1
		movwf	GPIO		; Writes 1 to GP0
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP1 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledK
		movlw	b'011001'	; Configure pins GP0 and GP4 to inputs
		tris	GPIO
		movlw	b'000010'	; Change corresponding bit of GP1 to 1
		movwf	GPIO		; Writes 1 to GP1
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP0 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0

lightledL
		movlw	b'001110'	; Configure pins GP0 and GP1 to inputs
		tris	GPIO
		movlw	b'010000'	; Change corresponding bit of GP4 to 1
		movwf	GPIO		; Writes 1 to GP4
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change correspoding bit of GP0 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO
		retlw	0
					
		end

And last but not least the compile info

Code:
----------------------------------------------------------------------
Debug build of project `C:\PIC12F509\Programs\Multi+Plexing LEDS-rev3.disposable_mcp' started.
Preprocessor symbol `__DEBUG' is defined.
Thu Aug 07 15:20:38 2008
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p12F509 "Multi+Plexing LEDS-rev3.ASM" /l"Multi+Plexing LEDS-rev3.lst" /e"Multi+Plexing LEDS-rev3.err" /d__DEBUG=1
Loaded C:\PIC12F509\Programs\Multi+Plexing LEDS-rev3.cod.
----------------------------------------------------------------------
Debug build of project `C:\PIC12F509\Programs\Multi+Plexing LEDS-rev3.disposable_mcp' succeeded.
Preprocessor symbol `__DEBUG' is defined.
Thu Aug 07 15:20:39 2008
----------------------------------------------------------------------
BUILD SUCCEEDED
 
Last edited:
Im also unsure about the delay I need if I want more then one LED on at a time say im making a name appear like John or something the LED's will have to appear on for so long say 2-3 seconds then turn off for a second then turn on again for the same amount of time and this is for each LED any ideas guys ? maby loop each letter for the 2-3 seconds like this useing this as a example its not 2-3 seconds at all but the concept is what im trying to get at this would be for the letter S would this work corretly and how many times would I need to repeat it to get 1 second then I can go off that to get more then 1 second if I need it also im not too sure that my LED Subroutines can do it since im only useing the call command and theres a delay in each one before it turns it off here is a example of lightledA to show you what I mean by this

Code:
                movlw	.13		; Loops 13 times
		movwf	cv1		; Writes 13 to cv1
cv5	        call    lightledC	  ; Letter J
		call	lightledB
		call	lightledA
		call	lightledD
		call	lightledG
		call	lightledG
		call	lightledH
		call	lightledI
		call	lightledJ
		call	lightledK
		call	lightledL
		decfsz	cv1,f	; Decrement counter is set to 13
		goto	cv5	    ; If Decrement counter is not 0 then repeats loop

Code:
lightledA
		movlw	b'111010'	; Configure GP4 and GP1 as input
		tris	GPIO
		movlw	b'000001'	; Change corresponding bit of GP0 to 1
		movwf	GPIO		; Writes 1 to GP0
		movlw	delaytime		; Get from dealytime variable
		call	delay10		; Delay of 50 x 10ms = 500ms or .5s
		movlw	shadow	; Change corresponding bit of GP0 to 0
		movwf	GPIO
		movlw	b'101000'	; Configure GP0,GP1,GP2,GP4 to outputs
		tris	GPIO			; Write 0 to GP0
		retlw	0
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top