打印
[STM32]

STM32F4,sd卡采用spi接口,初始化ACMD41一直返回0x01;

[复制链接]
3407|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tt朝花夕拾|  楼主 | 2017-7-26 15:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在调试一个spi的sdcard,发现在初始化时,ACMD41一直返回0x01;想请教下大家有没有好的建议排查;
1 查看了sdcard spi模式的初始化流程,觉得也是对的;
上电,cs拉高,发送spi 80个clk,cs拉低,发送CMD0,返回0x01;
发送(CMD8,0x1AA),返回R1=0x01;读取ocr,也是可以读到ocr 0x01和0xAA,
可是发送CMD55 R1=0x01,ACMD41 R1=0x1,而且一直是0x01
这个地方表示sd卡一直都没有进入初始化完成状态;
2 主电源断点,power off重新上电后,ACMD41又可以正常返回0x00;
3 再次关闭主电源,重新上电后,ACMD41再次不能正常返回0x00;
如此,交替ok;比较异常;
个人还是比较怀疑我的spi sdcard上电流程上哪里出了问题,
还请大神帮忙诊断;
附上初始化的一小段代码;

DSTATUS spisd_disk_initialize (
        BYTE drv                /* Physical drive nmuber (0) */
        )
{
    BYTE n, cmd, ty, ocr[4];
        uint16_t retry = 0;
        BYTE ret = 0;

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

    MMC_SPI_Config();
   
    MMC_POWERON();                                            /* Force socket power on */

        delay_ms(500);

    SPI_LowSpeed();   
    MMC_DESELECT();
    /* Wait for enter Idle state in timeout of 5000 msec */
        /* retry 10 times*/
    retry = 50;
    do
        {
        for (n = 10; n; n--) SPI_ReadWrite_Byte(0xFF);            /* 80 dummy clocks */
    }
    while((Send_Command(CMD0,0) != 1) && retry--);

    ty = 0;
    retry = 0xfffe;                                /* Initialization timeout of 2000 msec */
    if (Send_Command(CMD8, 0x1AA) == 1)        /* 检查是否支持SDC Ver2 */
    {
        for (n = 0; n < 4; n++)
        {
            ocr[n] = SPI_ReadWrite_Byte(0xff);        /* Get trailing return value of R7 resp */
                }
                printf("ocr2=0x%x ocr3=0x%x \r\n",ocr[2],ocr[3]);
        if (ocr[2] == 0x01 && ocr[3] == 0xAA)
        {                       
            /* The card can work at vdd range of 2.7-3.6V */
            /* Wait for leaving idle state (ACMD41 with HCS bit) */
                        do
                        {
                                ret = Send_Command(ACMD41,0x40000000);
                                printf("ACMD41 ret=%d\r\n",ret);
                        }
            while ((--retry) && ret);
                       
                        printf("retry %d \r\n",retry);

            if ((retry) && Send_Command(CMD58,0) == 0)
            {               
                /* Check CCS bit in the OCR */
                for (n = 0; n < 4; n++)
                    ocr[n] = SPI_ReadWrite_Byte(0xff);
                /* When CCS bit is set  R/W in block address insted of byte address */
                ty = (ocr[0] & 0x40) ? 12 : 4;
            }
        }
    }
    else
    {
        /* SDSC or MMC */
        if (Send_Command(ACMD41, 0) <= 1) /* initialize successful will response 0x00 */
        {
            ty = 2; cmd = ACMD41;        /* SDv1 */
        }
        else
        {
            ty = 1; cmd = CMD1;                /* MMC */
        }
        while ((--retry) && Send_Command(cmd, 0));                        /* Wait for leaving idle state */
        if (!retry || Send_Command(CMD16, 512) != 0)        /* Set R/W block length to 512 */
            ty = 0;
    }

    CardType = ty;       
    SPI_HighSpeed();
    SPI_Release();

    if (ty)
    {   /* Initialization succeded */
        Stat &= ~STA_NOINIT;       
                printf("ty %d stat %d\r\n",ty,Stat);               
    }
    else
    {        /* Initialization failed */
                printf("ty %d stat %d\r\n",ty,Stat);
        MMC_POWEROFF();
    }
    return Stat;
}

相关帖子

沙发
tt朝花夕拾|  楼主 | 2017-7-26 15:08 | 只看该作者
哦,再次补充下,硬件状态,sdcard的VDD为常供,即主电源上点,sdcard VDD就存在 3.28v电压;

使用特权

评论回复
板凳
tt朝花夕拾|  楼主 | 2017-7-27 10:25 | 只看该作者
特此在做一些结帖;
先说下我的问题原因,是因为sdcard的VDD在不能复位到0v,因为硬件电路设计的问题,确定每次都复位0v后,识别测试正常,ACMD41在每次复位后都可以正常返回0x0了;
类似的ACMD41返回问题,查了很多帖子,大致的返回值有 0x1,0x5,0xff,这3种返回值都不对,正常的情况下,应该是返回0x01几次后,返回0x00;表示sdcard初始化完成;
1 如果一直返回0x01;我的建议排查有几点:
第一点:排查供电电压,因为常规的microSD,都是工作在2.7~3.6v的,所以先确认下VDD的供电电压;
第二点:确定ACMD41的参数,0x40000000 表示大容量卡,而如果是<= 2G的卡,则需要传入0x00000000,bit[30] 这1位;
第三点:ACMD41,应该是循环发送的,请确保retry的次数是否足够,理论上的超时时间是1s;所以确认是否时间;
2 如果返回0x05,表示的是非法命令,
第一点:确定你的卡是不是大容量;sd卡还是MMC类型;
第二点:ACMD41的参数,以及CRC校验是否正确,理论上CRC在spi模式下是可以发送dumy CRC,不过cmd0 cmd8 要注意需要传入正确的CRC;
3 如果是返回0xff,则说明sd卡的硬件环境问题比较大;
第一点,查spi速率,要在低速下,小于400k,
第二点,查电源,是否上到3.3v;
第三点,查下spi线路是否正常;
第四点,spi发送的retry次数是否过小;

以上个人的小总结;具体还是要多看下论坛,以及sdcard 2.0协议介绍;

使用特权

评论回复
地板
幸福四叶草| | 2019-3-28 19:19 | 只看该作者
楼主的sdcard常供电问题怎么解决的,不改电路有办法解决吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

19

帖子

0

粉丝