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.

3 Inputs & 3 Outputs Coding problem

Status
Not open for further replies.

Suraj143

Active Member
Hi I have three inputs & three outputs.
PORTA1, 2, 3 – inputs
PORTB1, 2, 3 – outputs connected to 3 LED’s

The inputs coming from a digital logic IC.

Inputs coming like this

When PORTA1 = turn on PORTB1
When PORTA1 & PORTA2 = turn on PORTB2
When PORTA1 & PORTA2 & PORTA3 = turn on PORTB3

I want to detect the coming PORTA inputs. I know only to detect one input at a time & don’t know how to detect two or three inputs at a time.

Code:
SW1	btfss	PORTA,1		;check button1
	goto	SW2
	goto	LED1
SW2	btfss	PORTA,2		;check button2
	goto	SW3
	goto	LED2
SW3	btfss	PORTA,3		;check button3
	goto	SW1
	goto	LED3


LED1	bsf	PORTB,1		;turn on LED1
	goto	$-1
LED2	bsf	PORTB,2		;turn on LED2
	goto	$-1
LED3	bsf	PORTB,3		;turn on LED3
	goto	$-1

Please help me

Thanks
 
Hi,
btfss or btfsc is for checking a single bit of the register.

You can try taking the value of the whole port and compare it, for example:
movf PORTA, w
xorlw b'00000011'
btfsc STATUS, Z
goto LED2
goto SW3
 
Hi bananasiong thats the thing I needed.
It was very good & it didn't come to my mind.

I will apply your code to all three buttons it will work for sure.
I must study the other codes that I have not used before.

Thanks bananasiong.
 
How about,
Code:
	clrf	PORTB		;Turn off all LEDs
	movfw	PORTA		;Read port A
	andlw	b'00001110'	;keep only bits 1,2 and 3
	xorlw	b'00000010'	;invert bit 1
	btfsc	STATUS,Z	;if it's zero then PortA was 00000010
	bsf	PORTB,1		;Turn on LED1	
	xorlw	b'00000100'	;invert bit 2 - bits 1 and 2 are now inverted
	btfsc	STATUS,Z	;if it's zero then PortA was 00000110
	bsf	PORTB,2		;Turn on LED2
	xorlw	b'00001000'	;invert bit 3 - all three bits now inverted
	btfsc	STATUS,Z	;if it's zero then PortA was 00001110
	bsf	PORTB,3		;Turn on LED3

Not immediately obvious but if you work out what it's doing it should give you a better understanding of the xor instruction.

Mike.
 
Hi mike Thanks for your very useful coding. Now I really understand the function of XOR command. Thank you very much.

But a small question to ask when checking the second input (PORTA1 & 2)

Code:
	xorlw	b'00000110'

When checking the third input (PORTA1 & 2 & 3)

Code:
	xorlw	b'00001110'

Shouldn’t it like this?

Thanks
 
Suraj143 said:
But a small question to ask when checking the second input (PORTA1 & 2)

Code:
	xorlw	b'00000110'

When checking the third input (PORTA1 & 2 & 3)

Code:
	xorlw	b'00001110'

Shouldn’t it like this?

Thanks
Yes, if according to your first post.
 
Suraj143 said:
Hi mike Thanks for your very useful coding. Now I really understand the function of XOR command. Thank you very much.

But a small question to ask when checking the second input (PORTA1 & 2)

Code:
	xorlw	b'00000110'

When checking the third input (PORTA1 & 2 & 3)

Code:
	xorlw	b'00001110'

Shouldn’t it like this?

Thanks

No, because W is not reloaded, the previous bits stay inverted. If Port A contained '00000110' then after xorlw '00000010', W will contain '00000100'. After xorlw '00000100', W will contain zero. If you reload W from port A then your code would be correct.

Mike.
 
Some people write out those operands a little differently (below) where the 'test' value is XOR'ed with the previous 'test' value to cancel out or reverse the effects of the previous 'test' value. This might seem more intuitive since you can see the real 'test' value in the expression (the 1st value).


Code:
     clrf    PORTB          ; Turn off all LEDs
