Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

XOR operation using if..else statement

Status
Not open for further replies.

khatus

Member level 3
Member level 3
Joined
Oct 7, 2017
Messages
64
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Activity points
1,754
Hello guys I have taken two inputs from PORTB1 and PORTB2 pins in PIC MCU through two push buttons. And I have taken one LED output in pin PORTB0. If both inputs are 1 or 0 then LED will not light up. And if one of the two push buttons is on, it will light up. This should be done using if ... else statement. But without using Bitwise XOR operator (^) .
here is my code What is wrong with my code??

Code:
void main()
{
 TRISB.F0=0;
 TRISB.F1=1;
 TRISB.F2=1;
 PORTB.F0=0;
 while(1)
 {
  if(PORTB.F1==1)
   { if(PORTB.F2==1)
    {
      PORTB.F0=0;
       }
    }
   else if(PORTB.F1==0)
   {  if(PORTB.F2==0)
    {
      PORTB.F0=0;
    }
   }
   else
    PORTB.F0=1;
} 
}

here is my simulation picture

LED_pushbutton.PNG
 

What is wrong with my code??

You could spent few seconds to post your results as something like this :
SW1(on) and SW2(on) = ?
SW1(off) and SW2(on) = ?
SW1(on) and SW2(off) = ?
SW1(off) and SW2(off) = ?
This would save other's time, and yours.

BTW, seems like you missed the else outcome for each one of the inner if(Port.F2) statements.
 

Hi,

why that much lines?

If both inputs are 1 or 0 then LED will not light up.
I´m no C specialist, so see it as "pseudo code"

Code:
if(((PORTB.F1==1) && (PORTB.F2==1)) || ((PORTB.F1==0) && (PORTB.F2==0)))
   {
   (PORTB.F0==0)
   }
   else
   {
   (PORTB.F0==1)
   }
 

It can probably be even simpler:
Code:
if(PORTB.F1 == PORTB.F2) PORTB.F0 = 0;
else PORTB.F0 = 1;

Be careful though, there is a risk of RMW (Read-Modify-Write) problems with 16F processors.

Brian.
But may be better use temporary variable to hold port data for avoiding situation when port read two times?
So code should be something like this:
Code:
temp=PORTB;
if(temp.F1 == temp.F2) PORTB.F0 = 0;
else PORTB.F0 = 1;
May be I wrong...
 

not familiar with PIC16F....
what is the configuration of the input sections of the ports used for the switches?
i would have had R2 and R3 and pull ups instead of pull downs,
with the switches pulling the inputs low instead of high.

the switch connection to Vdd has no current limit.

have you built it? if so, how does it behave?
 

Reading the port into a variable before testing the bits is the simplest way to overcome the RMW issue I mentioned in post #4.

RMW isn't specifically a PIC problem and in most cases it will work perfectly. The 16F RMW issue is caused by all the bits being read simultaneously and written simultaneously when reading or writing to the port. It means the bits you are NOT interested in are also read and written. It means you have to be careful not to change the other bits and be sure the write operation doesn't itself cause outside problems. Reading into a variable 'snapshots' the port contents in one go. Often flipping the bit in the variable then writing the whole variable back to the port is a better solution. PIC18 series overcome the problem by having output latches before the port driver.

Brian.
 
Hi,

I see no RMW problem.
Even if the port is read two times, there is no "modify" and no "write".
On key input and LED output I see no problem of timing when there are different "timings of port read"

I´m not experienced with PIC but I have something in mind like: Read from one port register, but write to another port register. This I miss here.

Port inputs should be treated by the compiler as "volatile".

Klaus
 

The following operations are read-modify-write:
Code:
PORTB.F0 = 0;
PORTB.F0 = 1;
They read the current voltage on all port B pins, modify bit 0, and write all bits to the Port B output register.
Say that you connect one output pin directly to the base of a NPN transistor.
When the output is written as 1, the transistor will be on, but the pin voltage will be less than 1V.
If a read-modify-write operation is performed on the port (for another pin),
the base pin will be read as 0, so it will be rewritten as 0 and the transistor will switch off.
 

Hi,

Yes, i know these are RMW instructions.
But still I don't see a RMW problem.
****
In the meantime I did a search an found a document where it describes that it reads the input states but write output registers.
I understand the problem now ... but it relates just to (temporarily) overdriven output pins, where the output is set to a state but the external circuit forces the opposite state.

So in my eyes this rater is a problem of the external circuit, not the code. Or am I wrong here?

Klaus
 

It can be both but the fundamental problem is that all the bits are read, even if only one is being checked and all the bits are written, even if only one has changed. Imagine you write 0xFF to a port then read it back, you would expect 0xFF as the result but what you actually get is the state of the port pins which could be influenced by outside circuits. Similarly, using the OP's code, " if(PORTB.F1==1)" reads the current state of ALL the port bits, including ones not relevant to the code and "PORTB.F0=0;" writes to all the port pins. If the level on any other pins changes, it is possible for the wrong level to be written out again.

On PIC18F and later MCUs a different port structure is employed and writing goes to the port's LAT register while reading is still done from the PORT register. It is still possible to write to the port and it will still work but the RMW problem might still occur.

It's an obscure problem that doesn't manifest itself in most applications but worth knowing about when unexpected IO values show up. The 'quick fix' is often just to put a NOP (= single cycle) instruction to allow the port contents to settle between write and read instructions. The better fix is to read the port into a variable, change the bits in the variable then write it back out again.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top