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.

switch how do you save the key press

Status
Not open for further replies.
You do not have to use a stamp to use basic or other higher language. See the SourceBoost series of compilers. Free for up to 2k programs, quite reasonable for unlimited.
I Know I just haven't found what i like. And I don't think i should start with just
basic or C I want to learn assembly I would of had hi-tech C I like it. But I lost my Job thay close the plant I worked at. Can't buy it now lol. I'm going to try SourceBoost
It looks good thank you russ and Swordfish Basic when my pic18f's get here
 
More on SourceBoost

SourceBoost also has a C, a C++ and more. All pretty much the same deal. I think they work on the 16 and 18 chips ( not optimized for the 18 ). Take a look at **broken link removed** if you choose C, or maybe just for info if you do not.
 
Some thing like this
Code:
	list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 

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

      	cblock 0x20
   		InBuffer
		combo1
		combo2
		combo3
		combo4
		dbctr
		swlatch
                NoGo
		d1
		d2

	endc
		org   	0x0000      	; org sets the origin, 0x0000
        goto    Start   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	Start

Start		

		movlw   07h            		; Set GPIO <2:0) to
                movwf   CMCON0          	; digital I/O
		clrf   	ANSEL           	        ; digital I/0
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
		banksel	GPIO
		clrf	GPIO	  

getinput
        movlw   InBuffer        ; 4 character input buffer address
        movwf   FSR             ; FSR = &InBuffer
getnext
        call    getbutton       ; get a button press
        movwf   INDF            ; add to buffer (1, 2, 4, or 8)
        incf    FSR,F           ;
        movlw   InBuffer+4      ;
        xorwf   FSR,W           ; all 4 buttons added?
        bnz     getnext         ; no, branch, else,
chkcombo
        movf    InBuffer+0      ; W = InBuffer[0]
        xorlw   combo1          ; same as combination key 1?
        bnz     NoGo              ; no, branch, else
        movf    InBuffer+1      ; W = InBuffer[1]
        xorlw   combo2          ; same as combination key 2?
        bnz     NoGo              ; no, branch, else
        movf    InBuffer+2      ; W = InBuffer[2]
        xorlw   combo3          ; same as combination key 3?
        bnz     NoGo             ; no, branch, else
        movf    InBuffer+3      ; W = InBuffer[3]
        xorlw   combo4          ; same as combination key 4?
        bnz     NoGo            ; no, branch, else
;
;  we've got a good combo
;
getbutton
        movlw   20              ; reset debounce counter
        movwf   dbctr           ; to 20 msecs
dbdelay 
        call      DelayCy         ; use 1 msec sample interval
        comf    GPIO,W          ; sample active low switches
        andlw   0x0F            ; sample only b3..b0 bits
        xorwf   swlatch,W       ; a difference (press or release)?
        bz      getbutton       ; no, branch (reset), else
        decfsz  dbctr,f         ; debounced? yes, skip, else
        goto    dbdelay         ; sample again
        xorwf   swlatch,F       ; update debounced switch state latch
        andwf   swlatch,W       ; a debounced "new press"?
        bz      getbutton       ; no, branch (a "new release"), else
        return                  ; returns W = 1, 2, 4, or 8

DelayCy			;998 cycles
		movlw	0xC7
		movwf	d1
		movlw	0x01
		movwf	d2
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
		goto	$+1


	END                       ; directive 'end of program'
I need a delay named DelayCy
 
Last edited:
I tried it like Pommie I'll see how this works
Code:
	list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 	
	cblock 0x20
		KeyBuffer:4
		Keys
		Previous
		codevalue
		d1
		d2
	endc
	org   	0x0000      	; org sets the origin, 0x0000
        goto    main   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	main
	
main
		movlw   07h            		; Set GPIO <2:0) to
                movwf   CMCON0          	; digital I/O
		clrf   	ANSEL           	; digital I/0
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
		banksel	GPIO
		clrf	GPIO	  
		clrf	Previous
		movlw	KeyBuffer
		movwf	FSR
		movlw	b'1001'
		movwf	codevalue
