'<<' operator

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

Could anyone explain the operator '<<' used in these cases:

PORTB |= (1 << PINB.0);
PORTB &= ~(1 << PINB.0);

Is it used to clear/set bit PORTB.0?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

<< is logical shift left, >> is logical shift right, bitwise.
1<<PINB.0 shifts "1" times PINB.0, that by 0 or two positions. Result of such operation would be thus 1 if PINB.0 is 0 and 2 if PINB.0 is 1.

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For bit manipulation details:

https://www.avrfreaks.net/index.p...

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The << shifts a 1, PINB.0 times.

If the individual PINB pins are defined as:

#define PINB.0 0
#define PINB.1 1
#define PINB.2 2
#define PINB.3 3
#define PINB.4 4
#define PINB.5 5
#define PINB.6 6
#define PINB.7 7

so:

PORTB |= (1<< PINB.3);

This is equivelent to:

PORTB |= (PINB & 0b00001000);

and:

PORTB &= ~(1 << PINB.3); 

is equivelent to:

PORTB &= (PINB & 0b11110111);

So:

PORTx |= (1 << PINB.x)

and

PORTx &= ~(1 << PINB.x)

are actually used as a mask to isolate and manipulate individual I/O pins within PORTx.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

Last Edited: Fri. Jul 21, 2006 - 02:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks svofski.

I don't understand the purpose of using "1<<" in the commands.

In atmega128 datasdeet, page 22, there is a C code example which is written as

...
/* Write logical one to EEMWE */
EECR |= (1<<EEMWE);
/* Start eeprom write by setting EEWE */
EECR |= (1<<EEWE);
...

Suppose EECR=0x00 (EEMWE=0, EEWE=0) , after the two commands are executed, what is the value of EECR?

Can u explain more?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, I see. Thanks all.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

microcarl, it is a very good tutorial 8)

Mats

Last Edited: Fri. Jul 21, 2006 - 02:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Carl makes a point but you can't really write

#define PINB.0 0

in "normal" C, so I guess this is some particular AVR-specific compiler? Which compiler is that, how PINB.0 is defined?

After your datasheet quotation, EECR will have both EEMWE and EEWE bits set (provided that they are not write-only bits). EEMWE and EEWE in the code example you mention are defined as numbers of bits EEMWE and EEWE respectively. In a 8-bit word, the least significant bit, LSB, is bit 0 and the most significant bit, MSB, is bit 7.

I don't have that datasheet handy but it is not important for understanding of << operation. Suppose EEWE is defined as "3", just for example. Then

EECR |= 1 << EEWE;

translates into less dramatic:

EECR = EECR | (1 << 3);

which would perform a logical OR between current EECR value and another 8-bit word, value of which would be? - your guess please.

The Dark Boxes are coming.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mats Bjorkman wrote:
microcarl your defines has the same PINB.0 all over...

[edit] but it is a very good tutorial 8)

Mats

Thanks! I fixed the .0 error.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

svofski wrote:

Quote:
Carl makes a point but you can't really write
Code:
#define PINB.0 0

And neither can I using ImageCraft. I only used

#define PINB.0 0

because that was the format the OP used.

But I can, in fact use:

#define PINB_0 0
#define PINB_1 1
#define PINB_2 2   
#define PINB_3 3
#define PINB_4 4
#define PINB_5 5
#define PINB_6 6
#define PINB_7 7

PORTB |= (1 << PINB_3);

and:

PORTB &= ~(1 << PINB_3);

Which is just fine with me.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is CV the only compiler that provides this extension?

#define PINB.7 7

The CV help file doesn't state clearly, but experiment indicates that this isn't
the way it works -- a reference to PINB.7 gives either 0 or 1 (as svofski suggests),
so an equivalent expression would be:

#define PINB.7 ((PINB & (1 << 7)) >> 7)

First thought is that the OP code isn't what was intended, or is at least
unnecessarily obscure.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does any of this need to be added as a codicil to Eric's tutorial that I linked to above?

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That CV's extension is actually pretty nice. Although it is widely believed that for example GCC easily optimizes code like
PORTA |= (1 << 5)
into single SBI instruction, this doesn't always work in more complex expressions. Just yesterday I had to use some inline assembly just to fight off one very stubborn thing, it was a time-sensitive piece. Probably, just probably, it could be unnecessary if GCC had stuff like PINB.7.. But this is only a rant.

The Dark Boxes are coming.