你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32Cube移植FatFs文件系统,f_Open返回FR_NOT_READY?

[复制链接]
flqcandy 提问时间:2014-11-4 15:05 /
本帖最后由 flqcandy 于 2014-11-4 15:05 编辑

新手移植FatFs文件系统,利用STM32Cube,初始化SPI2,选择PB9作为片选信号,没用使用cube自带的fatfs文件系统;问题如标题所示,f_Open返回FR_NOT_READY,通过断点调试,发现在调用SD_Init()函数中,发送CMD0,让SD进入IDLE状态时,返回值不是0x01;调试了一周,也没找到问题所在。【系统时钟160MHz,SPI2所在的APBH1时钟为40MHz,SD卡为16G的SDHC卡】,跪求指导;
代码见楼下:
收藏 评论12 发布时间:2014-11-4 15:05

举报

12个回答
flqcandy 回答时间:2014-11-4 15:05:29
main.c
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "main.h"
#include "diskio.h"
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;

/* USER CODE BEGIN 0 */
FATFS fs;// Work area (file system object) for logical drive
//        DIR dir;
FIL fsrc, fdst;      // file objects
FRESULT fr;// FatFs function common result code
/* USER CODE END 0 */

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);

int main(void)
{

  /* USER CODE BEGIN 1 */
  char buffer[100]; // file copy buffer
        UINT br, bw;         // File R/W count
//        DSTATUS status;
        unsigned char w_buffer[]="123456789123456789123456789123456789";//??????
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI2_Init();

  /* USER CODE BEGIN 2 */
//        status = disk_initialize(0);
//        if(status==0)
//           {
//                return RES_OK;
//            }
  fr=f_mount(0,&fs);
        //fr=f_opendir(&dir,"");
        fr = f_open(&fsrc,"0:/srcfile.txt",FA_CREATE_ALWAYS|FA_WRITE);
        if(fr==FR_OK)
           fr = f_write(&fsrc,w_buffer,strlen(w_buffer),&bw);
        fr = f_close(&fsrc);
        f_mount(0,NULL);
  /* USER CODE END 2 */

  /* USER CODE BEGIN 3 */
  /* Infinite loop */
  while (1)
  {

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
static void SystemClock_Config(void)
{

  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  __PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 15;
  RCC_OscInitStruct.PLL.PLLN = 192;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

}

/* SPI2 init function */
void MX_SPI2_Init(void)
{

  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
  hspi2.Init.CRCPolynomial = 7;
  HAL_SPI_Init(&hspi2);

}

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __GPIOH_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}
flqcandy 回答时间:2014-11-4 15:05:54
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;
}
flqcandy 回答时间:2014-11-4 15:12:06
SPI_SD_Driver.c分3部分上传,Part1:
/* Includes ------------------------------------------------------------------*/
//#include "config.h"
#include "Spi_SD_Driver.h"
#include "stm32f4xx.h"
#include "main.h"

u8  SD_Type=0;


/* Private functions ---------------------------------------------------------*/

// ÒÔÏÂÊÇSPIÄ£¿éµÄ³õʼ»¯´úÂ룬ÅäÖóÉÖ÷»úģʽ£¬·ÃÎÊSD¿¨




/*******************************************************************************
* Function Name  : SPI_SetSpeed
* Description    : SPIÉèÖÃËÙ¶ÈΪ¸ßËÙ
* Input          : u8 SpeedSet
*                  Èç¹ûËÙ¶ÈÉèÖÃÊäÈë0£¬ÔòµÍËÙģʽ£¬·Ç0Ôò¸ßËÙģʽ
*                  SPI_SPEED_HIGH   1
*                  SPI_SPEED_LOW    0
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_SetSpeed(u8 SpeedSet)
{

  hspi2.Instance=SPI2;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
        hspi2.Init.CRCPolynomial = 7;
  if(SpeedSet==SPI_SPEED_LOW)
    {
        hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
    }
    else
    {
        hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;  
    }
  HAL_SPI_Init(&hspi2);




}
/*******************************************************************************
* Function Name  : SPI_ReadWriteByte
* Description    : SPI¶Áдһ¸ö×Ö½Ú£¨·¢ËÍÍê³Éºó·µ»Ø±¾´ÎͨѶ¶ÁÈ¡µÄÊý¾Ý£©
* Input          : u8 TxData ´ý·¢Ë͵ÄÊý
* Output         : None
* Return         : u8 RxData ÊÕµ½µÄÊý
*******************************************************************************/

u8 SPI_ReadWriteByte(u8 TxData)
{

   u8 RxData;
   HAL_SPI_TransmitReceive(&hspi2,&TxData,&RxData,1,1);
   return RxData;

}

