En realidad, la mayoría de la información / código que puede encontrar en la inicialización de SD está fechada o no es correcta, ya que es anterior a SDHC y SDXC por años. El procedimiento es más complicado hoy en día, ya que te obliga a lidiar con el hardware antiguo de una manera compatible con versiones anteriores.
En primer lugar, como lo mencionaron otros, seleccione una frecuencia de reloj inicial baja (generalmente en el rango de 100 kHz - 400 kHz; use 400 kHz si es posible); podrá cambiar a un reloj más alto más adelante, si el dispositivo lo permite. Mientras que las nuevas tarjetas pueden soportar de manera segura el reloj de MHz-ish, las antiguas se quejarán (es decir, no se comunicarán ni devolverán basura).
Lo siguiente es que no debe usar CMD1
para inicializar tarjetas SD / SDHC / SDXC a menos que su tarjeta no reconozca CMD55
/ ACMD41
; como se dice en la especificación de la tarjeta SD:
En cualquiera de los casos, no se recomienda CMD1 porque puede ser difícil para el host distinguir entre MultiMediaCard y SD Memory Card.
Algunos controladores (tarjetas más nuevas y de mayor capacidad en su mayoría) simplemente permanecerán en IDLE si los emite CMD1
. Primero debe emitir CMD8 0x1AA
después del reset ( CMD0
), y luego intentar usar CMD55 + ACMD41
. Si y solo si eso falla, úselo CMD1
.
tl; dr para inicializar la tarjeta en modo SPI debe:
CMD0
arg:, 0x0
CRC: 0x95
(respuesta:) 0x01
- tenga en cuenta que en caso de 0xFF
respuesta confusa, simplemente repita este paso; ver abajo para más información.
CMD8
arg:, 0x000001AA
CRC: 0x87
(respuesta:, 0x01
seguida de eco de arg, en este caso 0x000001AA
), aunque puede parecer que este comando es opcional, es completamente obligatorio para las tarjetas más nuevas. Si bien 0x1AA
es un valor arg común aquí, en realidad también puede pasar otros valores; consulte "Tabla 7-5: Operación de la tarjeta para CMD8 en modo SPI", pág. 108 en especificaciones para más detalles.
3a. CMD55
arg:, 0x0
CRC: any, en 0x65
realidad (respuesta 0x01
:; CMD55
siendo el prefijo de todos ACMD
; si la respuesta es 0x05
, tienes una tarjeta vieja - repite CMD1
con arg 0x0
[CRC 0xF9
] en lugar de CMD55
/ ACMD41
)
3b. ACMD41
, arg:, 0x40000000
CRC: any, en 0x77
realidad (tenga en cuenta que este argumento supone que la tarjeta es una HCS, que suele ser el caso; utilice 0x0
arg [CRC 0xE5
] para tarjetas más antiguas). Si la respuesta es 0x0
, estás bien; si es así 0x01
, pase a 3a; si es así 0x05
, vea la nota arriba (en 3a.); si no es ninguno, algo está mal (también ver más abajo).
La mayoría de las tarjetas requierenCMD1
que se repitan los pasos 3a / 3b (o para tarjetas viejas), generalmente al menos una vez, incluso si espera un tiempo entre ellas ; es decir, la secuencia real es CMD0
/ CMD8
/ CMD55
/ ACMD41
/ CMD55
/ ACMD41
(o CMD0
/ CMD8
/ CMD1
/ CMD1
) - para estar seguro, pruebe el CMD55
/ ACMD41
(o CMD1
si lo obtuvo 0x05
) veces (seleccione dentro de su razón; en realidad es bastante común tener que esperar un un par de cientos de ms si el dispositivo está justo después del encendido, así que apúntelo), con pequeños retrasos entre los intentos si lo desea, y suponga que falla si la respuestanortenorte0
no aparece (es decir, si el dispositivo permanece en modo inactivo por alguna razón). Además, la recepción 0xFF
de CMD0
es común si un dispositivo estaba en un estado "extraño" anteriormente (por ejemplo, colgó, se desasistió S̲S̲ [alto], tenía sobretensión / subtensión en algunos pines, etc.) - solo déle algo de tiempo, enjuague y repita veces Una respuesta a ilegible está bastante bien a veces - si ha enviado un par de veces y la respuesta no es aún ni tampoco , tratar de seguir adelante con . Si funciona, estás listo para ir; si no es así, probablemente esté roto .norteCMD0
0xFF
0x01
CMD8
Tenga en cuenta que las respuestas que tienen el MSB establecido pero que no 0xFF
suelen sugerir que su SPI haya cambiado en la sincronización (como resultado de, por ejemplo, la caída de Vcc, que ocurre de manera rutinaria cuando está haciendo hotplugs SD). Para solucionarlo, puede intentar restablecer completamente el dispositivo (encendido / apagado, desassert / afirmar S̲S̲, etc.); Por lo general funciona.
Además, la especificación dice
Después de la última transacción del bus de la tarjeta de memoria SD, se requiere que el host proporcione 8 (ocho) ciclos de reloj para que la tarjeta complete la operación antes de apagar el reloj.
Podría funcionar sin él, pero como 8 ciclos = 1 byte de salida SPI, no hará mucho daño y es bueno tenerlo.
Tenga en cuenta que debe afirmar que S̲S̲ (también conocido como CS) es bajo al menos antes y después de cada uno CMD
; es completamente obligatorio en caso de que CMD0
(el dispositivo no se encienda sin él) y, en realidad, es obligatorio para todos los demás CMD
si tiene un estándar tarjeta SD compatible. Conectar el S̲S̲ de la tarjeta a GND de forma permanente puede parecerser una buena idea si la tarjeta es el único cliente SPI al que se conectará su host, ya que le ahorraría tanto el pin de salida uC como la necesidad de administrarlo por código, y porque la tarjeta debería asumir que está seleccionado todo del tiempo. En realidad, algunas cartas (si no la mayoría de ellas) realmente esperan que se active una pendiente de alta a baja en lugar de simplemente detectar baja, y por lo tanto se enojan si no alternan el bit S̲S̲ en absoluto, y luego se retrasan relojes o escupir basura; algunas tarjetas (generalmente más nuevas) deberían funcionar, algunas (más antiguas) pueden no funcionar, YMMV (una vez más). Aún así, para cualquier configuración SPI más robusta (> 1 dispositivo esclavo) recuerde afirmar el pin bajo antes de cualquier transacción real con la tarjeta SD dada.
Además, aunque la especificación dice que solo CMD0
y CMD8
debe tener CRC en modo SPI, algunas tarjetas SD (como las de Transcend) parecen requerir CRC adecuado para CMD55
/ ACMD41
- si desea estar seguro, simplemente use un valor precalculado para ellas.
Además, si bien SPI no requiere pullups / down por sí solo, lanzar una pullup de 47k en MISO puede ser una buena idea; algunos dispositivos dejan su pin DO alto-Z bajo circunstancias específicas (no inicializadas, por ejemplo), y los pines flotantes siempre pueden ser una fuente de problemas extraños. Si su uC tiene 3.3 Vcc, puede usar pullups internos; si es 5V, no lo haga a menos que su línea MISO ya tenga una traducción lógica adecuada de 5-> 3.3V.
Otras lecturas:
Cómo usar MMC / SDC
Especificaciones SD Parte 1 Capa física simplificada Especificación simplificada : lo más importante, secciones 6.4.1 Encendido y 7.2.1 Selección e inicialización del modo con la Figura 7-1 : Diagrama de estado de la tarjeta de memoria SD (modo SPI)
CMD8
emisión previa. Además, el reloj generalmente no es un problema, siempre que esté dentro del rango razonable.