Skip to main content
6 of 7
Trying to comment, but can't do so, so editing to ask the question.

To write SPI data using library one uses the SPI library's transfer() function: it takes a byte argument and actually sends it over the SPI bus. You can specify more arguments, namely what to do with SS pin, but this doesn't seem to concern you.

The Arduino SPI EEPROM example might also be useful.

If you need to send data that isn't 8-bytes, it would be exceedingly convenient if the data size (in bits) was a multiple of 8. In this case, the data is sent in 8-bit (or one-byte) chunks. The simplest way to do it is to treat your data as a byte array:

byte data[] = {0x00, 0x00, 0x00, 0x00};  // this is 24 bits (8bits/byte * 4 bytes)

Question (Lardconcepts): The only way to comment seems to be to edit, so:

I'm very confused by this "8*4=24" bit above and below. This doesn't make sense to me. Also, isn't it SPI.transfer, not just transfer ?

// Transfer 24 bits of data
for (int i=0; i<4; i++) {
   transfer(data[i]);   // Send 8 bits
}

Sending data that isn't a multiple of 8 bits is a bit tricky with SPI on Arduino/AVR. But it appears that indeed, your EEPROM requires 25 bit data for writing. Since Arduino SPI only allows data to be sent in 8-bit chunks, the solution is to generate the start condition before you send the SPI data using the SPI library:

  // This is our setup
  pinMode(ss, OUTPUT);
  digitalWrite(ss, LOW);

  // Generate the start condition
  digitalWrite(ss, HIGH);
  digitalWrite(SPI_MOSI, HIGH);
  digitalWrite(SPI_CLK, HIGH);
  delay(1); // pause
  digitalWrite(SPI_CLK, LOW);
  // done with the start condition

  // Normal SPI write
  // no need to twiddle SS bits since SS is already high
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  ... // send stuff here
  digitalWrite(ss, LOW);

This technique is called bit-banging: raising and lowering of digital outputs in software in accordance with some protocol specification in order to interface with some peripheral or communicate with another chip. In fact, you could bit-bang all the data yourself using digitalWrite(), and bypass the SPI library altogether. It isn't really difficult, and we are already doing that to generate the start condition. What this would look like for every bit:

digitalWrite(SPI_CLOCK, LOW);
digitalWrite(SPI_MOSI, yourBitValueHere);
digitalWrite(SPI_CLOCK, HIGH);
delay(1);

SPI_MOSI would be the pin connected to your EEPROM's DI pin, or the SPI DATA pin on your Arduino. SPI_CLOCK would be the pin connected to your EEPROM's CLK pin. If you are not using the SPI library you could connect any digital output pins to the EEPROM. The spi library is limited to using Arduino's SPI pins, I believe.

angelatlarge
  • 3.6k
  • 23
  • 37