利用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
1楼-- · 2019-07-14 23:26
diskio.c
/* Includes ------------------------------------------------------------------*/
#include "diskio.h"
#include "ffconf.h"
#include "Spi_SD_Driver.h"
#include <stdio.h>

/* Private variables ---------------------------------------------------------*/
//extern MSD_CARDINFO SD0_CardInfo;


DSTATUS disk_initialize (
        BYTE drv                                /* Physical drive nmuber (0..) */
)
{
        int Status;
        Status = SD_Init();
        if(Status==0)
           {
                return RES_OK;
            }else{
                return STA_NOINIT;
            }
}




DSTATUS disk_status (
        BYTE drv                /* Physical drive nmuber (0..) */
)
{
       
        return RES_OK;
               
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */

DRESULT disk_read (
        BYTE drv,                /* Physical drive nmuber (0..) */
        BYTE *buff,                /* Data buffer to store read data */
        DWORD sector,        /* Sector address (LBA) */
        BYTE count                /* Number of sectors to read (1..255) */
)
{
        int Status;
        if( !count )
        {   
                return RES_PARERR;  /* count²»ÄܵÈÓÚ0£¬·ñÔò·µ»Ø²ÎÊý´íÎó */
        }
        if(count==1)            /* 1¸ösectorµÄ¶Á²Ù×÷ */      
        {   
                Status = SD_ReadSingleBlock( sector ,buff );
                if(Status == 0){
                        return RES_OK;
                }else{
                        return RES_ERROR;
                }   
        }                                                
        else                    /* ¶à¸ösectorµÄ¶Á²Ù×÷ */     
        {  
                Status = SD_ReadMultiBlock( sector , buff ,count);
                if(Status == 0){
                        return RES_OK;
                }else{
                        return RES_ERROR;
                }
        }                                                
               
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */

#if _READONLY == 0
DRESULT disk_write (
        BYTE drv,                        /* Physical drive nmuber (0..) */
        const BYTE *buff,                /* Data to be written */
        DWORD sector,                /* Sector address (LBA) */
        BYTE count                        /* Number of sectors to write (1..255) */
)
{
        int Status;
        if( !count )
        {   
                return RES_PARERR;  /* count²»ÄܵÈÓÚ0£¬·ñÔò·µ»Ø²ÎÊý´íÎó */
        }
       
        if(count==1)            /* 1¸ösectorµÄд²Ù×÷ */      
        {   
                Status = SD_WriteSingleBlock( sector , (uint8_t *)(&buff[0]) );
                if(Status == 0){
                        return RES_OK;
                }else{
                        return RES_ERROR;
                }
        }                                                
        else                    /* ¶à¸ösectorµÄд²Ù×÷ */   
        {  
        Status = SD_WriteMultiBlock( sector , (uint8_t *)(&buff[0]) , count );
                if(Status == 0){
                        return RES_OK;
                }else{
                        return RES_ERROR;
                }   
        }                                                
               
}
#endif /* _READONLY */



/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */

//DRESULT disk_ioctl (
//        BYTE drv,                /* Physical drive nmuber (0..) */
//        BYTE ctrl,                /* Control code */
//        void *buff                /* Buffer to send/receive control data */
//)
//{
//        //MSD0_GetCardInfo(&SD0_CardInfo);
//        switch (ctrl)
//        {
//                case CTRL_SYNC :
//                        return RES_OK;
//                case GET_SECTOR_COUNT :
//                        //*(DWORD*)buff = SD0_CardInfo.Capacity/SD0_CardInfo.BlockSize;
//                            return RES_OK;
//                case GET_BLOCK_SIZE :
//                        //*(WORD*)buff = SD0_CardInfo.BlockSize;
//                            return RES_OK;       
//                case CTRL_POWER :
//                        break;
//                case CTRL_LOCK :
//                        break;
//                case CTRL_EJECT :
//                        break;
//                      /* MMC/SDC command */
//                case MMC_GET_TYPE :
//                        break;
//                case MMC_GET_CSD :
//                        break;
//                case MMC_GET_CID :
//                        break;
//                case MMC_GET_OCR :
//                        break;
//                case MMC_GET_SDSTAT :
//                        break;       
//        }
//   
//}
DRESULT disk_ioctl(BYTE drv,  /* Physical drive nmuber (0..) */
BYTE ctrl,  /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
    return RES_OK;

}


/* µÃµ½ÎļþCalendar¸ñʽµÄ½¨Á¢ÈÕÆÚ,ÊÇDWORD get_fattime (void) Äæ±ä»» */                                                       
/*-----------------------------------------------------------------------*/
/* User defined function to give a current time to fatfs module          */
/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                          
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                                
DWORD get_fattime (void)
{
   
    return 0;
}
60user125
2楼-- · 2019-07-15 02:57
 精彩回答 2  元偷偷看……
60user125
3楼-- · 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;
}
60user125
4楼-- · 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;
}
60user125
5楼-- · 2019-07-15 15:51
由于字数限制,3部分没传完,只能补一部分啦,Part4:
/*******************************************************************************
* Function Name  : SD_ReadMultiBlock
* Description    : ¶ÁSD¿¨µÄ¶à¸öblock
* Input          : u32 sector È¡µØÖ·£¨sectorÖµ£¬·ÇÎïÀíµØÖ·£©
*                  u8 *buffer Êý¾Ý´æ´¢µØÖ·£¨´óСÖÁÉÙ512byte£©
*                  u8 count Á¬Ðø¶Ácount¸öblock
* Output         : None
* Return         : u8 r1
*                   0£º ³É¹¦
*                   other£ºÊ§°Ü
*******************************************************************************/
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count)
{
    u8 r1;

    //ÉèÖÃΪ¸ßËÙģʽ
    SPI_SetSpeed(SPI_SPEED_LOW);
   
    //Èç¹û²»ÊÇSDHC£¬½«sectorµØַת³ÉbyteµØÖ·
    if(SD_Type!=SD_TYPE_V2HC)
    {
        sector = sector<<9;
    }
    //SD_WaitReady();
    //·¢¶Á¶à¿éÃüÁî
        r1 = SD_SendCommand(CMD18, sector, 0);//¶ÁÃüÁî
        if(r1 != 0x00)
    {
        return r1;
    }
    //¿ªÊ¼½ÓÊÕÊý¾Ý
    do
    {
        if(SD_ReceiveData(buffer, 512, NO_RELEASE) != 0x00)
        {
            break;
        }
        buffer += 512;
    } while(--count);

    //È«²¿´«ÊäÍê±Ï£¬·¢ËÍÍ£Ö¹ÃüÁî
    SD_SendCommand(CMD12, 0, 0);
    //ÊÍ·Å×ÜÏß
    SD_CS_DISABLE();
    SPI_ReadWriteByte(0xFF);
   
    if(count != 0)
    {
        return count;   //Èç¹ûûÓд«Í꣬·µ»ØÊ£Óà¸öÊý
    }
    else
    {
        return 0;
    }
}


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

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

    //Èç¹û²»ÊÇSDHC£¬¸ø¶¨µÄÊÇsectorµØÖ·£¬½«Æäת»»³ÉbyteµØÖ·
    if(SD_Type != SD_TYPE_V2HC)
    {
        sector = sector<<9;
    }
    //Èç¹ûÄ¿±ê¿¨²»ÊÇMMC¿¨£¬ÆôÓÃACMD23Ö¸ÁîʹÄÜÔ¤²Á³ý
    if(SD_Type != SD_TYPE_MMC)
    {
        r1 = SD_SendCommand(ACMD23, count, 0x00);
    }
    //·¢¶à¿éдÈëÖ¸Áî
    r1 = SD_SendCommand(CMD25, sector, 0x00);
    if(r1 != 0x00)
    {
        return r1;  //Ó¦´ð²»ÕýÈ·£¬Ö±½Ó·µ»Ø
    }
   
    //¿ªÊ¼×¼±¸Êý¾Ý´«Êä
    SD_CS_ENABLE();
    //ÏÈ·Å3¸ö¿ÕÊý¾Ý£¬µÈ´ýSD¿¨×¼±¸ºÃ
    SPI_ReadWriteByte(0xff);
    SPI_ReadWriteByte(0xff);

    //--------ÏÂÃæÊÇN¸ösectorдÈëµÄÑ­»·²¿·Ö
    do
    {
        //·ÅÆðʼÁîÅÆ0xFC ±íÃ÷ÊǶà¿éдÈë
        SPI_ReadWriteByte(0xFC);
   
        //·ÅÒ»¸ö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;
        }

        //µÈ´ýSD¿¨Ð´ÈëÍê³É
        if(SD_WaitReady()==1)
        {
            SD_CS_DISABLE();    //µÈ´ýSD¿¨Ð´ÈëÍê³É³¬Ê±£¬Ö±½ÓÍ˳ö±¨´í
            return 1;
        }

        //±¾sectorÊý¾Ý´«ÊäÍê³É
    }while(--count);
   
    //·¢½áÊø´«ÊäÁîÅÆ0xFD
    r1 = SPI_ReadWriteByte(0xFD);
    if(r1==0x00)
    {
        count =  0xfe;
    }

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

    return count;   //·µ»ØcountÖµ£¬Èç¹ûдÍêÔòcount=0£¬·ñÔòcount=1
}
mczxm
6楼-- · 2019-07-15 17:11
LZ您好,我现在也遇到了您同样的问题,请问您解决了吗?

一周热门 更多>