Is there a way to write only the lower 4 bits of a byte on Port D

Is there a way to write only the lower 4 bits of a byte on Port D (PD0 –PD3) ?.

The 4 bits are generated from a loop counter, and are used to drive a 16:1 74LS154 mutliplexer to select the CS of multiple SPI devices.

I am using Timer0 and Timer1 external interrupts (same pins as PD4 and PD5) and therefore want to avoid writing the whole byte.

I cannot use Port B as I am using the SPI for read and write (SCK, MISO, MOSI), which leaves only 3 bits available.

I cannot use Port C as I am using the I2C (SDA, SCL) to drive a display, and serval analogue inputs (ADC0 to ADC2).

Thanks

No, a port write is always 8 bits. You have to read the port first, or in your d0-d3 bits and then write it back.

Do your homework. Google Arduino port write.

There are two ways that can be used to "write the lower 4 bits of a port"

  1. read the port, mask in your four bits, and write the value back out:
temp = (PORTB & 0xF0);  // mask off lower four bits
temp |= myval & 0xF;    // add in the new four bits
PORTB = temp;  // write back out
  1. write the bits individually. For the application you describe, where you are looping through multiple multiplexer values, you might be able to get clever with which chip-select goes where and use a sort of Gray code that requires a minimum of bit changes between states:
//assume D0:3 = 0 to start with
spi_read_stuff();
PORTB |= 0b0001;  // 1 means CS 1
spi_read_stuff();
PORTB |= 0b0010  //  11 means CS 2
spi_read_stuff();
PORTB &= ~0b0001;  // 10 means CS 3
// ... etc

Write the bits individually as follows (@westfw):

byte counter = 0xnn;    //value is updated by a loop counter

for(int i = 0; i<4; i++)
{
   bitWrite(PORTD, i, bitRead(counter, i));  //lower 4-bit of counter gets written into lower 4-bit of PORTD
}