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.

Nigel's tutorial no.9 explained for me please?

Status
Not open for further replies.

mr Clauds

New Member
Hey guys

I've learnt so much here already but am a little stuck on the details of the code below...
I am a beginner so please have some patience with me... thanks

Could someone answer the following in red?

RB0 - RB3 have resistors to +ve

...
KEY_PORT Equ PORTB ;keypad port
KEY_TRIS Equ TRISB
Col1 Equ 0 ;pins used for keypad inputs
Col2 Equ 1
Col3 Equ 2
Col4 Equ 3
...

SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0x0F ;set keypad pins
movwf KEY_TRIS ;half in, half out
movwf TRISB

.........

Chk_Keys movlw 0x00 ;wait until no key pressed
movwf KEY_PORT ;set all output pins low
movf KEY_PORT, W
andlw 0x0F ;mask off high byte
sublw 0x0F
btfsc STATUS, Z ;test if any key pressed
goto Keys ;if none, read keys
call Delay20
goto Chk_Keys ;else try again
(With the resistors on the inputs, that makes the inputs 1 all the time right?
Then if a key is pressed, it takes a 1 to the corresponding output changing the value, thereby changing the status of z?
)




Keys call Scan_Keys
movlw 0x10 ;check for no key pressed
(Dont understand the 0x10 above?)

subwf key, w
btfss STATUS, Z
goto Key_Found
call Delay20
goto Keys
Key_Found movf key, w
andlw 0x0f
call Key_Table ;lookup key in table
movwf key ;save back in key
return ;key pressed now in W

Scan_Keys clrf key
movlw 0xF0 ;set all output lines high
movwf KEY_PORT
(will it be b'11111111' ? )

movlw 0x04
movwf rows ;set number of rows
bcf STATUS, C ;put a 0 into carry
Scan rrf KEY_PORT, f
bsf STATUS, C ;follow the zero with ones
(Dont understand the above exactly? )

;comment out next two lines for 4x3 numeric keypad.
btfss KEY_PORT, Col4
goto Press
incf key, f
btfss KEY_PORT, Col3
goto Press
incf key, f
btfss KEY_PORT, Col2
goto Press
incf key, f
btfss KEY_PORT, Col1
goto Press
incf key, f
decfsz rows, f
goto Scan
Press return

(What im confused about is this...
where and how is the program checking for a 1 or 0 on portb to decide which key has been pressed?
The resistors make RB0-3 a value of 1 correct? so then having RB4-7 as an output does what?
)


Im trying to understand this at the most detailed level so I can learn how and why, which will lead me to be able to apply the knowledge and not just have a solution for my current problem :)
Thanks for all your explanation and patience
 
Hi,

Doubtless Nigel will be along to answer your points, but do re-read his tutorial description a few more times as it does clearly describe what is happening, though it can be a bit difficult to follow.

Have a look at this jpeg and try and follow the logic of just one switch.
The resistor pulls up the input to 1 , applying a 0 to the output will only change the Input if the switch is pressed so pulling the input down to 0.

The Status Z is changed by the Result of the preceeding instruction, not by it testing the key port.
 

Attachments

  • key.jpg
    key.jpg
    4.3 KB · Views: 225
Here I made it more readable

Code:
RB0 - RB3 have resistors to +ve

...
KEY_PORT	Equ	PORTB	 ;keypad port
KEY_TRIS	Equ	TRISB
Col1	 	Equ	0	 ;pins used for keypad inputs
Col2	 	Equ	1
Col3	 	Equ	2
Col4	 	Equ	3
...

SetPorts	bsf STATUS,	 RP0	;select bank 1
		movlw	0x0F	 	;set keypad pins
		movwf	KEY_TRIS	;half in, half out
		movwf	TRISB

.........

Chk_Keys 	movlw 0x00 		;wait until no key pressed 
		movwf KEY_PORT 		;set all output pins low 
		movf KEY_PORT, W 
		andlw 0x0F 		;mask off high byte 
		sublw 0x0F 
		btfsc STATUS, Z 	;test if any key pressed 
		goto Keys 		;if none, read keys 
		call Delay20 
		goto Chk_Keys 		;else try again 

;Your comments		
;With the resistors on the inputs, that makes the inputs 1 all the time right?
;Then if a key is pressed, it takes a 1 to the corresponding output changing the value, thereby changing the status of z?

Keys 		call Scan_Keys 
		movlw 0x10 		;check for no key pressed
					;Dont understand the 0x10 above?
					; If there is no keypress key = 0x10 (16 keys)
		subwf key, w 		; if you sub 16 with 16 you get zero..
		btfss STATUS, Z 	
		goto Key_Found 		; <- if not zero then there was a keypress
		call Delay20 		
		goto Keys 		; <- otherwise there wasn't!
Key_Found 	movf key, w 
		andlw 0x0f 
		call Key_Table 		;lookup key in table 
		movwf key 		;save back in key 
		return 			;key pressed now in W 

Scan_Keys 	clrf key 
		movlw 0xF0 		;set all output lines high 
		movwf KEY_PORT		;(Key port = '1111' top nibble )
		movlw 0x04 
		movwf rows 		;set number of rows 
		bcf STATUS, C 		;put a 0 into carry 
		
Scan 		rrf KEY_PORT, f 	; key port = 0111 then 1011 then 1101 and finally 1110
		bsf STATUS, C 		; follow the zero with ones 
					; Remember that rrf shifts in the carry.

		;comment out next two lines for 4x3 numeric keypad. 
		btfss KEY_PORT, Col4 	; was it column 4 ?
		goto Press 
		incf key, f 
		btfss KEY_PORT, Col3 	; was it column 3 ?
		goto Press 
		incf key, f 
		btfss KEY_PORT, Col2    ; was it column 2 ?
		goto Press 
		incf key, f 
		btfss KEY_PORT, Col1    ; was it column 1 ?
		goto Press 
		incf key, f 
		decfsz rows, f 		; None must be on next row
		goto Scan 		; try again
Press 		return 			; Found it return key (running total)

Its pretty straight forward

Cheers Ian
 
Last edited:
Thank you so much guys... makes perfect sense now...
Was stuck in the idea of a 1 on input as the trigger, but now see that taking it to zero is the trigger :)

Just out of curiosity, is there a particular reson that it wouldn't be a good idea to have everything zeros, rotate a 1 on the outputs and then look for a 1 on the inputs with resistors to ground?

Or is it the same thing and it's the programmers choice?

Thanks so much
Clauds
 
Just out of curiosity, is there a particular reson that it wouldn't be a good idea to have everything zeros, rotate a 1 on the outputs and then look for a 1 on the inputs with resistors to ground?

You can do it either way but as the pic has internal pullups, it's cheaper to use pullups.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top