• AVR Freaks

bitset bitclear C

Author
rianovich96
Senior Member
  • Total Posts : 176
  • Reward points : 0
  • Joined: 2010/07/27 13:17:27
  • Location: 0
  • Status: offline
2010/08/14 06:53:03 (permalink)
0

bitset bitclear C

Hi,

How do I set and clear in the same time 2 bits of a char, leaving rest unchanged ?

xxxx10xx

I want x to be unchanged but 2-3 to be 10. Is it possible done at once? Thanks.
#1

17 Replies Related Threads

    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re:bitset bitclear C 2010/08/14 07:17:56 (permalink)
    0
    I'd say that a couple of instructions are needed.
    2 bcf/bsf, or a AND and a OR...

    GENOVA :D :D ! GODO
    #2
    rianovich96
    Senior Member
    • Total Posts : 176
    • Reward points : 0
    • Joined: 2010/07/27 13:17:27
    • Location: 0
    • Status: offline
    Re:bitset bitclear C 2010/08/14 07:23:23 (permalink)
    0
    I don't want to mix C with asm. Is possible?
    #3
    lbodnar
    Super Member
    • Total Posts : 1148
    • Reward points : 0
    • Joined: 2005/12/18 06:06:09
    • Location: UK
    • Status: offline
    Re:bitset bitclear C 2010/08/14 07:35:48 (permalink)
    0
    CharA = (CharA & 0xF3) | 0x08;

    What did you mean by "at the same time?"

    Leo
    #4
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re:bitset bitclear C 2010/08/14 10:17:33 (permalink)
    0
    I guess he wanted one single ASM (machine) instruction, thus my reply.. Smile

    yours is of course the one!

    GENOVA :D :D ! GODO
    #5
    z12345
    Starting Member
    • Total Posts : 70
    • Reward points : 0
    • Joined: 2004/10/02 14:48:49
    • Location: Italia
    • Status: offline
    Re:bitset bitclear C 2010/08/25 01:36:23 (permalink)
    0
    You can use in assembler:
    movlw b'00001000'
    xorwf Var,W
    andlw b'00001100'
    xorwf Var,F

    Or in C:
    Var ^= ((Var^0x08)&0x0C)

    but you must verify the output code of the compiler, because the optimization of compiler may generate two bsf/bcf instruction.

    I think, you may should consider to include asm code into C source, in this mode you be sure of executed code.

    hi

    E` possibile fare qualunque cosa, ma il problema e` in quanto tempo.
    It is possible to do anything, but the problem is in how long.
    http://www.disystem.it
    #6
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11188
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re:bitset bitclear C 2010/08/25 10:19:41 (permalink)
    +1 (1)
    rianovich96

    xxxx10xx

    I want x to be unchanged but 2-3 to be 10. Is it possible done at once?

    You can't do it "at once" because a PIC18 can't do that in a single instruction.  As such, there's no particular advantage to doing it in a single line of C; it's easier to understand as two lines:

    var |= (1 << 3);   // set bit 3
    var &= ~(1 << 2) // clear bit 2


    #7
    kriskizlyk
    New Member
    • Total Posts : 7
    • Reward points : 0
    • Joined: 2012/08/26 09:42:03
    • Location: 0
    • Status: offline
    Re:bitset bitclear C 2015/03/10 06:56:21 (permalink)
    +1 (1)
    Credit to my friend for his help...but if anyone still cares about this you can use #define and create a macro.
     
    #define CHECK_BIT(var, pos) ((var) & (1<<(pos)))
    CHECK_BIT(var, pos)
     
    #define SET_BIT(var, pos) var |= (1 << pos)
    SET_BIT(var, pos)
     
    #define CLEAR_BIT(var, pos) var &= (~(1 << pos))
    CLEAR_BIT(var, pos)
     
    #define TOGGLE_BIT(var, pos) var ^= (1 << pos)
    TOGGLE_BIT(var, pos)
    #8
    crosland
    Super Member
    • Total Posts : 1580
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re:bitset bitclear C 2015/03/10 08:39:06 (permalink)
    0
    z12345
    You can use in assembler:
    movlw b'00001000'
    xorwf Var,W
    andlw b'00001100'
    xorwf Var,F

    Or in C:
    Var ^= ((Var^0x08)&0x0C)


    Why make it so obtuse by using xor, when the and-or solution was already given?
     
    #9
    1and0
    Access is Denied
    • Total Posts : 9257
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re:bitset bitclear C 2015/03/10 08:57:52 (permalink)
    +1 (1)
    crosland
    z12345
    You can use in assembler:
    movlw b'00001000'
    xorwf Var,W
    andlw b'00001100'
    xorwf Var,F

    Or in C:
    Var ^= ((Var^0x08)&0x0C)


    Why make it so obtuse by using xor, when the and-or solution was already given?

    Because it can change two (or more) bits "at once" -- useful if you want to change two or more output pins at the "same" time.
     
    *** Do notice this is a 4+ years old thread.
    post edited by 1and0 - 2015/03/10 09:00:35
    #10
    Ian.M
    Super Member
    • Total Posts : 13225
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re:bitset bitclear C 2015/03/10 09:25:02 (permalink)
    +2 (2)
    I proposed a MASKIN() macro for writing groups of bits in a byte simultaneously two years ago.  Its based on the XOR method 1and0 just presented, but all wrapped up in a convenient macro.  Its also thread-safe as long as two threads aren't changing the same group of bits in the byte.  You can also read the discussion  during its development of if it was really needed.

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #11
    crosland
    Super Member
    • Total Posts : 1580
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re:bitset bitclear C 2015/03/11 01:30:39 (permalink)
    0
    1and0
    Because it can change two (or more) bits "at once" -- useful if you want to change two or more output pins at the "same" time.
     
    *** Do notice this is a 4+ years old thread.


    So does AND with mask and OR with new bits and it's a lot more intuitive to a beginner as the mask makes it explicit which bits are changing. Or am I missing something?
    #12
    Ian.M
    Super Member
    • Total Posts : 13225
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re:bitset bitclear C 2015/03/11 01:49:27 (permalink)
    +1 (1)
    AND with mask clears all the bits that are affected then the OR sets the '1' bits.  This gives a '0' going glitch on any bit that was '1' previously and is '1' afterwards, which is unacceptable in many applications.  The XOR method doesn't glitch any bits that remain unchanged and flips all the bits to be changed at the same time (to within the limit of the port's LAT flipflops and output buffer propagation delays).

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #13
    crosland
    Super Member
    • Total Posts : 1580
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re:bitset bitclear C 2015/03/11 07:46:48 (permalink)
    0
    The XOR method has exactly the same problem. Initialise Var to 0x8 in the example in post 6 to see what I mean. Bit 3 gets flipped to 0 then back to 1.
     
    This glitching is only an issue if you write the intermediate result to a port, which no one is advocating, or an interrupt occurs during the sequence which is easily guarded against.
     
    I still don't see the advantage of the XOR method. All it does t my eyes is obfuscate the true intent of the code.
    #14
    Ian.M
    Super Member
    • Total Posts : 13225
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re:bitset bitclear C 2015/03/11 08:37:54 (permalink)
    +1 (1)
    crosland
    The XOR method has exactly the same problem. Initialise Var to 0x8 in the example in post 6 to see what I mean. Bit 3 gets flipped to 0 then back to 1.

    No it doesn't.   Post #6 has the expression Var ^= ((Var^0x08)&0x0C)
    Lets break that up into individual operaions, introdcing an intermediate result Temp, and start with Var==0x08.
    Expression        Temp  Var   Note
                      ----  0x08
    Temp=Var^0x08     0x00  0x08  Bit 3 was set and bit 2 was clear so do not need flipping

    Temp&=0x0C        0x00  0x08  Mask selects bits 2 and 3
    Var^=Temp         0x00  0x08  No bits were flipped
    Notice any glitches?  No, didn't think so! LoL
     
    crosland

    This glitching is only an issue if you write the intermediate result to a port, which no one is advocating, or an interrupt occurs during the sequence which is easily guarded against.

    Glitches are also important when writing to SFRs that have side-effects when written to or if specific individual bits are set or cleared. 
    crosland
    I still don't see the advantage of the XOR method. All it does to my eyes is obfuscate the true intent of the code.

    The XOR method avoids the pain of having to either disable interrupts to avoid a race condition if the AND/OR mask method is used with a temp variable, or causing glitches, without taking any more machine instructions.

     
    C expressions in general obfuscate the true intent for all who aren't very familiar with its operators and boolean maths. mr green


    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #15
    crosland
    Super Member
    • Total Posts : 1580
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re:bitset bitclear C 2015/03/11 09:01:45 (permalink)
    0
    OK, I misread the ^= as a simple assignment. the XOR code forces the use of a temp variable to hold the intermediate result.
     
    If you use a temp variable with the AND/OR method, even if it's just W, then there are no glitches and no race conditions that matter for the final result.
    #16
    Ian.M
    Super Member
    • Total Posts : 13225
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re:bitset bitclear C 2015/03/11 09:25:54 (permalink)
    +2 (2)
    There is a race condition in the AND/OR using temp method.
    If another thread modifies bits of the original variable that are set in the AND mask, while the temp variable is in use, those changed bits will be lost when the final value of the temp variable is written back to the original variable. sad
     
    Fortunately its far more pleasant to debate these methods with you than it was with the fdan00/qili/millwood troll.   The original argument brought to mind the saying "Never wrassle a pig. You both get dirty and the pig likes it."
    post edited by Ian.M - 2015/03/11 09:31:27

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #17
    crosland
    Super Member
    • Total Posts : 1580
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re:bitset bitclear C 2015/03/12 01:23:08 (permalink)
    +1 (1)
    OK, got it now :)
     
    Thank you for the final note. My personality does sometimes get in the way of clear expression :)
    #18
    Jump to:
    © 2019 APG vNext Commercial Version 4.5