SD Card SPI Initialization Guide: CMD0, CMD8, ACMD41 Explained
A practical SPI-mode startup sequence for SD, SDHC, and SDXC card bring-up, with command frames, expected responses, and the failure patterns that usually waste the most time.
Quick answer: minimal modern card flow
1. Power-up
Keep CS high, drive MOSI high, and send at least 74 clock pulses.
2. CMD0
Assert CS, send CMD0, expect R1 = 0x01.
3. CMD8
Send CMD8 with 0x1AA. Modern cards answer with an R7.
4. ACMD41 loop
Repeatedly send CMD55 then ACMD41 with HCS=1 until
R1 = 0x00.
5. CMD58
Read OCR with CMD58, then decide whether later accesses use block or byte
addressing.
For SDSC or very old cards, the flow changes after CMD8. This guide focuses on
the modern SD memory card path first because it is what most MCU projects need today.
Command checklist
| Command | Purpose | Typical argument / frame | Expected response |
|---|---|---|---|
| CMD0 | Reset card and request SPI mode | 40 00 00 00 00 95 | R1 = 0x01 means idle state entered |
| CMD8 | Check voltage range and card generation | 48 00 00 01 AA 87 | R7 echo ending in 0x01AA for SDv2+ |
| CMD55 | Prefix next command as application-specific | 77 00 00 00 00 01 | R1 = 0x01 while still idle |
| ACMD41 | Poll until internal initialization completes | 69 40 00 00 00 01 | 0x01 busy, then 0x00 ready |
| CMD58 | Read OCR and card capacity status | 7A 00 00 00 00 01 | R3; use CCS to distinguish SDSC from SDHC/SDXC |
| CMD16 | Set block length for SDSC access | 50 00 00 02 00 01 | Use when you need 512-byte SDSC block transfers |
Before CRC is explicitly enabled with CMD59, most SPI hosts send valid CRC for
CMD0 and CMD8, then use a dummy CRC byte such as 0x01
on later commands.
Prerequisites and SPI bring-up rules
Most SD card SPI failures start before the first command. Get the electrical and timing basics right before blaming the command sequence.
- Voltage: the card I/O is 3.3 V class. Use proper level shifting if the MCU is not 3.3 V compatible.
- Clock during init: keep
SCKin the 100 kHz to 400 kHz range until initialization is complete. - Default line states: keep
CShigh by default and driveMOSIhigh during the initial dummy clocks. - Pull-ups: keep
CSfrom floating and avoid a noisy or floatingMISOline during power-up. - Command pacing: after each command, keep clocking until a non-
0xFFresponse appears or the timeout expires. - Timeouts: never loop forever on
CMD0orACMD41. Timeouts make debugging sane.
The initialization sequence
The order matters. If the card does not reach the expected state, stop there and debug that transition before sending the next command.
Step 1: Power-up and dummy clocks
After power is stable, keep CS high and MOSI high, then send at
least 74 clock pulses. In practice, most firmware sends 80 clocks by
shifting ten bytes of 0xFF.
If you skip this, some cards never accept CMD0 cleanly because the internal
power-up state machine is not ready yet.
Step 2: Enter SPI mode with CMD0
Pull CS low and send CMD0:
40 00 00 00 00 95
The expected response is R1 = 0x01, which means the card is now idle and has
accepted SPI mode.
Step 3: Identify modern cards with CMD8
Send CMD8 with the standard 0x1AA argument:
48 00 00 01 AA 87 - Modern SD memory card: expect an
R7response whose tail echoes00 00 01 AA. - Illegal command: the card may be older SDSC or MMC, so the bring-up path changes.
For modern MCU work, this is the branch you usually want before moving to ACMD41.
Step 4: Loop on CMD55 + ACMD41 until ready
This is the core handshake. Send CMD55, then ACMD41 with
HCS=1 if you support high-capacity cards. Repeat until the card returns
R1 = 0x00.
0x01means the card is still busy initializing.0x00means initialization is complete and the card left the idle state.
Step 5: Read OCR with CMD58 and decide address mode
After the ACMD41 loop succeeds, send CMD58 to read the OCR
register and inspect the CCS bit.
- CCS = 1: SDHC or SDXC. Memory commands use block addressing and 512-byte blocks.
- CCS = 0: SDSC. Memory commands use byte addressing; set 512-byte block length with
CMD16if needed.
One of the most common post-init bugs is using SDSC byte addresses on an SDHC or SDXC card, which makes reads and writes look wrong by a factor of 512.
Reference pseudo-code
power_on_card();
delay_ms(5);
cs_high();
send_ff_clocks(10); // 80 clocks with MOSI high
for (retry = 0; retry < cmd0_timeout; retry++) {
r1 = send_cmd(CMD0, 0x00000000, 0x95);
if (r1 == 0x01) break;
}
r7 = send_cmd_long(CMD8, 0x000001AA, 0x87);
if (r7.r1 & 0x04) {
// Older SDSC or MMC path, not the main modern flow
}
deadline = now_ms() + 1000;
do {
send_cmd(CMD55, 0x00000000, 0x01);
r1 = send_cmd(ACMD41, 0x40000000, 0x01); // HCS = 1
} while (r1 == 0x01 && now_ms() < deadline);
ocr = send_cmd_long(CMD58, 0x00000000, 0x01);
if (ocr.ccs == 0) {
send_cmd(CMD16, 512, 0x01); // SDSC block length
addressing = BYTE_ADDRESSING;
} else {
addressing = BLOCK_ADDRESSING;
}
cs_high();
transfer_byte(0xFF); // trailing clocks before next transaction
Common failure cases
No 0x01 after CMD0
CSwas not high during the dummy clocks.- Initialization clock is too fast.
- The command frame or CRC byte is wrong.
- The card is not actually powered or level-shifted correctly.
CMD8 fails unexpectedly
- The card may be older SDSC or MMC.
- The host may not be clocking out enough bytes to read the full
R7response. - The line is sampled too early while the card still returns
0xFF.
ACMD41 never exits idle
CMD8was skipped on a modern card.HCSwas left clear while talking to SDHC or SDXC media.CMD55andACMD41sequencing is wrong.- The SPI clock is still out of range for initialization.
Reads and writes hit the wrong block
- SDSC: memory commands use byte addresses and usually need
CMD16. - SDHC or SDXC: memory commands use block addresses with fixed 512-byte blocks.
- If the offset looks wrong by 512x, check your CCS handling first.
FAQ
Why does SD card SPI mode require 74 clock cycles before CMD0?
The initial clocks give the card time to finish power-up and start sampling SPI commands.
Keep CS high, keep MOSI high, and send at least 74 clocks before
asserting CS for CMD0. Many firmwares send 80 clocks for margin.
What CRC bytes should I send for CMD0 and CMD8?
Send 0x95 for CMD0 with argument 0x00000000 and
0x87 for CMD8 with argument 0x000001AA. Later
commands usually use a dummy CRC byte unless CMD59 enables CRC checking.
Why does ACMD41 never leave the idle state?
Common causes are missing CMD8 before ACMD41 on modern cards,
HCS not set for SDHC or SDXC bring-up, SPI clock too fast during
initialization, or chip-select and command framing errors.
Do CMD0 and CMD8 need valid CRC in SPI mode?
Yes. Hosts typically send valid CRC for CMD0 and CMD8 during
startup. Later commands often use a dummy CRC byte while CRC checking stays disabled unless
CMD59 explicitly enables it.
When do I need CMD16 after initialization?
SDSC cards use byte addressing and usually need CMD16 to select a 512-byte
block length. SDHC and SDXC cards use fixed 512-byte blocks for memory access commands and
do not need CMD16 for standard block reads and writes.
Why do reads look shifted by a factor of 512?
That usually means the host is using SDSC byte addressing rules on an SDHC or SDXC card,
or the opposite. Check CMD58 CCS handling and make sure your later commands
use the correct address format.
Closing notes
The SPI startup sequence is strict, but it is also very deterministic. If you validate each response before moving on, SD card bring-up becomes much easier to debug than it first appears. For final edge cases and card-behavior details, use the SD Association Physical Layer Simplified Specification as the primary reference.