open
		call   	KeyLoop
                subwf  	codevalue, W      ; is it same as code?
                btfss  	STATUS, Z         ; zero set if yes
                goto   	open
                call 	ledOn         ; frist thing to do
                goto 	open

KeyLoop		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
		xorlw	0xff		;1 = key pressed
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later
		xorwf	Previous,W	;find keys that have changed
		andwf	Keys,W		;and are currently pressed
		btfsc	STATUS,Z	
		goto	KeyLoop
		movwf	INDF		;store the key
		incf	FSR,f		;move pointer forward
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
		goto	KeyLoop
;here KeyBuffer will contain 4 key values.
ledOn
		banksel	GPIO		;turn on led on GP5
		bsf     GPIO,GP5 
		 



Delay10mS		        	;9998 cycles
		movlw	0xCF
		movwf	d1
		movlw	0x08
		movwf	d2
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
	goto	$+1

 end
I wish I was smarter. more of my mom would of helped lol
 
Last edited:
Well I'm still dum as a coal bucket I don't think this part is right how do I load the value to compare
Code:
		movlw	b'1001'
		movwf	codevalue
open
		call   	KeyLoop
                subwf  	codevalue, W      ; is it same as code?
                btfss  	STATUS, Z         ; zero set if yes
                goto   	open
                call 	ledOn         ; frist thing to do
                goto 	open
 
You code is going to crash as you have subroutines without a return, especially the delay routine. When it has completed the delay it will continue executing the code after it which is just empty space. Whenever you call a piece of code it has to have a return instruction to go back to the instruction after the calling instruction. See **broken link removed**.

Mike.
 
Last edited:
Thanks that's a good site. I played a little with my code last night and found where it was getting lost at the delay I added the return like you said. I found a lock that use's a 16f84
on picklist but i gave away all my 16f84 and that code would be hard to port to the 12f683
it save's the key press to porta. It help with the buffer I think I'm getting it 1 bit at time.
Thanks agin Mike for the help
 
I just had a play with your code and put some returns in and a test for the 4 key pushes.

See if this makes any sense,

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

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 	
	cblock 0x20
		KeyBuffer:4
		Keys
		Previous
		codevalue
		d1
		d2
	endc
	org   	0x0000      	; org sets the origin, 0x0000
        goto    main   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	main
	
main
		movlw   07h            		; Set GPIO <2:0) to
                movwf   CMCON0          	; digital I/O
		clrf   	ANSEL           	; digital I/0
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
		banksel	GPIO
		clrf	GPIO	  
		clrf	Previous
GetLoop		movlw	KeyBuffer
		movwf	FSR
		movlw	b'1001'
		movwf	codevalue
		call   	KeyLoop

		movfw	KeyBuffer	;test the first key press
		xorlw	b'0001'		;was it key 1	
		btfss	STATUS,Z	;yes so skip
		goto	GetLoop		;no so go back and get new keys

		movfw	KeyBuffer+1	;test the second key press
		xorlw	b'0010'		;2
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+2	;test the third key press
		xorlw	b'0100'		;3
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+3	;test the fourth key press
		xorlw	b'0001'		;1
		btfss	STATUS,Z
		goto	GetLoop

;if it get's to here then keys 1,2,3,1 were pressed.

	;turn on LED here

                goto 	GetLoop

KeyLoop		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
		xorlw	0xff		;1 = key pressed
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later
		xorwf	Previous,W	;find keys that have changed
		andwf	Keys,W		;and are currently pressed
		btfsc	STATUS,Z	
		goto	KeyLoop
		movwf	INDF		;store the key
		incf	FSR,f		;move pointer forward
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
		goto	KeyLoop
;here KeyBuffer will contain 4 key values.
		return		 



Delay10mS		        	;9998 cycles
		movlw	0xCF
		movwf	d1
		movlw	0x08
		movwf	d2
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
		goto	$+1
		return
 end

Mike.
 
I don't need this part do I
Code:
                movlw	b'1001'
		movwf	codevalue
My buttons are low going high on press

When i get to here all need is something like this
Code:
;if it get's to here then keys 1,2,3,1 were pressed.

	;turn on LED here
                call    LedOn
                goto 	GetLoop
