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

How to read a Bit from a Byte ?

Respectable colleagues,

how to read a value of a BIT from value of a BYTE variable in Keil C ?

For example:
X=(Byte1.Bit7*4)+(Byte1.Bit6*2)

Thanks in advance.

With best regards,

Dragan Kujovic

  • In C51, you'd have to go via a bit-addressable object; ie,

    1. Copy your byte to a bit-addressable byte
    2. Access the required bit
    3. If required, write back to your original byte.

    Beware the optimiser!

    Failing that, the normal 'C' tools of masks/shifts, or bitfields - taking care to read the manual & app notes on bit & byte ordering.

  • Accessing an individual bit in a word.

    The first method is to use a mask to extract the value of a bit as in:

    msb = ( byte & 0x80 ) != 0x00;
    
    This will set the value of msb to the value of the most significant bit of byte. Where there is a requirement to access the nth bit of a byte, it is possible to use a table of masks as in:
    unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    
    bit_n = ( byte & mask_table[ n ] ) != 0x00;
    
    Using masks has the advantage that the code will be reasonably portable.

    The second method is to use a structure with bit-fields as in:
    struct {
    	bit_0:1
    	bit_1:1
    	bit_2:1
    	bit_3:1
    	bit_4:1
    	bit_5:1
    	bit_6:1
    	bit_7:1
    } byte;
    
    bit = byte.bit_7
    
    However, it can result in portability problems. With this method, it is only possible to reference a constant bit.

    Keil C51 has its own special extensions to take advantage of the C51 chip's bit addressing instructions.

  • > unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };

    > bit_n = ( byte & mask_table[ n ] ) != 0x00;

    Thanks, that's it.

    > Keil C51 has its own special extensions to take advantage of the C51 chip's bit addressing instructions.

    I don't know why Keil didn't make possible accessing individual pins on C16x, but I have made Reg167.h, Reg168.h, Reg169.h and RegST10F269.h files of my own with all necessary declarations. So, now is possible to access individual pins from C code with simple commands like:

    P2_0 = 1; // Port 2 Pin 0 HIGH

    or

    P2_0 = 0; // Port 2 Pin 0 LOW

    I will send those files to them, and if they find this useful, they can include those files in the software package, or put on the Web site.

    With best regards,

    Dragan Kujovic

  • // main.h

    #define OUTPUT 1
    #define INPUT 0
    #define HIGH 1
    #define LOW 0

    sfrbit P_TEST _atbit(P2,10);
    sfrbit DP_TEST _atbit(DP2,10);

    //main.c

    DP_TEST = OUTPUT;
    P_TEST = HIGH;
    _nop();
    P_TEST = LOW;

    DP_TEST = INPUT;
    if (P_TEST == HIGH)
    {
    }


    Does this workout for you ?

    Best Regards,
    Bert

  • Don't forget those &ltpre&gt and &lt/pre&gt tags when posting code:

    // main.h

    #define OUTPUT 1
    #define INPUT  0
    
    #define HIGH 1
    #define LOW  0
    
    sfrbit P_TEST  _atbit(P2,10);
    sfrbit DP_TEST _atbit(DP2,10);
    
    //main.c
    void main( void )
    {
       DP_TEST = OUTPUT;
       P_TEST  = HIGH;
       _nop();
       P_TEST  = LOW;
    
       DP_TEST = INPUT;
       if (P_TEST == HIGH) 
       {
          /* do stuff */
       }
    }
    

  • You need to create your variable in BDATA zone and defined its bits :

    char bdata BYTE;

    sbit Bit0 = BYTE ^ 0;
    sbit Bit1 = BYTE ^ 1;
    sbit Bit2 = BYTE ^ 2;
    sbit Bit3 = BYTE ^ 3;
    sbit Bit4 = BYTE ^ 4;
    sbit Bit5 = BYTE ^ 5;
    sbit Bit6 = BYTE ^ 6;
    sbit Bit7 = BYTE ^ 7;

    Then you'll be able to access each bit individually.

    nb:you need to use a type cast (int) to multiply a bit by a number

    int X=(int)Bit7*4 + (int)Bit6*2;

    Gilles