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

基于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卡】,跪求指导;
代码见楼下:
收藏 评论11 发布时间:2014-11-4 15:05

举报

11个回答
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
我也遇到了求大神赐教
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版