LedOn 
                banksel  GPIO         
                bsf        GPIO,GP5     ;turn on led on GP5
                goto      LedOn         ;keeps it in this loop for now
I tried it it didn't turn on the led
 
I don't need this part do I
Code:
                movlw	b'1001'
		movwf	codevalue
Correct.
My buttons are low going high on press

In that case remove the xorlw 0xff.
Code:
KeyLoop		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
	[COLOR="Red"];;	xorlw	0xff		;1 = key pressed <-remove[/COLOR]  
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later

Mike.
 
Last edited:
I tried this
Code:
  list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF &[COLOR="Red"] _MCLRE_OFF [/COLOR]& _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 	
	cblock 0x20
		KeyBuffer:4
		Keys
		Previous
		codevalue
		d1
		d2
	endc
	org   	0x0000      	; org sets the origin, 0x0000
        goto    main   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	main
	
main
		movlw   07h            		; Set GPIO <2:0) to
        movwf   CMCON0          	; digital I/O
		clrf   	ANSEL           	; digital I/0
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
		banksel	GPIO
		clrf	GPIO	  
		clrf	Previous
GetLoop
		call	KeyLoop
		movfw	KeyBuffer	;test the first key press
		xorlw	b'0001'		;was it key 1	
		btfss	STATUS,Z	;yes so skip
		goto	GetLoop		;no so go back and get new keys

		movfw	KeyBuffer+1	;test the second key press
		xorlw	b'0010'		;2
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+2	;test the third key press
		xorlw	b'0100'		;3
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+3	;test the fourth key press
		xorlw	b'0001'		;1
		btfss	STATUS,Z
		goto	GetLoop
		[COLOR="Red"]call    LedOn[/COLOR]
;if it get's to here then keys 1,2,3,1 were pressed.

	;turn on LED here
[COLOR="Red"]
LedOn	
		banksel	GPIO
		bsf	GPIO,GP5	
     	        goto    LedOn[/COLOR]
KeyLoop		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
		xorlw	0xff		;1 = key pressed
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later
		xorwf	Previous,W	;find keys that have changed
		andwf	Keys,W		;and are currently pressed
		btfsc	STATUS,Z	
		goto	KeyLoop
		movwf	INDF		;store the key
		incf	FSR,f		;move pointer forward
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
		goto	KeyLoop
;here KeyBuffer will contain 4 key values.
		return		 



Delay10mS		        	;9998 cycles
		movlw	0xCF
		movwf	d1
		movlw	0x08
		movwf	d2
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
		goto	$+1
		return
 end
change my switches to high going low on press
still can't get it to work
 
Last edited:
Hi be80be,
You are missing few lines of code (red color)
Code:
		banksel	TRISIO
		movwf	TRISIO
[COLOR="Red"]	clrf   	ANSEL     	; bank 1, digital I/0
[/COLOR]		banksel	GPIO
		clrf	GPIO	  
		clrf	Previous
GetLoop
[COLOR="Red"]	movlw	KeyBuffer
	movwf	FSR	;Buffer to FSR			
[/COLOR]		call	KeyLoop
		movfw	KeyBuffer	;test the first key press
 
Thanks But I have that part it's when I added the part to light the led it stays on here the whole code
Code:
     list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 	
	cblock 0x20
		KeyBuffer:4
		Keys
		Previous
		codevalue
		d1
		d2
	endc
	org   	0x0000      	; org sets the origin, 0x0000
        goto    main   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	main
	
main
		movlw   07h            		; Set GPIO <2:0) to
                movwf   CMCON0          	; digital I/O
		           	
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
                clrf   	ANSEL
		banksel	GPIO
		clrf	GPIO	  ; digital I/0
		clrf	Previous
GetLoop		movlw	KeyBuffer
		movwf	FSR
		call   	KeyLoop

		movfw	KeyBuffer	;test the first key press
		xorlw	b'0001'		;was it key 1	
		btfss	STATUS,Z	;yes so skip
		goto	GetLoop		;no so go back and get new keys

		movfw	KeyBuffer+1	;test the second key press
		xorlw	b'0010'		;2
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+2	;test the third key press
		xorlw	b'0100'		;3
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+3	;test the fourth key press
		xorlw	b'0001'		;1
		btfss	STATUS,Z
		goto	GetLoop

