Why are Bitshift operators?

I don’t understand when and why you will use bitrate operators for programming microchips: 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);
}

What is going on here? someone please explain graphically with 0 and 1, please. Or here is 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.

+5
source share
8 answers

A few spring reasons to consider why you use them.

Firstly, sometimes the memory is rigidly attached to devices such as a microcontroller, and you may want to save as much space as possible.

, , , . , , TCP/IP, (, DF) (, IP-).

, , , SerialInit, (UART = ). UCSRx UART Control/Status Register #x, , .

, / . , , , , -.

, .

:

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

. , , , , .

, g :

mmap_byte |= 0x20; // binary 00100000

:

mmap_byte &= 0xdf; // binary 11011111

, , , .


, , , , :

  • 1, 1.
  • - 1, 1.
  • XOR - 1, 1.
  • NOT - 1, 0.
  • .
  • .

, . , ( NOT, ), .

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

, 4 , 15 ( 1111), :

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

: 4- , 8-, (left-shift, and or):

packed_val = ((val1 & 15) << 4) | (val2 & 15)
  • & 15 , 4 .
  • << 4 - 4- , val1 4 8- .
  • | .

val1 7 val2 4:

                val1            val2
                ====            ====
 & 15 (and)   xxxx-0111       xxxx-0100  & 15
 << 4 (left)  0111-0000           |
                  |               |
                  +-------+-------+
                          |
| (or)                0111-0100
+17
  • , , : 1 0. , 1 8 .

  • (, - 0 7), 3 (000 = 0 dec, 001 = 1, 010 = 2,..., 111 = 7). 5 8 .

? -, , 0 1

1 < 2 = 00000001 < 2 = 00000100 = 4

4 → 2 = 00000100 → 2 = 00000001 = 1

+5

, , ", , ", ", , , , , ?"

, , . , , .

- ? Atmel pdf.

USART - UCSRnB

• 7 - RXCIEn: RX Complete n RXCn . USART , RXCIEn , SREG RXCn UCSRnA .

• 6 - TXCIEn: TX Complete n TXCn . USART- , TXCIEn , SREG TXCn UCSRnA .

... • 5 - UDRIEn:... • 4 - RXENn:... • 3 - TXENn:... • 2 - UCSZn2:... • 1 - RXB8n:... • 0 - TXB8n:...

, . , . , , .

, interupt RXCn Flag . , . | = -

0x3F ( , ) :

*((unsigned char*)0x3F) |= 0x80;// I want to set bit number 7 (RXCIEn)

, ?

, UCSRnB RXCIEn, - . , RXCIEn - -, , , ,

UCSRnB |= (1 << RXCIEn);

-

UCSRnB = (1<<RXENn)|(1<<TXENn);

,

*((unsigned char*)0x3F) = 0x18; // I want to set bits number 4 and 3 (RXENn and TXENn)

, , , .

+4

:

SWITCH_DDR &= ~SWITCH_BIT;   
SWITCH_PORT |= SWITCH_BIT;

-, .

, , , .

, SWITCH_DDR SWITCH_PORT - , - . / . , , . , , SWITCH_BIT, . , SWITCH_BIT 0x80 (10000000 ). , SWITCH_BIT ~ ( 01111111 ) AND SWITCH_DDR. . 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);
}

, ( ), - :

a) (SWITCH_BIT), - . , U2X , / ( ), . (1<<U2X) . , , ( SWITCH_BIT), U2X 7, 10000000 .

b) :

UCSRC = (1<<URSEL) + (1<<UCSZ1) + (1<<UCSZ0);

, ( ). , + , / , , "" , . OR, , , , .

c) ,

UBRRH = ((XTAL / (8 * 250000)) - 1)>>8;

, , -, , , . , , .

+3

, SerialInit.

, . , , - . , , , 9600 buad , , , 12- . , XTAL/(8 * 250000) 16 250000 8 . , 0x200, , 0x234. UBBRH , , , -, 8 ( ), UBBRL , 8 .

8 0x0234 0x02, 0x02 0x0234,

0x0234 = 0b0000001000110100 (0b , 0x )

, , C ( ). , , , , .

0b0000001000110100 8 0bxxxxxxxx00000010. Xxes - , C, . , 8 , 8 .

, 0x234 UBRRL - 8 . C 8 0x34 .

, 0x234 0x02 0x34 .

UCSRA = (1 < U2X);

-, , . , U2X, , 5 1 < 5 0x01 0b00000001. , , C 5 . , 5 .

So 
0b00000001
add five zeros to visualize
0b0000000100000
then chop five off the left
0b00100000
and we end up with 0x20.

UCSRB .

UCSRC ,

UCsrc= (1 < URSEL) + (1 < UCSZ1) + (1 < UCSZ0);

, , .

UCsrc= (1 < 5) + (1 < 2) + (1 < 4);

UCSRA UCSRB,

one with five zeros shifted in
0b100000
Pad that on the left to make it a full 8 bits
0b00100000
one with 2 zeros and one with 4 zeros
0b100 padded is 0b00000100
0b10000 padded is 0b00010000

, :

0b00100000
0b00000100
0b00010000

0b00110100 = 0x34

.

, add . , , , , , , , , . , URSEL UCSZ1

UCsrc= (1 < URSEL) + (1 < UCSZ1) + (1 < UCSZ0);

UCsrc= (1 < 5) + (1 < 5) + (1 < 4);

you would get
0b00100000
0b00100000
0b00010000
which adds to
0b01010000
when you probably wanted to or them and get
0b00110000

, a , , , , .

, , , , . , , ,

