利用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 13:07
Part3:
/*******************************************************************************
* Function Name  : SD_GetCID
* Description    : »ñÈ¡SD¿¨µÄCIDÐÅÏ¢£¬°üÀ¨ÖÆÔìÉÌÐÅÏ¢
* Input          : u8 *cid_data(´æ·ÅCIDµÄÄڴ棬ÖÁÉÙ16Byte£©
* Output         : None
* Return         : u8
*                  0£ºNO_ERR
*                  1£ºTIME_OUT
*                  other£º´íÎóÐÅÏ¢
*******************************************************************************/
u8 SD_GetCID(u8 *cid_data)
{
    u8 r1;

    //·¢CMD10ÃüÁ¶ÁCID
    r1 = SD_SendCommand(CMD10, 0, 0xFF);
    if(r1 != 0x00)
    {
        return r1;  //û·µ»ØÕýÈ·Ó¦´ð£¬ÔòÍ˳ö£¬±¨´í
    }
    //½ÓÊÕ16¸ö×Ö½ÚµÄÊý¾Ý
    SD_ReceiveData(cid_data, 16, RELEASE);

    return 0;
}


/*******************************************************************************
* Function Name  : SD_GetCSD
* Description    : »ñÈ¡SD¿¨µÄCSDÐÅÏ¢£¬°üÀ¨ÈÝÁ¿ºÍËÙ¶ÈÐÅÏ¢
* Input          : u8 *cid_data(´æ·ÅCIDµÄÄڴ棬ÖÁÉÙ16Byte£©
* Output         : None
* Return         : u8
*                  0£ºNO_ERR
*                  1£ºTIME_OUT
*                  other£º´íÎóÐÅÏ¢
*******************************************************************************/
u8 SD_GetCSD(u8 *csd_data)
{
    u8 r1;

    //·¢CMD9ÃüÁ¶ÁCSD
    r1 = SD_SendCommand(CMD9, 0, 0xFF);
    if(r1 != 0x00)
    {
        return r1;  //û·µ»ØÕýÈ·Ó¦´ð£¬ÔòÍ˳ö£¬±¨´í
    }
    //½ÓÊÕ16¸ö×Ö½ÚµÄÊý¾Ý
    SD_ReceiveData(csd_data, 16, RELEASE);

    return 0;
}


/*******************************************************************************
* Function Name  : SD_GetCapacity
* Description    : »ñÈ¡SD¿¨µÄÈÝÁ¿
* Input          : None
* Output         : None
* Return         : u32 capacity
*                   0£º È¡ÈÝÁ¿³ö´í
*******************************************************************************/
u32 SD_GetCapacity(void)
{
    u8 csd[16];
    u32 Capacity;
    u8 r1;
    u16 i;
        u16 temp;

    //È¡CSDÐÅÏ¢£¬Èç¹ûÆÚ¼ä³ö´í£¬·µ»Ø0
    if(SD_GetCSD(csd)!=0)
    {
        return 0;
    }
      
    //Èç¹ûΪSDHC¿¨£¬°´ÕÕÏÂÃ淽ʽ¼ÆËã
    if((csd[0]&0xC0)==0x40)
    {
        Capacity =  (((u32)csd[8])<<8 + (u32)csd[9] +1)*(u32)1024;
    }
    else
    {
        //ÏÂÃæ´úÂëΪÍøÉÏ°æ±¾
        ////////////formula of the capacity///////////////
        //
        //  memory capacity = BLOCKNR * BLOCK_LEN
        //       
        //        BLOCKNR = (C_SIZE + 1)* MULT
        //
        //           C_SIZE_MULT+2
        //        MULT = 2
        //
        //               READ_BL_LEN
        //        BLOCK_LEN = 2
        /**********************************************/
        //C_SIZE
            i = csd[6]&0x03;
            i<<=8;
            i += csd[7];
            i<<=2;
            i += ((csd[8]&0xc0)>>6);
   
        //C_SIZE_MULT
            r1 = csd[9]&0x03;
            r1<<=1;
            r1 += ((csd[10]&0x80)>>7);
   
        //BLOCKNR
            r1+=2;
            temp = 1;
            while(r1)
            {
                    temp*=2;
                    r1--;
            }
            Capacity = ((u32)(i+1))*((u32)temp);
   
        // READ_BL_LEN
            i = csd[5]&0x0f;
        //BLOCK_LEN
            temp = 1;
            while(i)
            {
                    temp*=2;
                    i--;
            }
        //The final result
            Capacity *= (u32)temp;
            //Capacity /= 512;
    }
    return (u32)Capacity;
}