;if it get's to here then keys 1,2,3,1 were pressed.

	;turn on LED here

                goto 	GetLoop

KeyLoop		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
		xorlw	0xff		;1 = key pressed
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later
		xorwf	Previous,W	;find keys that have changed
		andwf	Keys,W		;and are currently pressed
		btfsc	STATUS,Z	
		goto	KeyLoop
		movwf	INDF		;store the key
		incf	FSR,f		;move pointer forward
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
		goto	KeyLoop
		call    LedOn

;here KeyBuffer will contain 4 key values.
		return		 
LedOn	
		banksel	GPIO
		bsf	GPIO,GP5	
     	        goto    LedOn
		return
		

Delay10mS		        	;9998 cycles
		movlw	0xCF
		movwf	d1
		movlw	0x08
		movwf	d2
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
		goto	$+1
		return
 end
I still think I need to use a shallow copy off GPIO so the led is just updated on key press.
 
Last edited:
if you have not assigned "clrf ANSEL" in bank 1, it not turn to digital IO.
as analog pin you can not get key press/release
Code:
      clrf ANSEL   ;still analog IO pin
 
       ;banksel 0x81 = banksel TRISIO = banksel ANSEL
      banksel ANSEL  ;bank 1
      clrf   ANSEL      ;turn to digital IO pin 
      bansel  0          ;bank 0
 
I see said the blinded man I had it before it should be here
Code:
movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
                clrf   	ANSEL
the led came on when I pressed the button Thats hope Five0 have you tried this sim
Oshon Software Homepage
 
I changed the code but I'm still missing something it reads the 4 keys but it dosen't start the main code which is just to turn on GP4 for now
Code:
   list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 	
	cblock 0x20
		KeyBuffer:4
		Keys
		Previous
		codevalue
		d1
		d2
	endc
	org   	0x0000      	; org sets the origin, 0x0000
        goto    main   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	main
	
main:
		movlw   07h            		; Set GPIO <2:0) to
       	movwf   CMCON0          	; digital I/O
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
		clrf   	ANSEL           	; digital I/0
		banksel	GPIO
		clrf	GPIO	  
		clrf	Previous
GetLoop:	
		movlw	KeyBuffer
		movwf	FSR
		call   	KeyLoop
		movfw	KeyBuffer	;test the first key press
		xorlw	b'1110'		;was it key 1	
		btfss	STATUS,Z	;yes so skip

		goto	GetLoop		;no so go back and get new keys
		movfw	KeyBuffer+1	;test the second key press
		xorlw	b'1101'		;2
		btfss	STATUS,Z
	
		goto	GetLoop
		movfw	KeyBuffer+2	;test the third key press
		xorlw	b'1011'		;3
		btfss	STATUS,Z
	
		goto	GetLoop
		movfw	KeyBuffer+3	;test the fourth key press
		xorlw	b'0111'		;1
		btfss	STATUS,Z
		goto	GetLoop
		goto 	Myled
[COLOR="Red"]Myled:
	
		clrf	GPIO
		bcf		GPIO,GP4
		goto	Myled[/COLOR]
;if it get's to here then keys 1,2,3,1 were pressed.

	;turn on LED here
		
         goto 	GetLoop

KeyLoop:		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
		xorlw	0xff		;1 = key pressed
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later
		xorwf	Previous,W	;find keys that have changed
		andwf	Keys,W		;and are currently pressed
		btfsc	STATUS,Z	
		goto	KeyLoop
		movwf	INDF		;store the key
		incf	FSR,f		;move pointer forward
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
		call    LedOn
		return
		

;here KeyBuffer will contain 4 key values.
		return		 
LedOn:	
		banksel	GPIO
		bsf	GPIO,GP5	
		return
		

Delay10mS:		        	;9998 cycles
		movlw	0xCF
		movwf	d1
		movlw	0x08
		movwf	d2
Delay_0:
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
		goto	$+1
		return
  end
 
Just try Oshon, but can't pass Delay10ms loop so I giveup

