jwm
jwm

Reputation: 5040

Data handling in bit field

I am reading the code that involves some bitwise operations as shown below:

unsigned char data = 0;
unsigned char status = 0;

//DAQmx functions for reading data
DAQmxReadDigitalLines(taskHandleIn,1,10.0,DAQmx_Val_GroupByChannel,dataIn,8,&read,&bytesPerSamp,NULL);
DAQmxReadDigitalLines(taskHandleOut,1,10.0,DAQmx_Val_GroupByChannel,dataOutRead,8,&read,&bytesPerSamp,NULL);


for (int i = 0; i < 8; i++)
{
    if (dataOutRead[i] == 1)
        data = data | (0x01 << i);
    else
        data = data & ~(0x01 << i);
}

for (int i = 0; i < 4; i++)
{
    if (dataIn[i] == 1)
        status = status | (0x01 << (7 - i));
    else
        status = status & ~(0x01 << (7 - i));
}
ctrl = 0;

In the above codes, dataOutRead and dataIn are both uInt8 8-element arrays originally initialized to zero.

I don't quite understand what the code is actually doing? Anyone can walk me through these codes?

Upvotes: 2

Views: 127

Answers (2)

user2736738
user2736738

Reputation: 30936

Well the first loop is creating an unsigned char same as that of dataOutRead - Replicating whatever there is in dataOutRead to data. This one checks whether the ith bit is set/reset - and based on that it sets or resets in data.

Second loop does the same but with 4 least significant bits and copies whatever is there in most signigficant bits of status (Bit 7 to 4) from dataIn (but in reverse manner). To clarify further:-

7 6 5 4 3 2 1 0
x y z w w z y x

If in the second case 2 bit is set/reset then 5 bit of status is being set/reset.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727047

Key part of understanding this code is the conditional with a bitwise operation inside:

if(dataOutRead[i]==1) {
    data = data | (0x01 << i);
} else {
    data = data & ~(0x01 << i);
}

It uses bytes of dataOutRead as a sequence of ones and not ones (presumably, but not necessarily, zeros). This sequence is "masked" into bits of data starting with the least significant one:

  • When dataOutRead[i] is 1, the corresponding bit is set
  • When dataOutRead[i] is not 1, the corresponding bit is cleared. This step is unnecessary, because data is zeroed out before entering the loop.

This could be thought of as converting a "byte-encoded-binary" (one byte per bit) into its corresponding binary number.

The second loop does the same thing with reversed bits, processing only the lower four bits, and sticking them into the upper nibble of the data byte in reverse order.

It's hard to speculate on the purpose of this approach, but it could be useful in applications that use arrays of full-byte Booleans to control the state of some hardware register, e.g. in a microcontroller.

Upvotes: 2

Related Questions