利用STM32Cube移植FatFs文件系统,f_Open返回FR_NOT_READY

2019-07-14 13:59发布



新手移植FatFs文件系统,利用STM32Cube,初始化SPI2,选择PB9作为片选信号,没用使用cube自带的fatfs文件系统;问题如标题所示,f_Open返回FR_NOT_READY,通过断点调试,发现在调用SD_Init()函数中,发送CMD0,让SD进入IDLE状态时,返回值不是0x01;调试了一周,也没找到问题所在。【系统时钟160MHz,SPI2所在的APBH1时钟为40MHz,SD卡为16G的SDHC卡】,跪求指导;
代码见楼下:
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
7条回答
60user125
2019-07-15 07:33
Part2:
/*******************************************************************************
* Function Name  : SD_Init
* Description    : ³õʼ»¯SD¿¨
* Input          : None
* Output         : None
* Return         : u8
*                  0£ºNO_ERR
*                  1£ºTIME_OUT
*                  99£ºNO_CARD
*******************************************************************************/
u8 SD_Init(void)
{
    u16 i;      // ÓÃÀ´Ñ­»·¼ÆÊý
    u8 r1;      // ´æ·ÅSD¿¨µÄ·µ»ØÖµ
    u16 retry;  // ÓÃÀ´½øÐг¬Ê±¼ÆÊý
    u8 buff[6];

    //Èç¹ûûÓмì²âµ½¿¨²åÈ룬ֱ½ÓÍ˳ö£¬·µ»Ø´íÎó±êÖ¾
//    if(!SD_DET())
//    {
//        //return 99;        
//        return STA_NODISK;  //  FatFS´íÎó±êÖ¾£ºÃ»ÓвåÈë´ÅÅÌ
//    }

    //SD¿¨Éϵç
   // SD_PWR_ON();
    // ´¿ÑÓʱ£¬µÈ´ýSD¿¨ÉϵçÍê³É
  
        /*******************************************************
        //Õâ¸öµØ·½Òª¼ÓÒ»¾ä,ÉèÖÃSPIËÙ¶ÈΪµÍËÙ¡£
        //ΪʲôÓеĿ¨¿ÉÒÔÄØ£¿ÒòΪSPI³õʼ»¯Ê±ÊǵÍËٵģ¬SD¿¨³õʼ»¯
        //Íê³ÉºóÉèÖÃΪ¸ßËÙ£¬ÓеĿ¨Ö»Òª³õʼ»¯Ò»´Î¾ÍÐУ¬³ÌÐò¾Íok£»
        //µ«ÓеĿ¨ÐèÒª¶à´Î¸´Î»£¬ºÇºÇ£¬Õâ¸öµØ·½²îÕâÒ»¾ä£¬
        //ÕâÖÖ¿¨¾ÍÓò»³É¿©£¡
        *******************************************************/
    SPI_SetSpeed(0); //ÉèÖÃSPIËÙ¶ÈΪµÍËÙ
               
    //ÏȲúÉú>74¸öÂö³å£¬ÈÃSD¿¨×Ô¼º³õʼ»¯Íê³É
    for(i=0;i<10;i++)
    {
        SPI_ReadWriteByte(0xFF);
    }

    //-----------------SD¿¨¸´Î»µ½idle¿ªÊ¼-----------------
    //Ñ­»·Á¬Ðø·¢ËÍCMD0£¬Ö±µ½SD¿¨·µ»Ø0x01,½øÈëIDLE״̬
    //³¬Ê±ÔòÖ±½ÓÍ˳ö
                SD_CS_ENABLE();
    retry = 0;
    do
    {
        //·¢ËÍCMD0£¬ÈÃSD¿¨½øÈëIDLE״̬
        r1 = SD_SendCommand(CMD0, 0, 0x95);
        retry++;
    }while((r1 != 0x01) && (retry<200));

    //Ìø³öÑ­»·ºó£¬¼ì²éÔ­Òò£º³õʼ»¯³É¹¦£¿or ÖØÊÔ³¬Ê±£¿
    if(retry==200)
    {
        return 1;   //³¬Ê±·µ»Ø1
    }
//                retry=20;
//                do
//                {
//                        r1=SD_SendCommand(CMD0,0,0x95);
//                }while((r1!=0x01)&&retry--);
//                SD_Type=0;
    //-----------------SD¿¨¸´Î»µ½idle½áÊø-----------------



    //»ñÈ¡¿¨Æ¬µÄSD°æ±¾ÐÅÏ¢
    r1 = SD_SendCommand_NoDeassert(8, 0x1aa, 0x87);

    //Èç¹û¿¨Æ¬°æ±¾ÐÅÏ¢ÊÇv1.0°æ±¾µÄ£¬¼´r1=0x05£¬Ôò½øÐÐÒÔϳõʼ»¯
    if(r1 == 0x05)
    {
        //ÉèÖÿ¨ÀàÐÍΪSDV1.0£¬Èç¹ûºóÃæ¼ì²âµ½ÎªMMC¿¨£¬ÔÙÐÞ¸ÄΪMMC
        SD_Type = SD_TYPE_V1;

        //Èç¹ûÊÇV1.0¿¨£¬CMD8Ö¸ÁîºóûÓкóÐøÊý¾Ý
        //ƬѡÖøߣ¬½áÊø±¾´ÎÃüÁî
        SD_CS_DISABLE();
        //¶à·¢8¸öCLK£¬ÈÃSD½áÊøºóÐø²Ù×÷
        SPI_ReadWriteByte(0xFF);

        //-----------------SD¿¨¡¢MMC¿¨³õʼ»¯¿ªÊ¼-----------------

        //·¢¿¨³õʼ»¯Ö¸ÁîCMD55+ACMD41
        // Èç¹ûÓÐÓ¦´ð£¬ËµÃ÷ÊÇSD¿¨£¬ÇÒ³õʼ»¯Íê³É
        // ûÓлØÓ¦£¬ËµÃ÷ÊÇMMC¿¨£¬¶îÍâ½øÐÐÏàÓ¦³õʼ»¯
        retry = 0;
        do
        {
            //ÏÈ·¢CMD55£¬Ó¦·µ»Ø0x01£»·ñÔò³ö´í
            r1 = SD_SendCommand(CMD55, 0, 0);
            if(r1 != 0x01)
            {
                return r1;  
            }
            //µÃµ½ÕýÈ·ÏìÓ¦ºó£¬·¢ACMD41£¬Ó¦µÃµ½·µ»ØÖµ0x00£¬·ñÔòÖØÊÔ200´Î
            r1 = SD_SendCommand(ACMD41, 0, 0);
            retry++;
        }while((r1!=0x00) && (retry<400));

        // ÅжÏÊdz¬Ê±»¹Êǵõ½ÕýÈ·»ØÓ¦
        // ÈôÓлØÓ¦£ºÊÇSD¿¨£»Ã»ÓлØÓ¦£ºÊÇMMC¿¨
        
        //----------MMC¿¨¶îÍâ³õʼ»¯²Ù×÷¿ªÊ¼------------
        if(retry==400)
        {
            retry = 0;
            //·¢ËÍMMC¿¨³õʼ»¯ÃüÁûÓвâÊÔ£©
            do
            {
                r1 = SD_SendCommand(1, 0, 0);
                retry++;
            }while((r1!=0x00)&& (retry<400));
            if(retry==400)
            {
                return 1;   //MMC¿¨³õʼ»¯³¬Ê±
            }
            //дÈ뿨ÀàÐÍ
            SD_Type = SD_TYPE_MMC;
        }
        //----------MMC¿¨¶îÍâ³õʼ»¯²Ù×÷½áÊø------------
        
        //ÉèÖÃSPIΪ¸ßËÙģʽ
        SPI_SetSpeed(1);

                SPI_ReadWriteByte(0xFF);
        
        //½ûÖ¹CRCУÑé
        /*
                r1 = SD_SendCommand(CMD59, 0, 0x01);
        if(r1 != 0x00)
        {
            return r1;  //ÃüÁî´íÎ󣬷µ»Ør1
        }
        */   
        //ÉèÖÃSector Size
        r1 = SD_SendCommand(CMD16, 512, 0xff);
        if(r1 != 0x00)
        {
            return r1;  //ÃüÁî´íÎ󣬷µ»Ør1
        }
        //-----------------SD¿¨¡¢MMC¿¨³õʼ»¯½áÊø-----------------

    }//SD¿¨ÎªV1.0°æ±¾µÄ³õʼ»¯½áÊø
   

    //ÏÂÃæÊÇV2.0¿¨µÄ³õʼ»¯
    //ÆäÖÐÐèÒª¶ÁÈ¡OCRÊý¾Ý£¬ÅжÏÊÇSD2.0»¹ÊÇSD2.0HC¿¨
    else if( r1 == 0x01)
    {
        //V2.0µÄ¿¨£¬CMD8ÃüÁîºó»á´«»Ø4×Ö½ÚµÄÊý¾Ý£¬ÒªÌø¹ýÔÙ½áÊø±¾ÃüÁî
        buff[0] = SPI_ReadWriteByte(0xFF);  //should be 0x00
        buff[1] = SPI_ReadWriteByte(0xFF);  //should be 0x00
        buff[2] = SPI_ReadWriteByte(0xFF);  //should be 0x01
        buff[3] = SPI_ReadWriteByte(0xFF);  //should be 0xAA
     
        SD_CS_DISABLE();
        //the next 8 clocks
        SPI_ReadWriteByte(0xFF);
        
        //Åжϸÿ¨ÊÇ·ñÖ§³Ö2.7V-3.6VµÄµçѹ·¶Î§
        if(buff[2]==0x01 && buff[3]==0xAA)
        {
            //Ö§³Öµçѹ·¶Î§£¬¿ÉÒÔ²Ù×÷
            retry = 0;
            //·¢¿¨³õʼ»¯Ö¸ÁîCMD55+ACMD41
                    do
                    {
                            r1 = SD_SendCommand(CMD55, 0, 0);
                            if(r1!=0x01)
                            {
                                    return r1;
                            }
                            r1 = SD_SendCommand(ACMD41, 0x40000000, 0);
                if(retry>200)   
                {
                    return r1;  //³¬Ê±Ôò·µ»Ør1״̬
                }
            }while(r1!=0);
         
            //³õʼ»¯Ö¸Áî·¢ËÍÍê³É£¬½ÓÏÂÀ´»ñÈ¡OCRÐÅÏ¢

            //-----------¼ø±ðSD2.0¿¨°æ±¾¿ªÊ¼-----------
            r1 = SD_SendCommand_NoDeassert(CMD58, 0, 0);
            if(r1!=0x00)
            {
                return r1;  //Èç¹ûÃüÁîûÓзµ»ØÕýÈ·Ó¦´ð£¬Ö±½ÓÍ˳ö£¬·µ»ØÓ¦´ð
            }
            //¶ÁOCRÖ¸Áî·¢³öºó£¬½ô½Ó×ÅÊÇ4×Ö½ÚµÄOCRÐÅÏ¢
            buff[0] = SPI_ReadWriteByte(0xFF);
            buff[1] = SPI_ReadWriteByte(0xFF);
            buff[2] = SPI_ReadWriteByte(0xFF);
            buff[3] = SPI_ReadWriteByte(0xFF);

            //OCR½ÓÊÕÍê³É£¬Æ¬Ñ¡Öøß
            SD_CS_DISABLE();
            SPI_ReadWriteByte(0xFF);

            //¼ì²é½ÓÊÕµ½µÄOCRÖеÄbit30루CCS£©£¬È·¶¨ÆäΪSD2.0»¹ÊÇSDHC
            //Èç¹ûCCS=1£ºSDHC   CCS=0£ºSD2.0
            if(buff[0]&0x40)    //¼ì²éCCS
            {
                SD_Type = SD_TYPE_V2HC;
            }
            else
            {
                SD_Type = SD_TYPE_V2;
            }
            //-----------¼ø±ðSD2.0¿¨°æ±¾½áÊø-----------           
            //ÉèÖÃSPIΪ¸ßËÙģʽ
            SPI_SetSpeed(1);  
        }

    }
    return r1;
}