/*******************************************************************************
* Function Name  : SD_ReadSingleBlock
* Description    : ¶ÁSD¿¨µÄÒ»¸öblock
* Input          : u32 sector È¡µØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£©
*                  u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£©
* Output         : None
* Return         : u8 r1
*                   0£º ³É¹¦
*                   other£ºÊ§°Ü
*******************************************************************************/
u8 SD_ReadSingleBlock(u32 sector, u8 *buffer)
{
        u8 r1;

    //ÉèÖÃΪ¸ßËÙģʽ
    SPI_SetSpeed(SPI_SPEED_LOW);
   
    //Èç¹û²»ÊÇSDHC£¬½«sectorµØַת³ÉbyteµØÖ·
    if(SD_Type!=SD_TYPE_V2HC)
    {
        sector = sector<<9;
    }

        r1 = SD_SendCommand(CMD17, sector, 0);//¶ÁÃüÁî
       
        if(r1 != 0x00)
    {
        return r1;
    }
   
    r1 = SD_ReceiveData(buffer, 512, RELEASE);
    if(r1 != 0)
    {
        return r1;   //¶ÁÊý¾Ý³ö´í£¡
    }
    else
    {
        return 0;
    }
}

/*******************************************************************************
* Function Name  : SD_WriteSingleBlock
* Description    : дÈëSD¿¨µÄÒ»¸öblock
* Input          : u32 sector ÉÈÇøµØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£©
*                  u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£©
* Output         : None
* Return         : u8 r1
*                   0£º ³É¹¦
*                   other£ºÊ§°Ü
*******************************************************************************/
u8 SD_WriteSingleBlock(u32 sector, const u8 *data)
{
    u8 r1;
    u16 i;
    u16 retry;


    //ÉèÖÃΪ¸ßËÙģʽ
    SPI_SetSpeed(SPI_SPEED_LOW);

    //Èç¹û²»ÊÇSDHC£¬¸ø¶¨µÄÊÇsectorµØÖ·£¬½«Æäת»»³ÉbyteµØÖ·
    if(SD_Type!=SD_TYPE_V2HC)
    {
        sector = sector<<9;
    }

    r1 = SD_SendCommand(CMD24, sector, 0x00);
    if(r1 != 0x00)
    {
        return r1;  //Ó¦´ð²»ÕýÈ·£¬Ö±½Ó·µ»Ø
    }
   
    //¿ªÊ¼×¼±¸Êý¾Ý´«Êä
    SD_CS_ENABLE();
    //ÏÈ·Å3¸ö¿ÕÊý¾Ý£¬µÈ´ýSD¿¨×¼±¸ºÃ
    SPI_ReadWriteByte(0xff);
    SPI_ReadWriteByte(0xff);
    SPI_ReadWriteByte(0xff);
    //·ÅÆðʼÁîÅÆ0xFE
    SPI_ReadWriteByte(0xFE);

    //·ÅÒ»¸ösectorµÄÊý¾Ý
    for(i=0;i<512;i++)
    {
        SPI_ReadWriteByte(*data++);
    }
    //·¢2¸öByteµÄdummy CRC
    SPI_ReadWriteByte(0xff);
    SPI_ReadWriteByte(0xff);
   
    //µÈ´ýSD¿¨Ó¦´ð
    r1 = SPI_ReadWriteByte(0xff);
    if((r1&0x1F)!=0x05)
    {
        SD_CS_DISABLE();
        return r1;
    }
   
    //µÈ´ý²Ù×÷Íê³É
    retry = 0;
    while(!SPI_ReadWriteByte(0xff))
    {
        retry++;
        if(retry>0xfffe)        //Èç¹û³¤Ê±¼äдÈëûÓÐÍê³É£¬±¨´íÍ˳ö
        {
            SD_CS_DISABLE();
            return 1;           //дÈ볬ʱ·µ»Ø1
        }
    }

    //дÈëÍê³É£¬Æ¬Ñ¡ÖÃ1
    SD_CS_DISABLE();
    SPI_ReadWriteByte(0xff);

    return 0;
}

一周热门 更多>