Electrical – Bit shifting and PORT value on PIC18F4520


I am working on a PIC18f4520.
To do my test, I have connected a led to the pic. The following items are the steps I would like to do :

  • Save the value of the port set for the LED (which blinks according to the ISR subroutine I wrote, and can be look at in this case as a clock signal). For this I did :

    unsigned char portValue;   // initialization
    TRISBbits.TRISB5 = 0;      // LED on RB5 set as output
    portValue = PORTBbits.RB5; // operation in the main while loop  
  • Left shift the bits of portValue by one but with the insertion of the RB5 value. To illustrate :

    --> if RB5 = 1, I would have portValue = 0b0000 0001 
    --> at t+1, RB5 = 0 then portValue = 0b0000 0010
    --> at t+2, RB5 = 1 then portValue = 0b0000 0101
    --> and so on (RB5 taking 1 or 0 and no other value)

With what I have wrote so far I can only do a left shifting. But I can't find a way to "add" the RB5…

Does something like

portValue = portValue<<(&PORTBbits.RB5); 

could work ?
Bit shifting operations are quite new to me so my questions can be odd.

Anyhow, thanks in advance !

Best Answer

Bitshifting works like this:

result = value << amount

this shifts the bits of the variable value by amount of bits to the left. Use >> for right shifting.

So before you store your new bit, you want do shift portValue by one bit, like this:

portValue = portValue << 1;

Now the first bit will be 0 by default and you can store your new bit there like this:

portValue = portValue | PORTBbits.RB5;

This assumes that the variable PORTBbits.RB5 will only have the values 0 or 1 so every other bit except bit 0 is always 0. To make sure of this you can mask PORTBbits.RB5 with 0x01 like this:

portValue = portValue | (PORTBbits.RB5 & 0x01);

This will make sure that only the first bit will be changed.

This can now be combined in one line if you like:

portValue = (portValue << 1 ) | (PORTBbits.RB5 & 0x01);