Help with basic bit shifting

I've tried looking around and doing some experiments but I can't wrap my head around this one.

Lets say I have a value in PORTD

PORTD=0b10101010;

However, I want to translated PORTB, bits 5 and 4 to be equivalent to PORTD bits 7 and 6.

PORTB |= PORTD7>>2 | PORTD6>>2;

However, that doesn't work :frowning: Any guidance would be appreciated

I think

  byte tmp = PORTD;
PORTB |= ((tmp >> 2) & 0x18);

should be correct

This is how I would do it...

First, shift PORTD to the right two, so bit 7 becomes bit 5, bit 6 becomes bit 4, and so on:

(PORTD >> 2)

Then, clear all the bits you don't want (everything except bits 4 and 5). Do this by bitwise-anding each bit with zero, except bits 4 and 5:

(PORTD >> 2) & 0b00110000

Finally, assign this to PORTB. If you want to replace the contents of PORTB with this result, just use normal assignment. If you want to combine the present contents of PORTB with the result, you would do a bitwise-or assignment:

PORTB = (PORTD >> 2) & 0b00110000;
PORTB |= (PORTD >> 2) & 0b00110000;

e: Magician, I think that would keep bits 3 and 4 (assuming we're counting from bit zero).
e2: Oops, pyro is right - you need to clear bits 4 and 5 in PORTB before assignment.

Maybe something like this: ( taken the bits are 0 - 7 not 1 - 8 )

PORTB = ( ( PORTD >> 2 ) & 0b00110000 ) | ( PORTB & 0b11001111 );

@Magician, would your version still work if PORTB has 5 or 4 set and PORTD doesn't have 6 or 7 set?

pYro_65:
Maybe something like this: ( taken the bits are 0 - 7 not 1 - 8 )

PORTB = ( ( PORTD >> 2 ) & 0b00110000 ) | ( PORTB & 0b11001111 );

@Magician, would your version still work if PORTB has 5 or 4 set and PORTD doesn't have 6 or 7 set?

That did it, thanks. The second part is key as it will give a weird "memory" effect without it.