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

accessing bits from byte

I want access bit from Byte array.for example consider array of 30 bytes in which I want to access 1 to 15 bits...
How to access it. kindly help me.......

  • 8 bits / byte.

    Just compute in which byte you have bit n, and what bit within this byte.

    n >> 3 will represent the byte (dividing by 8 since 8 bits in a byte).

    n & 7 will represent the bit number in the byte, since the bit index within a byte is 0..7 and this consumes exactly 3 bits of the number n.

    so:

    unsigned char bits[...];
    bits[n >> 3] |= 1 << (n & 7); // set a bit
    bits[n >> 3] &= ~(1 << (n & 7)); // clear a bit
    if (bits[n >> 3] & (1 << (n & 7))) {
        // tests a bit
    }
    

  • I am posting my program...it is not working Logic error is there in this program....

    #include<stdio.h>
    #include <REGX55.H>
    unsigned char code maskBit[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    unsigned char buffer[10];
    void AccessBit(unsigned char,unsigned char);
    
    void main()
    {
     buffer[0]=0xFA;
     buffer[1]=0x0A;
     buffer[2]=0x5B;
     while(1)
     {
      AccessBit(4,20);
    
     }
    
    }
    void AccessBit(unsigned char startAddr,unsigned char endAddr)
    {
     unsigned char byteValue,byteTemp,value=0x30,count=0,j;
     unsigned char i=7;
     unsigned char startBit,startByte,endBit,endByte;
    
     startByte=startByte/8;
     startBit=startAddr%8;
     endByte=endAddr/8;
     endBit=endAddr%8;
     count=startBit;
    
       for(i=startByte;i<=endByte;i++)
       {
         if(i==startByte&i==endByte)
             {
              count=endBit;
             }
             else if(i==endByte)
             {
              count=endBit;
             }
             else
             {
              count=startBit;
             }
          for(j=startAddr;j<=endAddr;j++)
              {
    
               byteTemp=((buffer[i]&maskBit[count]))!=0;
           if(byteTemp)
           {
                 byteValue=byteValue<<1;
             byteValue|=1;
           }
               if(!byteTemp)
               {
                byteValue=byteValue<<1;
               }
               if(count==startBit)
               {
                break;
                    byteValue=0;
                    startBit=0;
               }
               count--;
              }
            }
      }
    

    In bit access function i want select a particular bits and storte every 8 bits in byte variable/array....in above 4 to 11 froms a byte 11 to 18 form a byte other two bits shoulbe framed with byte appending zeros.....

  • Did you look at my code?

    You divide by 8. Unless the compiler do a strength reduction, the division is very heavy for most embedded processors.

    You do modulo 8 (another division) to get the bit position inside the byte.

    You have a function called AccessBit() - which seem to imply that it accesses a single bit. But in this case it takes a start address and an end address. So what is the function intended to do?

    Did you compile with warnings on?

    You send in a parameter startAddr, but you do an assign startByte = startByte/8. Where do you give startByte an initial value before using it on the right-hand side in an expression? This implies that you are posting asking for help before looking for bugs in your code.

    If your start and end addresses points into the same byte, then you do:

    if(i==startByte&i==endByte)
    


    Did you intend a bit and (&) instead of a logic and (&&)? And what value do you assign to count when you do:

    count=endBit;
    


    In what way does endBit represent a count? Shouldn't startBit also been taken into account when you figure out the number of bits inside the range of the byte?

    And if startByte and endByte are the same - why have this test inside a for loop?

    No use trying to look for more errors in the code, since you haven't documented what the intended action should be - I can only look for bugs when I compare between a map and the reality. If I can't see the reality, I will not know if the map is good or bad.

  • "it is not working Logic error is there in this program..."

    Here's an obvious first error:

    startByte=startByte/8;
    

    Anyway, your code seems too complex. Here's a very generic example that uses bit masks to count off when to do source and destination buffer reads and writes:

    unsigned char src_buf[8];
    unsigned char dst_buf[8];
    
    void bitcpy(unsigned char *dst,
                unsigned char *src,
                unsigned char start_bit,
                unsigned char n_bits)
    {
        unsigned char src_byte, src_mask;
        unsigned char dst_byte, dst_mask;
    
        src += start_bit / 8;
        src_mask = 0x80 >> (start_bit % 8);
        src_byte = *src;
    
        dst_mask = 0x80;
        dst_byte = 0;
    
        while (n_bits--) {
            if (src_byte & src_mask) {
                dst_byte |= dst_mask;
            }
            if ((src_mask >>= 1) == 0) {
                src_mask = 0x80;
                src_byte = *++src;
            }
            if ((dst_mask >>= 1) == 0) {
                dst_mask = 0x80;
                *dst++ = dst_byte;
                dst_byte = 0;
            }
        }
    
        if (dst_mask != 0) {
            *dst = dst_byte;
        }
    }
    
    void main(void)
    {
        src_buf[0] = 0xFA;
        src_buf[1] = 0x0A;
        src_buf[2] = 0x5B;
    
        bitcpy(dst_buf, src_buf, 4, 20);
    
        for (;;);
    }
    

  •     if (dst_mask != 0) {
            *dst = dst_byte;
        }
    

    To avoid an extra store when the number if bits is a multiple of 8, that should have been:

        if (dst_mask != 0x80) {
            *dst = dst_byte;
        }
    

    Sorry, my bad. Where are all you code reviewers anyway?