/*******************************************************************************
* Function Name  : SD_WaitReady
* Description    : µÈ´ýSD¿¨Ready
* Input          : None
* Output         : None
* Return         : u8
*                   0£º ³É¹¦
*                   other£ºÊ§°Ü
*******************************************************************************/
u8 SD_WaitReady(void)
{
    u8 r1;
    u16 retry;
    retry = 0;
    do
    {
        r1 = SPI_ReadWriteByte(0xFF);
        if(retry==0xfffe)
        {
            return 1;
        }
    }while(r1!=0xFF);

    return 0;
}



/*******************************************************************************
* Function Name  : SD_SendCommand
* Description    : ÏòSD¿¨·¢ËÍÒ»¸öÃüÁî
* Input          : u8 cmd   ÃüÁî
*                  u32 arg  ÃüÁî²ÎÊý
*                  u8 crc   crcУÑéÖµ
* Output         : None
* Return         : u8 r1 SD¿¨·µ»ØµÄÏìÓ¦
*******************************************************************************/
u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc)
{
    unsigned char r1;
    unsigned char Retry = 0;

    //????????
    SPI_ReadWriteByte(0xff);
    //Ƭѡ¶ËÖõͣ¬Ñ¡ÖÐSD¿¨
    SD_CS_ENABLE();

    //·¢ËÍ
    SPI_ReadWriteByte(cmd | 0x40);                         //·Ö±ðдÈëÃüÁî
    SPI_ReadWriteByte(arg >> 24);
    SPI_ReadWriteByte(arg >> 16);
    SPI_ReadWriteByte(arg >> 8);
    SPI_ReadWriteByte(arg);
    SPI_ReadWriteByte(crc);
   
    //µÈ´ýÏìÓ¦£¬»ò³¬Ê±Í˳ö
    while((r1 = SPI_ReadWriteByte(0xFF))==0xFF)
    {
        Retry++;
        if(Retry > 200)
        {
            break;
        }
    }
   

    //¹Ø±ÕƬѡ
    SD_CS_DISABLE();
    //ÔÚ×ÜÏßÉ϶îÍâÔö¼Ó8¸öʱÖÓ£¬ÈÃSD¿¨Íê³ÉÊ£ÏµĹ¤×÷
    SPI_ReadWriteByte(0xFF);

    //·µ»Ø״ֵ̬
    return r1;
}


/*******************************************************************************
* Function Name  : SD_SendCommand_NoDeassert
* Description    : ÏòSD¿¨·¢ËÍÒ»¸öÃüÁî(½áÊøÊDz»Ê§ÄÜƬѡ£¬»¹ÓкóÐøÊý¾Ý´«À´£©
* Input          : u8 cmd   ÃüÁî
*                  u32 arg  ÃüÁî²ÎÊý
*                  u8 crc   crcУÑéÖµ
* Output         : None
* Return         : u8 r1 SD¿¨·µ»ØµÄÏìÓ¦
*******************************************************************************/
u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc)
{
    unsigned char r1;
    unsigned char Retry = 0;

    //????????
    SPI_ReadWriteByte(0xff);
    //Ƭѡ¶ËÖõͣ¬Ñ¡ÖÐSD¿¨
    SD_CS_ENABLE();

    //·¢ËÍ
    SPI_ReadWriteByte(cmd | 0x40);                         //·Ö±ðдÈëÃüÁî
    SPI_ReadWriteByte(arg >> 24);
    SPI_ReadWriteByte(arg >> 16);
    SPI_ReadWriteByte(arg >> 8);
    SPI_ReadWriteByte(arg);
    SPI_ReadWriteByte(crc);

    //µÈ´ýÏìÓ¦£¬»ò³¬Ê±Í˳ö
    while((r1 = SPI_ReadWriteByte(0xFF))==0xFF)
    {
        Retry++;
        if(Retry > 200)
        {
            break;
        }
    }
    //·µ»ØÏìÓ¦Öµ
    return r1;
}



flqcandy 回答时间:2014-11-4 15:14:35
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;
}


flqcandy 回答时间:2014-11-4 15:15:47
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;
}


flqcandy 回答时间:2014-11-4 15:16:45
由于字数限制,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
}
zqyycl 回答时间:2015-10-28 16:52:14
LZ您好,我现在也遇到了您同样的问题,请问您解决了吗?
zqyycl 回答时间:2015-10-28 16:52:30
在线等您的答案
不良苏 回答时间:2018-12-15 14:17:33
我也遇到了求大神赐教
★↣Rese♧rve 回答时间:2018-12-15 23:41:17
解决了吗?
kepma 回答时间:2020-2-13 21:26:30
请问解决了嘛?
freefishmj 回答时间:2021-3-1 13:29:20

请问解决了嘛?

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版