/*******************************************************************************
* Function Name  : SD_ReceiveData
* Description    : ´ÓSD¿¨ÖжÁ»ØÖ¸¶¨³¤¶ÈµÄÊý¾Ý£¬·ÅÖÃÔÚ¸ø¶¨Î»ÖÃ
* Input          : u8 *data(´æ·Å¶Á»ØÊý¾ÝµÄÄÚ´æ>len)
*                  u16 len(Êý¾Ý³¤¶È£©
*                  u8 release(´«ÊäÍê³ÉºóÊÇ·ñÊÍ·Å×ÜÏßCSÖÃ¸ß 0£º²»ÊÍ·Å 1£ºÊÍ·Å£©
* Output         : None
* Return         : u8
*                  0£ºNO_ERR
*                  other£º´íÎóÐÅÏ¢
*******************************************************************************/
u8 SD_ReceiveData(u8 *data, u16 len, u8 release)
{
    u16 retry;
    u8 r1;

    // Æô¶¯Ò»´Î´«Êä
    SD_CS_ENABLE();
    //µÈ´ýSD¿¨·¢»ØÊý¾ÝÆðʼÁîÅÆ0xFE
    retry = 0;
    do
    {
        r1 = SPI_ReadWriteByte(0xFF);
        retry++;
        if(retry>2000)  //2000´ÎµÈ´ýºóûÓÐÓ¦´ð£¬Í˳ö±¨´í
        {
            SD_CS_DISABLE();
            return 1;
        }
    }while(r1 != 0xFE);
    //¿ªÊ¼½ÓÊÕÊý¾Ý
    while(len--)
    {
        *data = SPI_ReadWriteByte(0xFF);
        data++;
    }
    //ÏÂÃæÊÇ2¸öαCRC£¨dummy CRC£©
    SPI_ReadWriteByte(0xFF);
    SPI_ReadWriteByte(0xFF);
    //°´ÐèÊÍ·Å×ÜÏߣ¬½«CSÖøß
    if(release == RELEASE)
    {
        //´«Êä½áÊø
        SD_CS_DISABLE();
        SPI_ReadWriteByte(0xFF);
    }

    return 0;
}

一周热门 更多>