Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Bitshift operators?

I dont understand when and why you would use bitshift operators for microchip programming: for example...

SWITCH_DDR &= ~SWITCH_BIT;   
SWITCH_PORT |= SWITCH_BIT;

Why use these operators?

Or...

void SerialInit(void)
{
   UBRRH = ((XTAL / (8 * 250000)) - 1)>>8;   // 250kbps at 16Mhz
   UBRRL = (XTAL / (8 * 250000)) - 1;
   UCSRA = (1<<U2X);
   UCSRB = (1<<TXEN);
   UCSRC = (1<<URSEL) + (1<<UCSZ1) + (1<<UCSZ0);
}

Whats going on here??? someone please explain graphically with 0's and 1's please. Or here's another example:

ulong MesureLC(void)
{
 int i;

 TCCR1B = 0;
 CountHigh = 0;
 TCNT1 = 0;

 for (i=0;i<25000;i++)
 {
  TCCR1B = (1<<CS12) + (1<<CS11) + (1<<CS10);   // WTF ???
  UDR = 0x55;
  while(!(UCSRA & (1<<UDRE)));
 }
 while(!(UCSRA & (1<<TXC)));
 TCCR1B = 0;

 CountLow = TCNT1;
 Count = CountLow + (CountHigh << 16);

 return Count;
}

I need to understand this stuff. Any help is appreciated.

like image 440
will lewis Avatar asked Aug 03 '10 14:08

will lewis


People also ask

What is Bitshift used for?

A bit shift is a bitwise operation where the order of several bits is moved, either to the left or right, to efficiently perform a mathematical operation. Bit shifts help with optimization in low-level programming because they require fewer calculations for the CPU than conventional math.

How does Bitshift work in Java?

The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator " >>> " shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.


1 Answers

A number of reasons spring to mind as to why you would use them.

The first is that sometimes memory is tight on micro-controller type devices and you may want to store as much as possible in as little space as possible.

This requirement may also be driven by the fact that other devices or software you interface with have that same minimal-space desire. They may use sub-byte data types for doing work, one example being TCP/IP headers where fields range from a single bit (such as the DF field) up to much more (such as the IP addresses).

In fact, that second bit of code you gave, SerialInit, is setting up properties for a serial comms chip (UART = Universal Asynchronous Receiver and Transmitter). UCSRx usually stands for UART Control/Status Register #x so you're writing information to a fairly low-level device to control its behaviour.

Another reason is that you may have memory mapped I/O. That means that, though you think you're writing to memory, you may well be sending those bits directly to an I/O device of some sort.

A classic example may be the use of a memory mapped byte where a seven-segment LEDs is controlled.

The LED may be structured as:

+---+---+---+---+---+---+---+---+
| d | e | g | f | a | b | c | p |
+---+---+---+---+---+---+---+---+
  #   #   #   #   #   #   #   #
  #   #   #   #   #   #   #   #===========#
  #   #   #   #   #   #   #               #
  #   #   #   #   #   #   #===========#   #
  #   #   #   #   #   #               #   #
  #   #   #   #   #   #===========#   #   #
  #   #   #   #   #               #   #   #
  #   #   #   #   #=====#         #   #   #
  #   #   #   #         #         #   #   #
  #   #   #   #     +-------+     #   #   #
  #   #   #   #     |aaaaaaa|     #   #   #
  #   #   #   #   +-+-------+-+   #   #   #
  #   #   #   #   |f|       |b|   #   #   #
  #   #   #   #===|f|       |b|===#   #   #
  #   #   #       |f|       |b|       #   #
  #   #   #       +-+-------+-+       #   #
  #   #   #=========|ggggggg|         #   #
  #   #           +-+-------+-+       #   #
  #   #           |e|       |c|       #   #
  #   #===========|e|       |c|=======#   #
  #               |e|       |c|           #
  #               +-+-------+-+ +---+     #
  #=================|ddddddd|   |ppp|=====#
                    +-------+   +---+

where each of the seven segments and the dot are controlled by a different bit. If you wanted to turn on a single segment while leaving the others as they are, you would use bit operations like your question contains.

By way of example, turning on the g segment involves an operation like:

mmap_byte |= 0x20; // binary 00100000

Turning it off involves:

mmap_byte &= 0xdf; // binary 11011111

You may also find yourself in a situation where single bits or groups of bit in a byte control totally distinct devices and you don't want the operation of one to affect the other.


As to what bitwise operators do, they are operators that work on a multi-bit value but conceptually one bit at a time:

  • AND is 1 only if both of its inputs are 1.
  • OR is 1 if one or more of its inputs are 1.
  • XOR is 1 only if exactly one of its inputs are 1.
  • NOT is 1 only if its input are 0.
  • left shift shifts bits left a certain amount.
  • right shift shifts bits right a certain amount.

Discounting the shifts for now, these can be best described as truth tables. Inputs possibilities are on the top and left, the resultant bit is one of the four (two in the case of NOT since it only has one input) values shown at the intersection of the two inputs.

AND | 0 1     OR | 0 1     XOR | 0 1    NOT | 0 1
----+-----    ---+----     ----+----    ----+----
 0  | 0 0      0 | 0 1       0 | 0 1        | 1 0
 1  | 0 1      1 | 1 1       1 | 1 0

One example is if you only want the lower 4 bits of an integer, you AND it with 15 (binary 1111) so:

    201: 1100 1001
AND  15: 0000 1111
------------------
 IS   9  0000 1001

Another example is if you have two 4-bit values that you want to pack into an 8-bit one, you can use all three of your operators (left-shift, and and or):

packed_val = ((val1 & 15) << 4) | (val2 & 15)
  • The & 15 operation will make sure that both values only have the lower 4 bits.
  • The << 4 is a 4-bit shift left to move val1 into the top 4 bits of an 8-bit value.
  • The | simply combines these two together.

If val1 is 7 and val2 is 4:

                val1            val2
                ====            ====
 & 15 (and)   xxxx-0111       xxxx-0100  & 15
 << 4 (left)  0111-0000           |
                  |               |
                  +-------+-------+
                          |
| (or)                0111-0100
like image 88
paxdiablo Avatar answered Oct 02 '22 11:10

paxdiablo