硬汉嵌入式论坛

 找回密码
 立即注册
查看: 424|回复: 2
收起左侧

[有问必答] SD初始化问题

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 2025-4-30 14:12:50 | 显示全部楼层 |阅读模式
使用的是stm32F407驱动一个32G的tf卡,使用的SPI模式。第一次上电时,卡识别初始化能通过,但是再keil调试时复位,再运行到初始化这里。卡识别初始化一直过不了。这个时候拔插一次tf卡,再次初始化就能通过。这是什么原因?怎么解决?

初始化代码部分:
uint8_t SD_Initialize(void)
{
    uint8_t r1;      // 存放SD卡的返回值
    uint16_t retry;  // 用来进行超时计数
    uint8_t buf[4];
    uint16_t i;

    SD_SPI_Init();                //初始化IO
    for (i = 0; i < 10; i++)SD_SPI_ReadWriteByte(0XFF); //发送最少74个脉冲
    retry = 20;
    do
    {
        r1 = SD_SendCmd(CMD0, 0, 0x95); //进入IDLE状态
    }
    while ((r1 != 0X01) && retry--);
    SD_Type = 0; //默认无卡
    if (r1 == 0X01)
    {
        if (SD_SendCmd(CMD8, 0x1AA, 0x87) == 1) //SD V2.0
        {
            for (i = 0; i < 4; i++)buf[i] = SD_SPI_ReadWriteByte(0XFF);        //Get trailing return value of R7 resp
            if (buf[2] == 0X01 && buf[3] == 0XAA) //卡是否支持2.7~3.6V
            {
                retry = 0XFFFE;
                do
                {
                    SD_SendCmd(CMD55, 0, 0X01);        //发送CMD55
                    r1 = SD_SendCmd(CMD41, 0x40000000, 0X01); //发送CMD41
                }
                while (r1 && retry--);
                if (retry && SD_SendCmd(CMD58, 0, 0X01) == 0) //鉴别SD2.0卡版本开始
                {
                    for (i = 0; i < 4; i++)buf[i] = SD_SPI_ReadWriteByte(0XFF); //得到OCR值
                    if (buf[0] & 0x40)SD_Type = SD_TYPE_V2HC; //检查CCS
                    else SD_Type = SD_TYPE_V2;
                }
            }
        }
        else //SD V1.x/ MMC        V3
        {
            SD_SendCmd(CMD55, 0, 0X01);                //发送CMD55
            r1 = SD_SendCmd(CMD41, 0, 0X01);        //发送CMD41
            if (r1 <= 1)
            {
                SD_Type = SD_TYPE_V1;
                retry = 0XFFFE;
                do //等待退出IDLE模式
                {
                    SD_SendCmd(CMD55, 0, 0X01);        //发送CMD55
                    r1 = SD_SendCmd(CMD41, 0, 0X01); //发送CMD41
                }
                while (r1 && retry--);
            }
            else
            {
                SD_Type = SD_TYPE_MMC; //MMC V3
                retry = 0XFFFE;
                do //等待退出IDLE模式
                {
                    r1 = SD_SendCmd(CMD1, 0, 0X01); //发送CMD1
                }
                while (r1 && retry--);
            }
            if (retry == 0 || SD_SendCmd(CMD16, 512, 0X01) != 0)SD_Type = SD_TYPE_ERR; //错误的卡
        }
    }
    SD_DisSelect();//取消片选
    if (SD_Type)return 0;
    else if (r1)return r1;
    return 0xaa;//其他错误
}
发送CMD8时,响应值正常。CMD55也正常响应。ACMD41返回值一直是0x01(r1 = SD_SendCmd(CMD41, 0x40000000, 0X01); //发送CMD41)。
if (buf[2] == 0X01 && buf[3] == 0XAA) //卡是否支持2.7~3.6V
            {
                retry = 0XFFFE;
                do
                {
                    SD_SendCmd(CMD55, 0, 0X01);        //发送CMD55
                    r1 = SD_SendCmd(CMD41, 0x40000000, 0X01); //发送CMD41
                }
                while (r1 && retry--);
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 2025-5-4 11:17:42 | 显示全部楼层
这个建议以冷启动为准,也就是不连接下载器的情况下,反复上电和下电,测试是否正常。
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2025-5-14 09:41:10 | 显示全部楼层
eric2013 发表于 2025-5-4 11:17
这个建议以冷启动为准,也就是不连接下载器的情况下,反复上电和下电,测试是否正常。

冷启动是可以的,不过冷启动不就相当于插拔了一次SD卡吗?后面我在代码里试着初始化两次,用冷启动的方式,只是能通过第一次初始化,第二次就失败了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-10 06:52 , Processed in 0.228582 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表