Send one bit out per clock pulse received using direct port manipulation?
Example bit-banged SPI using port manipulation:



bitBangedSPIfast.h :

#include &lt;Arduino.h&gt;

class bitBangedSPIfast
  {
  // addresses of output ports - NULL if not applicable
  volatile byte * const mosiPort_;
  volatile byte * const misoPin_;
  volatile byte * const sckPort_;

  // bit masks for above
  const byte mosiBit_;
  const byte misoBit_;
  const byte sckBit_;

  // addresses of data direction register ports
  volatile byte * const mosiDDR_;
  volatile byte * const misoDDR_;
  volatile byte * const sckDDR_;

  // bit masks for above
  const byte mosiDDRBit_;
  const byte misoDDRBit_;
  const byte sckDDRBit_;

  // delay for clock being high
  unsigned long delayUs_;

  public:
    // constructor
    bitBangedSPIfast (
          // output ports
          volatile byte &amp; mosiPort, 
          const    byte mosiBit,
          volatile byte &amp; misoPin, 
          const    byte misoBit,
          volatile byte &amp; sckPort,
          const    byte sckBit,

          // data direction register ports
          volatile byte &amp; mosiDDR, 
          const    byte mosiDDRBit,
          volatile byte &amp; misoDDR, 
          const    byte misoDDRBit,
          volatile byte &amp; sckDDR,
          const    byte sckDDRBit,

          const unsigned long delayUs = 1)
       : 
         mosiPort_ (&amp;mosiPort), 
         mosiBit_  (1 &lt;&lt; mosiBit),
         misoPin_  (&amp;misoPin), 
         misoBit_  (1 &lt;&lt; misoBit), 
         sckPort_  (&amp;sckPort), 
         sckBit_   (1 &lt;&lt; sckBit), 

         mosiDDR_     (&amp;mosiDDR), 
         mosiDDRBit_  (1 &lt;&lt; mosiDDRBit),
         misoDDR_     (&amp;misoDDR), 
         misoDDRBit_  (1 &lt;&lt; misoDDRBit), 
         sckDDR_      (&amp;sckDDR), 
         sckDDRBit_   (1 &lt;&lt; sckDDRBit), 

        delayUs_ (delayUs) { }

    void begin ();
    byte transfer (byte input);

  };  // end of bitBangedSPIfast




bitBangedSPIfast.cpp :

#include &lt;bitBangedSPIfast.h&gt;

void bitBangedSPIfast::begin ()
  {
  if (mosiPort_)
    *mosiDDR_ |= mosiDDRBit_;    // output
  if (misoPin_)
    *misoDDR_ &amp;= ~misoDDRBit_;   // input
  *sckDDR_ |= sckDDRBit_;        // output
  }   // end of bitBangedSPIfast::begin


// Bit Banged SPI transfer
byte bitBangedSPIfast::transfer (byte c)
{       
  // loop for each bit  
  for (byte bit = 0; bit &lt; 8; bit++) 
    {
    // set up MOSI on falling edge of previous SCK (sampled on rising edge)
    if (mosiPort_)
      {
      if (c &amp; 0x80)
        *mosiPort_ |= mosiBit_;
      else
        *mosiPort_ &amp;= ~mosiBit_;
      }

    // finished with MS bit, get read to receive next bit      
    c &lt;&lt;= 1;

    // read MISO
    if (misoPin_)
      c |= (*misoPin_ &amp; misoBit_) != 0;

    // clock high
    *sckPort_ |= sckBit_;

    // delay between rise and fall of clock
    delayMicroseconds (delayUs_);

    // clock low
    *sckPort_ &amp;= ~sckBit_;

    // delay between rise and fall of clock
    delayMicroseconds (delayUs_);
    }  // end of for loop, for each bit

  return c;
  }  // end of bitBangedSPIfast::transfer  




Example usage:

#include &lt;bitBangedSPIfast.h&gt;

bitBangedSPIfast bbSPI (PORTD,  5, PIND,  6, PORTD, 7,    // MOSI port (D5), MISO pin (D6), SCK port (D7)
                        DDRD,   5, DDRD,  6, DDRD,  7);   // MOSI ddr  (D5), MISO ddr (D6), SCK ddr  (D7)
const byte mySS =  8;  // slave select

void setup (void)
  {
  bbSPI.begin ();
  pinMode (mySS, OUTPUT);
  }  // end of setup

void loop (void)
  {
  char c;

  // enable Slave Select
  digitalWrite(mySS, LOW); 

  // send test string
  for (const char * p = "Hello, world!" ; c = *p; p++)
    bbSPI.transfer (c);

  // disable Slave Select
  digitalWrite(mySS, HIGH);

  delay (100); 
  }  // end of loop




Reference

SPI - Serial Peripheral Interface - for Arduino