bottom KeyLoop your code is missing
Code:
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
 [COLOR="Red"]       goto KeyLoop
[/COLOR]		call    LedOn
		return
I am not used with "xorlw b'1011'", because I can't not set input pin to 1 as default

if GPIO input button pressed to ground then I use "movfw GPIO",
or button to V+ I use "comf GPIO,w", result keypressed =1
My key process only pressed until release, no need debounce


Code:
getkey	
       ;get key as Pressed until release
	movfw	GPIO	 ;Pull-Up keypress=1
	;comf	GPIO,w	;Pull-Down keypress=0
	andlw	0x0f
	bz	getkey	;loop until key press
	movwf	Keys		;store Key
keyon	
	movfw	GPIO		
	;comf	GPIO,w	
	andlw	0x0f
	bnz	keyon	;loop until key release
	movfw	Key	;return Key as W
	return
 
See my swiches are pulled high so there going to read as 0 when pressed so when you read GPIO 0-3 no key press it would read B'1111' and I was thinking that where I anded the
Code:
               btfss	STATUS,Z
		call    LedOn
		return
would turn a led on to tell me the I pressed 4 keys it did and seeing it returns to where it was that still makes it go threw the loop maybe I get it to work to nite got to go to work
 
Last edited:
Ok I tried it the way Mike had it changed my swiches to low going high on press
when you press the 4 keys the Led will not come on I don't get it do I need to compare
the KeyBuffer ??
here the code
Code:
list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions

	errorlevel  -302          ; suppress message 302 from list file

	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 	
	cblock 0x20
		KeyBuffer:4
		Keys
		Previous
		codevalue
		d1
		d2
	endc
	        org   	0x0000      	; org sets the origin, 0x0000
                goto    main   		; go to beginning of program 
		org	  	0x0004			;interrupt vector
		goto 	main
	
main
		movlw   07h            		; Set GPIO <2:0) to
                movwf   CMCON0          	; digital I/O
		movlw	b'001111'
		banksel	TRISIO
		movwf	TRISIO
		clrf   	ANSEL           	; digital I/0
		banksel	GPIO
		clrf	GPIO	  
		clrf	Previous
GetLoop		movlw	KeyBuffer
		movwf	FSR
		movlw	b'1001'
		movwf	codevalue
		call   	KeyLoop

		movfw	KeyBuffer	;test the first key press
		xorlw	b'0001'		;was it key 1	
		btfss	STATUS,Z	;yes so skip
		goto	GetLoop		;no so go back and get new keys

		movfw	KeyBuffer+1	;test the second key press
		xorlw	b'0010'		;2
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+2	;test the third key press
		xorlw	b'0100'		;3
		btfss	STATUS,Z
		goto	GetLoop

		movfw	KeyBuffer+3	;test the fourth key press
		xorlw	b'0001'		;1
		btfss	STATUS,Z
		goto	GetLoop

;if it get's to here then keys 1,2,3,1 were pressed.

	;turn on LED here
LedOn	
		banksel	GPIO
		bsf	    GPIO,GP5	;turn on a led and hang out here
		goto	LedOn

                goto 	GetLoop

KeyLoop		
		call	Delay10mS	;debounce delay
		movfw	Keys		;keep copy of previous keys
		movwf	Previous
		movfw	GPIO		;get key state
		xorlw	0xff		;1 = key pressed
		andlw	0x0f		;keep only 0-3 bits  <-added
		movwf	Keys		;save for later
		xorwf	Previous,W	;find keys that have changed
		andwf	Keys,W		;and are currently pressed
		btfsc	STATUS,Z	
		goto	KeyLoop
		movwf	INDF		;store the key
		incf	FSR,f		;move pointer forward
		movfw	FSR		    ;see if we have 4 keys yet
		xorlw	KeyBuffer+4
		btfss	STATUS,Z
		goto	KeyLoop
;here KeyBuffer will contain 4 key values.
		return		 



Delay10mS		        	;9998 cycles
		movlw	0xCF
		movwf	d1
		movlw	0x08
		movwf	d2
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_0

			;2 cycles
		goto	$+1
		return
 end
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top