Here's an example:
// bit banged SPI pins
const byte MSPIM_SCK = 4; // port D bit 4
const byte MSPIM_SS = 5; // port D bit 5
const byte BB_MISO = 6; // port D bit 6
const byte BB_MOSI = 7; // port D bit 7
// for fast port access (Atmega328)
#define BB_MISO_PORT PIND
#define BB_MOSI_PORT PORTD
#define BB_SCK_PORT PORTD
const byte BB_SCK_BIT = 4;
const byte BB_MISO_BIT = 6;
const byte BB_MOSI_BIT = 7;
// control speed of programming
const byte BB_DELAY_MICROSECONDS = 4;
// Bit Banged SPI transfer
byte BB_SPITransfer (byte c)
{
byte bit;
for (bit = 0; bit < 8; bit++)
{
// write MOSI on falling edge of previous clock
if (c & 0x80)
BB_MOSI_PORT |= _BV (BB_MOSI_BIT);
else
BB_MOSI_PORT &= ~_BV (BB_MOSI_BIT);
c <<= 1;
// read MISO
c |= (BB_MISO_PORT & _BV (BB_MISO_BIT)) != 0;
// clock high
BB_SCK_PORT |= _BV (BB_SCK_BIT);
// delay between rise and fall of clock
delayMicroseconds (BB_DELAY_MICROSECONDS);
// clock low
BB_SCK_PORT &= ~_BV (BB_SCK_BIT);
// delay between rise and fall of clock
delayMicroseconds (BB_DELAY_MICROSECONDS);
}
return c;
} // end of BB_SPITransfer
void setup () { }
void loop () { }
You'll have to change the constants to suit.