[LEFT]     movfw   PORTA          ; Read port A
     andlw   b'00001110'    ; keep only bits 1,2 and 3[/LEFT]
 
[LEFT]     xorlw   b'00000010'    ;
     skpnz                  ; 00000010? no, skip, else
     bsf     PORTB,1        ; Turn on LED1
     xorlw   b'00000110'^b'00000010'
     skpnz                  ; 00000110? no, skip, else
     bsf     PORTB,2        ; Turn on LED2
     xorlw   b'00001110'^b'00000110'
     skpnz                  ; 00001110? no, skip, else
     bsf     PORTB,3        ;Turn on LED3[/LEFT]
 
Last edited:
Wow more code to try I was wondering what to select.:D

Thanks Mike, K8LH for your coding.
I have never used skpnz. Now I’m going to place them in my normal routines.;)

And also Can you tell me what’s the meaning of “^” character.
 
Pommie said:
No, because W is not reloaded, the previous bits stay inverted. If Port A contained '00000110' then after xorlw '00000010', W will contain '00000100'. After xorlw '00000100', W will contain zero. If you reload W from port A then your code would be correct.

Mike.

Oh I see now I understood.

Thanks Mike for your well support.
 
Suraj143 said:
I have never used skpnz. Now I’m going to place them in my normal routines.;)

And also Can you tell me what’s the meaning of “^” character.
Hi,
"^" is XOR, you can test and see the result in disassembly listing.
While for skpnz, you can refer to the attachment.
 

Attachments

  • PIC_Instruction_Reference.pdf
    116 KB · Views: 360
Oh I see it’s a XOR function. Your PDF contains many new instructions. It was very helpful & useful for a beginner.

Thank you very much banansiong.
 
Hi I have configured my inputs to THREE buttons that is RA4, RA5, RA6.
They are active low inputs (used 10K pull up resistors for each)

But when I run this code all the time the LED2 is turn ON. & my code was not working well.

I have missed something.
Please help me

Thanks

Code:
		org	0x00
		movlw	0x07
		movwf	CMCON
		bsf	STATUS,RP0
		clrf	TRISB		
		movlw	b'01110000'	;make RA4,RA5,RA6 as inputs (active low)
		movwf	TRISA
		bcf	STATUS,RP0
		clrf	PORTA
		clrf	PORTB		
				
SW1		movfw	PORTA	
		andlw	b'01110000'	;keep only bit 4,5,6
		xorlw	b'00010000'	;invert bit 5(check button0)
		btfsc	STATUS,Z
		call	LED0
		xorlw	b'00100000'	;invert bit 6(check button1)
		btfsc	STATUS,Z
		call	LED1
		xorlw	b'01000000'	;invert bit 7(check button2)
		btfsc	STATUS,Z
		call	LED2					
		goto	SW1
		
LED0		movlw	01h
		movwf	PORTB
		return		
LED1		movlw	02h
		movwf	PORTB
		return	
LED2		movlw	04h
		movwf	PORTB
		return	
				
		end
 
Hi,
You should update w register from PORTA everytime you've changed the value in the w register. Get what I mean? Before checking button 1 and button 2, load again PORTA to w.
 
Hi You mean something like this?
Code:
SW1		movfw	PORTA	
		andlw	b'01110000'	;keep only bit 4,5,6
		xorlw	b'00010000'	;invert bit 5(check button0)
		btfsc	STATUS,Z
		call	LED0
		[B]movfw	PORTA[/B]
		xorlw	b'00100000'	;invert bit 6(check button1)
		btfsc	STATUS,Z
		call	LED1
		[B]movfw	PORTA[/B]
		xorlw	b'01000000'	;invert bit 7(check button2)
		btfsc	STATUS,Z
		call	LED2					
		goto	SW1
 
Yes, and if you're using other pins of PORTA, you might need to keep only bit 4, 5, 6 by
andlw b'01110000' ;keep only bit 4,5,6
 
Oh I see then I should add ANDLW b’01110000’ before checking the three buttons. I have added the ANDLW only for the first button. I have to add the other two also before checking them.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top