This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Port input query

Hi,

I'm trying to use the below line of code to test the input bits of port B. The first line works correctly, however I would like to use the second equivalent line to make it easy to read my code. What have I done incorrectly in the second line?

if( (P2IN & 0x2c)!=0 && (P2IN & BIT4)==0)

if( (P2IN & BIT2+BIT3+BIT5)!=0 && (P2IN & BIT4)==0)

Thanks in advance

Clueless

  • Try:

    if( (P2IN & (BIT2+BIT3+BIT5))!=0 && (P2IN & BIT4)==0)

  • Hi,

    This did not work either as I did give that a try before posting on here. However, I've just tried the below and it works fine. I would still prefer it in the other format though if you have any other ideas!

    if( (P2IN & (0xb00101100))!=0 && (P2IN & BIT4)==0)

    Thanks,

    Clueless

  • Weirdness.

    What compiler?

    I'm curious if this would work:

    char weird = (BIT2+BIT3+BIT5);

    if( (P2IN & weird)!=0 && (P2IN & BIT4)==0)

  • clueless clueless said:
    This did not work either

    That is strange. Did you dump the generated assembly instructions for the two cases and compare what the compiler did differently? Can you post that here?

  • I'm using the IAR Embedded Workbench compiler.

  • Brian,

    No I've not done this, just tested by single stepping in IAR. I'm new to IAR workbench thus not looked into the comparisons. Did you try this on your compiler?

    Clueles

  • clueless clueless said:
    This did not work either

    in fact, 0x2c and (BIT2+BIT3+BIT5) (with brackets!) is exactly the same and the compiler will both turn into the same constant value. It would be better to combine bits with the binary OR instead of the arithmetic and, but it makes no difference here (with brackets around them!).

     Personally, I would write it this way:

    If ( (P2IN & (BIT5|BIT3|BIT2)) && !(P2IN & BIT4) )

     Just for completeness, (A & B | C) is ((A&B)|C) and therefore always !=0

  • Thanks for this Jens-Michael,

    I'm trying to understand why the line of code below does not work in my IAR compiler. I'm single stepping and watching the bits on Port 2. BIT5 is low and  the line still returns true as though BIT5 is not being tested.

    if( (P2IN & BIT2+BIT3+BIT5)!=0 && (P2IN & BIT4)==0)

  • Jens-Michael Gross said:
     Just for completeness, (A & B + C) is ((A&B)+C) and therefore always !=0

    Bitwise AND has lower precedence than addition, so (A & B + C) is equivalent to (A & (B + C)).

    clueless clueless said:

    Thanks for this Jens-Michael,

    I'm trying to understand why the line of code below does not work in my IAR compiler. I'm single stepping and watching the bits on Port 2. BIT5 is low and  the line still returns true as though BIT5 is not being tested.

    if( (P2IN & BIT2+BIT3+BIT5)!=0 && (P2IN & BIT4)==0)

    You said bit 5 of P2IN is 0, but what are the states of the other bits? If bit 2 or 3 are set, then "(P2IN & BIT2+BIT3+BIT5)!=0" is true. If, additionally, bit 4 is clear then the if condition evaluates to true.

  • clueless clueless said:

    Thanks for this Jens-Michael,

    I'm trying to understand why the line of code below does not work in my IAR compiler. I'm single stepping and watching the bits on Port 2. BIT5 is low and  the line still returns true as though BIT5 is not being tested.

    if( (P2IN & BIT2+BIT3+BIT5)!=0 && (P2IN & BIT4)==0)

    The statement that I highlighted seems at odds with the code fragment you posted. Let me rephrase and you tell me if I'm correct in what you are trying to do...

    If bits 2, 3, and 5 on Port 2 are ALL high, and bit 4 on Port 2 is low, then evaluate true and do whatever is in the brackets following the if statement.

    That would be coded like this:

         if ( ( (P2IN & (BIT2 | BIT3 | BIT5)) == (BIT2 | BIT3 | BIT5)) && !(P2IN & BIT4) ) { .... }

    If that is not correct, please state your intended operation in words like my example.

  • Brian,

    What you stated above is exactly what I'm trying to do. I will try what you recommended. 

    Thanks again for your help. 

  • clueless clueless said:
    if( (P2IN & BIT2+BIT3+BIT5)!=0 && (P2IN & BIT4)==0)

    Again you forgot the brackets around (BIT2+BIT3+BIT5). Without them, the port will be checked for BIT2 only any of the three bits being set. , and BIT3 and BIT5 will be added to the result, which is of course always non-zero. Please learn about operator precedence in C expressions.
    This has nothing to do with the MSP, only with C language.

  • Jens-Michael Gross said:
    Again you forgot the brackets around (BIT2+BIT3+BIT5). Without them, the port will be checked for BIT2 only, and BIT3 and BIT5 will be added to the result, which is of course always non-zero. Please learn about operator precedence in C expressions.

    Like I said earlier:

    Robert Cowsill said:

     Just for completeness, (A & B + C) is ((A&B)+C) and therefore always !=0

    Bitwise AND has lower precedence than addition, so (A & B + C) is equivalent to (A & (B + C)).[/quote]

    So in this case the parentheses aren't required. If the additions were replaced with bitwise OR, however, the parentheses would be required.

    The issue here was that the test as written didn't match the OP's intent. It was checking for any one of {BIT2, BIT3, BIT5} being set, when instead the requirement was to check for all of them being set simultaneously.

  • Robert Cowsill said:
    Bitwise AND has lower precedence than addition


    Oh, you're right, I'm so used to not use arithmetic operators for bit operations, that I forgot that arithmetic operators have higher precedence than binary operators.

    Robert Cowsill said:
    the requirement was to check for all of them being set

    Then this could be of course done as you wrote, or like this:

    if (  P2IN & BIT2 && P2IN & BIT3 && P2IN && BIT5 && !(P2IN & BIT4) )

    which makes the intention even more clear. However, there is a difference that has something to do with the MSP:
    On a normal variable, the compiler would generate the exact same cod for both versions. However, on hardware registers, my version will produce larger code, as the compiler is forced to do one access to P2In each tiem it appears in the source code.

    For this reason, I would suggest another version:

    if ( (P2IN & (BIT2|BIT3|BIT4|BIT5) ) == (BIT2|BIT3|BIT5) ) {}

    It generates only one read access to P2IN, so all bits are really checked simultaneously. In the other version you proposed, it could be that between checking the three bits being set and the one bit being clear, an ISR happens, and the condition evaluates to true even if the four bits never had the required pattern (e.g. before the ISR, all four were set, and after the ISR, all four were clear).

**Attention** This is a public forum