0b0SPPLLLL

SS - 1 = 2 0 = 1 PP - 0b00 = 0b01 = 0b10 = LLLL - 0b1000 = 8, 0b0111 = 7 ..

, - :

SCONTROL = (0 < 7) | (2 < 4) | (8 < 0);

, :

SCONTROL = (ONESTOPBIT < STOPBITS) | (NOPARITY < PARITYBITS) | (DATABITS8 < DATABITS);

, , -, , ( ).

SWITCH_DDR & = ~ SWITCH_BIT;

SWITCH_PORT | = SWITCH_BIT;

, -- - , 3 - , , - :

ra = SOMEREGISTER;
ra&=~7;
ra|=newnumber&7;
SOMEREGISTER = ra;

ra & = ~ 7

start with 
0x0000....0000111
take the ones complement, which is make the zeros ones and ones zeros
0x1111....1111000

, 1- , , 0, --- , , , .

, , ~ 7 0xFFFF... FF8. , :

#define SOMEMASK 0x7

and then use 
ra&=~SOMEMASK;
ra|=newvalue&SOMEMASK.

#define SOMEMASKBITS 3 #define SOMEMASK ((1

, 0x7 - . 3.

+2

- ( ): .

, , :

. , "", . , "" , .

, .

:

1000 shl 1 = 0000 (the 1 fell off the end, and a 0 appeared on the other end)
1000 shr 1 = 0100 (a zero fell off the right end)

, , .

1000 rol 1 = 0001 (the 1 was rotated back in on the other side)

:

  • , .
  • , .

, , .

0, :

1000 rcl 1 = 0000 (rcl = rotate through carry to left)
0000 rcl 1 = 0001 (now the 1 came back, it was temporarily stored in carry flag)

:

rcl ax, 1    ; rotate AX-register, 16-bit, left 1 bit, through carry
rcr bx, 1    ; rotate BX-register, 16-bit, right 1 bit, through carry

AX, BX.

. , N ( N 0, 0 - ), :

value = value OR (1 shl N)

1 N . N 0, .

. 1, 1 , 1 .

, :

1 shl 0 = 00000001 shl 0 = 00000001
1 shl 1 = 00000001 shl 0 = 00000010
1 shl 2 = 00000001 shl 0 = 00000100
1 shl 3 = 00000001 shl 0 = 00001000
1 shl 4 = 00000001 shl 0 = 00010000
1 shl 5 = 00000001 shl 0 = 00100000
1 shl 6 = 00000001 shl 0 = 01000000
1 shl 7 = 00000001 shl 0 = 10000000

OR:

???????? OR 00100000 = ??1?????, where ? means whatever it was before

, :

UBRRH = ((XTAL / (8 * 250000)) - 1)>>8;   // 250kbps at 16Mhz
UBRRL = (XTAL / (8 * 250000)) - 1;

, (XTAL / (8 * 250000)) - 1, . , , - . ( .)

, :

UBRRH = value >>8;   // 250kbps at 16Mhz
UBRRL = value;

, , UBRRH UBRRL BYTE, , 8 . , :

  • UBRRH 8 "", 8 . , , , 8-15
  • UBRRL 8 , , 0-7

L H, .

+1

( ). , , . , SWITCH_DDR 8- SWITCH_BIT 8- , 2:

SWITCH_DDR = 00000000;  // initial value of SWITCH_DDR is 0
SWITCH_BIT = 00000010;

, SWITCH_DDR 1:

SWITCH_DDR |= SWITCH_BIT; // SWITCH_DDR is 00000010 now

, SWITCH_BIT, AND:

TEMP = 10101010 & SWITCH_BIT; // TEMP is 00000010 now (1 in TEMP is set only if there 1 in both operands)
if (TEMP == SWITCH_BIT) // The condition is true
{ /* Do something */ }
TEMP = SWITCH_DDR & SWITCH_BIT;  // TEMP is again 00000010 because we set it to 00000010 before and the AND operator doesn't therefore change anything
if (TEMP == SWITCH_BIT)  // The condition is also true
{ /* Do something */ }

, :

TEMP = ~SWITCH_BIT;  // TEMP is now 11111101
SWITCH_DDR &= TEMP;  // This preserves everything (because 1 & 1 = 1 and 1 & 0 = 0) but the SWITCH_BIT bit which will be always set to 0 (anything & 0 = 0)

:

RESULT = 10010010 << 1;  // RESULT is 00100100
RESULT <<= 1;  // RESULT is 01001000
RESULT <<= 2;  // RESULT is 00100000
RESULT >>= 1;  // RESULT is 00010000

- / 2:

RESULT = 3 << 1;  // Result is 6 (3 * 2)
RESULT = 5 << 2;  // Result is 20 (5 * 4)
RESULT = 1 << 7;  // Result is 128 (1 * 128)
RESULT = 36 >> 1; // Result is 18 (36 / 2)
RESULT = 35 >> 1; // Result is 17 (35 / 2)
+1

, , -. - , , . , :

  some_port |= 8;  /* Statement #1a -- Note value is a power of 2 */
  some_port |= 2;  /* Statement #1b -- Note value is a power of 2 */

  some_port |= 9;  /* Statement #2 -- Note value is not a power of 2 */

(, ARM Z80), some_port volatile ( ), , . (, PIC) , , . .

Time/space for 1st and 2nd methods of setting bits
(time in cycles unless noted)
1st  2nd
2/4  2/3  8051 (standard)
4/4  3/3  8051 (accelerated clone)
2/2  2/2  PIC
10/4 8/6  6805
0

All Articles