La tarjeta SD no se comunica - STM32

0

He implementado los controladores de palanca baja de los fatfs. Intenté escribir un archivo txt en una tarjeta SDHC, pero nunca puedo inicializar la tarjeta. MCU es STM32F103C8T6. Estoy usando CubeMX con las bibliotecas HAL y usando SPI para comunicarme. Depuré para descubrir que durante wait_ready() , se supone que la tarjeta debe devolver 0xFF para indicar que está lista, pero en mi caso, devuelve 0x00, no importa cuánto tiempo espere. Si omito el comando wait_ready () y envío el comando IDLE (CMD0), todavía obtengo 0x00 como respuesta. He habilitado el pull-up interno para el pin MISO, no ayudó. La parte interesante es que, cuando probé el pin MISO justo después de su inicialización, noté que estaba a 0.01 voltios. Me parece que no estaba siendo elevado. También me aseguré de que la velocidad del reloj SPI estuviera entre 100 kHz y 400 kHz.

Logré escribir en la tarjeta conectándola a mi computadora. También logró escribir con un arduino. Las siguientes son las partes relevantes de mi código. Puede ignorar las implementaciones de tiempo de espera.

static BYTE wait_ready(void) {
Timer2 = 255;
rcvr_spi();
do
    res = rcvr_spi();
while ((res != 0xFF) && Timer2--);

return (res == 0xFF) ? 1 : 0;
}

void deselect()
{
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
    xmit_spi(0xFF);
}

uint8_t select()
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);

xmit_spi(0xFF);
if(wait_ready()) return 1;
deselect();

return 0;
}

DSTATUS USER_initialize (
BYTE pdrv           /* Physical drive nmuber to identify the drive */
)
{
  BYTE n, ty, ocr[4];

if (pdrv)
    return STA_NOINIT; /* Supports only single drive */
if (Stat & STA_NODISK)
    return Stat; /* No card in the socket */

deselect();

//send_initial_clock_train();
for (int i = 0; i < 10; i++)
    xmit_spi(0xFF); 

HAL_Delay(10);

ty = 0;
uint32_t tick = HAL_GetTick();

if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
    Timer1 = 100; /* Initialization timeout of 1000 msec */
    if (send_cmd(CMD8, 0x1AA) == 1) { /* SDC Ver2+ */
        for (n = 0; n < 4; n++)
            ocr[n] = rcvr_spi();
        if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
            do {
                if (send_cmd(CMD55, 0) <= 1
                        && send_cmd(CMD41, 1UL << 30) == 0)
                    break; /* ACMD41 with HCS bit */
            } while (Timer1);
            if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
                for (n = 0; n < 4; n++)
                    ocr[n] = rcvr_spi();
                ty = (ocr[0] & 0x40) ? 6 : 2;
            }
        }
    } else { /* SDC Ver1 or MMC */
        ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) ? 2 : 1; /* SDC : MMC */
        do {
            if (ty == 2) {
                if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0)
                    break; /* ACMD41 */
            } else {
                if (send_cmd(CMD1, 0) == 0)
                    break; /* CMD1 */
            }
        } while (Timer1);
        if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Select R/W block length */
            ty = 0;
    }
}
CardType = ty;
deselect(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */

if (ty) /* Initialization succeded */
    Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */


return Stat;
}

static void xmit_spi(BYTE Data)
{
 while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
 HAL_SPI_Transmit(&hspi1, &Data, 1, 5000);
}

static BYTE rcvr_spi(void)
{
 unsigned char Dummy, Data;
 Dummy = 0xFF;
 Data = 0;
 while ((HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY));

 HAL_SPI_TransmitReceive(&hspi1, &Dummy, &Data, 1, 5000);

 return Data;
}

¿Qué estoy haciendo mal?

    
pregunta zeke

0 respuestas

Lea otras preguntas en las etiquetas