# Bitwise operations in embedded C if button pressed on AVR circuit

I am using ATmega32 AVR microcontroller. I am confused about bitwise operation in embedded C. I understand (AND, OR, XOR, NOT) logic gates very well, but there is something that I don't understand:

1. I understand this block of code:

if ((PINB&(1<<PB0))==0x01) //if button pressed
{
//Do something
}

2. But I don't understand why if I edited that to be:

 if (PINB &(1<<PB0))    //if button pressed
{
//Do something
}


Does the same function...

In other words, what is the default value of PINB which made the two blocks of code have the same functionality?

• The example number 1 will work only if PB0 equals 0. Whereas example number 2 will work for any value of PB0. – kkrambo Aug 13 at 13:29
• @kkrambo Is not it that the default value of PB0 is always 0 ? – Abdulrhman Aboghanima Aug 13 at 13:32
• How could we possibly know the default value of PB0? You haven't told us anything about it. – Elliot Alderson Aug 13 at 13:40
• Maybe PB0 equals 0 and example 1 works. Now suppose you add another button that is connected to PB1. So you cut and paste your button code and change PB0 to PB1. The pattern in example 1 will no longer work for your new button because PB1 is not equal to 0. Don't follow the pattern in example 1. – kkrambo Aug 13 at 13:44
• @ElliotAlderson PB0 is defined 0 in one of the headers. – Jeroen3 Aug 13 at 14:06

The example number 1 is not a good pattern to follow because it will work only if PB0 equals 0. Example number 2 is a better pattern to follow because it will work for all values of PB0. Example 1 can be edited to work for all values of PB0 like this:

if ((PINB & (1<<PB0)) == (1<<PB0)) //if button pressed
{
//Do something
}

• Thank you very much . You made it easy . :) – Abdulrhman Aboghanima Aug 13 at 15:44

The first expression shows a common error in embedded programming. Note that the expression PINB&(1<<PB0) has two variables, PINB and PB0. Exxentially the result of this expression will be equal to 1 << PB0 if and only if bit number PB0 in PINB is a 0. Note that the result can be equal to 0x1 only if the value of PB0 is 0, so the entire conditional will never evaluate as true if PB0 has any value other than 0.

The second example performs the same bit-wise AND operation, but it relies on the fact that a non-zero integer evaluates as a logical true in C. So, if the result of the expression is 0x20 we can infer that PB0 equals 5 and that bit 5 in PINB is a 1.

An if statement is true if the expression compares unequal to 0.

This means that as long as the and operation PINB &(1<<PB0) return a value above zero, it is true.
And the only way for the above expression to do so is when PB0 is 1 in the PINB register.

This means the equality operator ==0x01 would be redundant, and fault sensitive due to it requiring to have the correct bit in the parameter. If the parameter is mandatory in the style guide, use (1<<PB0) again.

• Thanks for you answer. I want to know why PINB &(1<<PB0) return a value above zero ? and whati is this value? – Abdulrhman Aboghanima Aug 13 at 13:22
• The ==0x01 is not redundant in these examples. The ==0x01 is probably a mistake because the resulting conditional can only possibly test true if PB0 equals 0. The ==0x01 conditional will not work correctly for any other values of PB0. – kkrambo Aug 13 at 13:25
• What does "when PB0 is set" mean? I think your explanation of how the conditional expression works is missing a lot of detail. – Elliot Alderson Aug 13 at 13:38
• @AbdulrhmanAboghanima PB0 is defined as 0 in avr/io.h, and PINB is the PORT input register. You perform an & on it with a 1. (the 1 is left shifted 0 times, stays 1) – Jeroen3 Aug 13 at 14:04

You said you understood logical operations very well so what is the question?

Why (x&1)==1 is equivalent to (x&1)!=0?

What are the possible outcomes of x&1?

1 and 0. So you can either compare x&1 to 1 or not 0 if you want to test for the result being a 1.

Has nothing to do with embedded, it is just the C language.

kkrambo has a good point, although experience will show what bit is being isolated the code should have either simply anded with 1 or compared with the thing being anded (1<

if ((PINB&(1<<PB0))!=0)


For C boolean, false is defined as zero and true is not-zero

so if(z) will be false if z is 0 and true if z is not zero

if(x&1) will be true if x[0] is 1 and false if x[0] is 0. So the if((x&1)!=0) is equivalent but reads better.

For some folks the defines/macros make life easier, for others (myself included) they make life much worse, very unreadable. The logic isnt going to change so programming to the logic is fine, IMO you need to justify the abstraction. YMMV

if ((PINB&(1<<PB0))==0x01)


Here we evaluate if the state of the bit with this register is set. if it evaluates to hex 0x01 or 1 we proceed.

if (PINB &(1<<PB0))


here we have the same expression but we don't compare it.

Remember the if statements prototype:

if (test expression)
{
// statements to be executed if the test expression is true
}


now recall that logic 1 = true and logic 0 = false;

So if we simply write -

int x = 1;
if(x)
{
// do something.
}


The expression we want to evaluate (x) is true because its 1.

• No, those two conditional statements are not exactly the same. If PB0 has any non-zero value then the expression (PINB&(1<<PB0))==0x01 will never evaluate to true. – Elliot Alderson Aug 13 at 13:31
• I see thank you for clarifying @ElliotAlderson :) – Sorenp Aug 14 at 4:12