Issues with Sending an SPI Command


I am trying to set up a micro SD card using a SPI network with an Arduino Mini. I’m currently just trying to get the basics up and running using the code provided by the Arduino playground, found here:

The only change in my code is the pin location declarations, which for are as follows:

//SPI pins:
int PIN_CS = 10; //Chip select
int PIN_MOSI = 11; //Master out slave in
int PIN_MISO = 12; //Master in slave out
int PIN_CLOCK = 13; //Clock

I am presently having some problems with the void setup() function. When I try to run the sdc_totalNbrBlocks() function (which gets the number of blocks on the SD memory care), I end up in an infinite loop.

After doing some digging, I found that the code is stuck in the sdc_readRegister() function which reads the SD card register content and stores it in a buffer. The line it is stuck at is:

while (spi_cmd(0xFF) != 0xFE)

Looking more into the code, I found that I am also having problem in the spi_cmd function, which is used to send a SPI command. Basically, waiting for the end of transmission fails and an error value is returned. So I think this part of the code might be the root cause of the issue. This is the while loop where it fails:

while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
    if (i >= 0xFF)
      spi_err = 1;
      Serial.print("Error Value: ");
      Serial.println(spi_err, DEC);

It seems like a lot of people have used and tested this code from Arduino program, so I’m not quite sure how to fix the issue. Could this be a hardware setup or a pin initialization error?

Help is appreciated. Please let me know if you need more information about the code. Thanks,

  • Julie

This library does not use the official Arduino procedures to setup the pins:

  PORTB |=  (1<<PIN_CS);          // deasserts card for warmup
  PORTB |=  (1<<PIN_MOSI);        // set MOSI high

For example, you assigned 10 to PIN_CS. 10 is the (indeed correct) number for the CS pin in the Arduino world. But in this case PIN_CS should have the bit-number of the CS line in port B, which actually has the value 2. So, i guess the original values are still correct for the Mini:

// Ports
int PIN_CS = PINB2;      // chip select
int PIN_MOSI = PINB3;    // master out slave in
int PIN_MISO = PINB4;    // master in slave out
int PIN_CLOCK = PINB5;   // clock


The only change in my code is the pin location declarations

Not sure what you posted because what followed is the pins, is it just the names you changed?

You can't change what pins you use for this process because it is defined at the hardware level.

That worked! Thanks so much for your help!!