This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

bit field

Hi All,

I have a struct:

   union U
   {
      unsigned char c;
      struct
      {
         unsigned char bit0 : 1;
         unsigned char bit1 : 1;
         unsigned char bit2 : 1;
         .
         .
         .
      }S;
   };
}
If I test multiple bits together I would have to do something like:
if (S.bit0 || S.bit1 || S.bit2)
which might generate insufficient code.

I can group multiple bits together but that would require changing the bitfields all the time as the code changes.

if I used bit mask instead of bit field. It would be something like:
if (var & (BIT_0 | BIT_1 | BIT2))
which generates much better code.

Is there anyway to makeit more efficient testing mutiple bit fields in 1 shot?

Thanks,

Anh

  • hi,

    first of all, do never rely on that bits will be placed into union as you wish. For example, try this simple code:

    union
    {
    	unsigned char my_chars[2];
    	struct
    	{
    		unsigned char bit0  : 1;
    		unsigned char bits1 : 6;
    		unsigned char bits2 : 7;
    		unsigned char bit1  : 1;
    		unsigned char bit2  : 1;
    	} my_bits;
    } my_union;
    
    void main(void)
    {
    	unsigned char x;
    
    	x = sizeof(my_union);
    }

    Do you think that x is loaded with 2? No, it will be loaded with 3. So: if your union contains different data types then their placement depends on compiler. Generally try to avoid such way of data types conversion.
    By the way, example above even do not place variable my_chars (named also as my_bits) into bit addressable area.

    Now how it should be done. Next example is clean and I hope make you light:
    unsigned char bdata my_bits;
    sbit my_bit0 = my_bits^0;
    sbit my_bit1 = my_bits^1;
    sbit my_bit2 = my_bits^2;
    
    void main(void)
    {
    	my_bits = 0x00;
    	my_bit1 = 1;
    
    	while(1)
    	{
    		if (my_bits & 0x06)		// check either bit 1 or 2 set
    		  my_bits &= ~0x06;		// reset both
    		else
    		  my_bits++;
    	}
    }
    
    In this example, we allocate bit addressable area for variable my_bits. Then we just define bits which are bits of this variable.

    Regards,
    Oleg

  • Thanks Oleg for your example and explanation. It does work if it is bit addressable. My question is more of a C language that works for standard data type where byte is the smallest addressing.

    Any other ideas?

    Thanks,

    Anh

  • hi,

    My question is more of a C language that works for standard data type where byte is the smallest addressing

    My suggestion is still the same: do not use union. It may be done with next way:

    unsigned char my_bits;
    #define BIT0_MASK	(1)
    #define BIT1_MASK	(1<<1)
    #define BIT2_MASK	(1<<2)
    
    
    void main(void)
    {
    	my_bits = 0x00;					// clear variable
    	my_bits |= BIT1_MASK;				// set bit 1
    
    	while(1)
    	{
    		if (my_bits & (BIT1_MASK|BIT2_MASK))	// check either bit 1 or 2 set
    		  my_bits &= ~(BIT1_MASK|BIT2_MASK);	// reset both
    		else
    		  my_bits++;
    	}
    }
    

    Regards,
    Oleg