搜索
bottom↓
楼主: jiangjx

FATFS R0.06版本测试程序 已经测试成功,欢迎使用

[复制链接]

出0入0汤圆

发表于 2009-8-14 21:19:04 | 显示全部楼层
移植了一下, 发现了个很奇怪的问题.
我的环境是 RVMDK3.5 , ST的3.0库

移植后, 在列文件的时候, 执行到
BOOL disk_detect_OK(void)

函数的时候进入
void HardFault_Handler(void)


而其他的, 显示磁盘容量等却没有问题,

建目录也是96楼的情形.

而如果直接下载楼主的代码来操作则没有这些问题。

出0入0汤圆

发表于 2009-8-16 21:07:38 | 显示全部楼层
很是感谢

出0入0汤圆

发表于 2009-8-17 10:26:53 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2009-8-19 15:32:12 | 显示全部楼层
好贴顶一下

出0入0汤圆

发表于 2009-8-21 23:35:06 | 显示全部楼层
碰到跟75楼一样的问题,加入降速处理,OK

出0入0汤圆

发表于 2009-8-25 14:00:39 | 显示全部楼层
cool

出0入0汤圆

 楼主| 发表于 2009-9-8 20:34:19 | 显示全部楼层
好久没来了,
关于SD驱动问题,本程序确实存在一些问题,
有些卡存在初始化不成功的现象。
当时手头只有一张SD卡,测试非常稳定,这个问题才一直没有解决,
FATFS功能除了格式化功能没测试过之外,其它功能经过测试都是正常的

出0入0汤圆

发表于 2009-9-8 22:56:57 | 显示全部楼层
记号!!谢谢楼主分享

出0入0汤圆

发表于 2009-9-9 20:05:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-27 17:11:30 | 显示全部楼层
有个小问题?当修改Test_f_write函中中buffer值的时候,每当运行Test_f_write()时,单片机会崩溃,直接进入HardFaultException(),这是怎么回事?原程序是buffer[50],当改成大于256/512/1024或是其它的时候都会出现这种情况,还有为什么是50呢?一个扇区数据的字节都不够,不懂此处的用意.

出0入0汤圆

发表于 2009-10-5 22:02:55 | 显示全部楼层
好东西,酷!

出0入0汤圆

发表于 2009-10-21 15:56:17 | 显示全部楼层
写SD一直没成功,读数据是好用的。搞得我头大。
用楼主的程序复制文件,可以建立空的文件,没有数据。

----------Please select the function to test? >> 4
source file:>/2.txt
target file:>/5.txt
The function succeeded!

----------Please select the function to test? >> 3
read file:>/5.txt
The function succeeded!

read file start time :15:55:40
please waiting...

reading file finished!

<Speed Evaluate>
read file start time:15:55:40
read file ending time:15:55:41
               /5.txt:       0 byte
         reading time:       1 s
        reading speed:       0 byte/s


还请各位大侠指教啊·~~

出0入0汤圆

 楼主| 发表于 2009-10-21 16:37:57 | 显示全部楼层
本测试程序不支持往SD卡写入文件功能

出0入0汤圆

发表于 2009-10-26 10:27:01 | 显示全部楼层
mark!  顶起!

出0入0汤圆

发表于 2009-12-11 15:56:00 | 显示全部楼层
谢谢提供,不过MDK4报了好多警告,个人一个警告都不喜欢。

出0入0汤圆

发表于 2009-12-15 22:19:22 | 显示全部楼层
hao dong xi

出0入0汤圆

发表于 2009-12-16 23:18:28 | 显示全部楼层
jiangjx大虾大好啊,SD卡我一直没搞定,就靠你了

出0入0汤圆

发表于 2009-12-17 00:12:08 | 显示全部楼层
大侠上个原理图,你的SD卡是怎么接的

出0入0汤圆

发表于 2009-12-19 09:22:35 | 显示全部楼层
强贴!mark 了再顶!

出0入0汤圆

发表于 2009-12-19 09:43:13 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2009-12-19 10:46:51 | 显示全部楼层
有个小问题?当修改Test_f_write函中中buffer值的时候,每当运行Test_f_write()时,单片机会崩溃,直接进入HardFaultException(),这是怎么回事?原程序是buffer[50],当改成大于256/512/1024或是其它的时候都会出现这种情况,还有为什么是50呢?一个扇区数据的字节都不够,不懂此处的用意.

答复:
1、这个问题在设计当中我也碰见过,主要问题是局部数组太大了,导致溢出,
2、为什么是50呢?一个扇区数据的字节都不够,不懂此处的用意. 答:设为其它值也可以的

出0入0汤圆

发表于 2009-12-19 11:13:22 | 显示全部楼层
Mark,学习

出0入0汤圆

发表于 2009-12-21 14:39:45 | 显示全部楼层
马一下克

出0入0汤圆

发表于 2009-12-24 14:48:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-2 23:33:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-3 23:27:35 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2010-1-4 08:41:15 | 显示全部楼层
可以读目录,但是在创建路径的时候就出现这样的错误:A file or directory that has same name is already existing!
请问怎样解决呢?谢谢

回复:这是因为A file or directory that has same name is already existing!
也就是说SD卡没有\abc目录,但是你要创建一个\abc\123 目录就会不成功,
必须先创建\abc目录,然后再创建\abc\123 目录

出0入0汤圆

发表于 2010-1-11 10:11:25 | 显示全部楼层
顶。谢谢。

出0入0汤圆

 楼主| 发表于 2010-1-14 15:29:30 | 显示全部楼层
提供官方版的SD驱动,在金士顿1G上测试是可以用的

/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name          : msd.c
* Author             : MCD Application Team
* Version            : V3.1.0
* Date               : 10/30/2009
* Description        : MSD card driver source file.
*                      Pin assignment:
*             ----------------------------------------------
*             |  STM32F10x    |     MSD          Pin        |
*             ----------------------------------------------
*             | CS            |   ChipSelect      1         |
*             | MOSI          |   DataIn          2         |
*             |               |   GND             3 (0 V)   |
*             |               |   VDD             4 (3.3 V) |
*             | SCLK          |   Clock           5         |
*             |               |   GND             6 (0 V)   |
*             | MISO          |   DataOut         7         |
*             -----------------------------------------------
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "msd.h"
#include "delay.h"

/* Private function prototypes -----------------------------------------------*/
static void SPI_Config(void);
static void SPI_SetSpeed(uint8_t SpeedSet);
/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
* Function Name  : MSD_Init
* Description    : Initializes the MSD/SD communication.
* Input          : None
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_Init(void)
{
  uint32_t i = 0;
  uint8_t res;

  /* Initialize MSD_SPI */
  SPI_Config();
  SPI_SetSpeed(SPI_SPEED_LOW);
  MSD_POWER_ON();
  delay_ms(50);//待电压稳定
  
  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte 0xFF, 10 times with CS high*/
  /* rise CS and MOSI for 80 clocks cycles */
  for (i = 0; i <= 9; i++)
  {
    /* Send dummy byte 0xFF */
    MSD_WriteByte(DUMMY);
  }
  /*------------Put MSD in SPI mode--------------*/
  /* MSD initialized and set to SPI mode properly */

  res=MSD_GoIdleState();

  SPI_SetSpeed(SPI_SPEED_HIGH);

  return res;
}

/*******************************************************************************
* Function Name  : MSD_WriteBlock
* Description    : Writes a block on the MSD
* Input          : - pBuffer : pointer to the buffer containing the data to be
*                    written on the MSD.
*                  - WriteAddr : address to write on.
*                  - NumByteToWrite: number of data to write
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_WriteBlock(const uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
  uint32_t i = 0;
  uint8_t rvalue = MSD_RESPONSE_FAILURE;

  /* MSD chip select low */
  MSD_CS_LOW();
  /* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */
  MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF);

  /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
  if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  {
    /* Send a dummy byte */
    MSD_WriteByte(DUMMY);
    /* Send the data token to signify the start of the data */
    MSD_WriteByte(0xFE);
    /* Write the block data to MSD : write count data by block */
    for (i = 0; i < NumByteToWrite; i++)
    {
      /* Send the pointed byte */
      MSD_WriteByte(*pBuffer);
      /* Point to the next location where the byte read will be saved */
      pBuffer++;
    }
    /* Put CRC bytes (not really needed by us, but required by MSD) */
    MSD_ReadByte();
    MSD_ReadByte();
    /* Read data response */
    if (MSD_GetDataResponse() == MSD_DATA_OK)
    {
      rvalue = MSD_RESPONSE_NO_ERROR;
    }
  }

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte: 8 Clock pulses of delay */
  MSD_WriteByte(DUMMY);
  /* Returns the reponse */
  return rvalue;
}

/*******************************************************************************
* Function Name  : MSD_ReadBlock
* Description    : Reads a block of data from the MSD.
* Input          : - pBuffer : pointer to the buffer that receives the data read
*                    from the MSD.
*                  - ReadAddr : MSD's internal address to read from.
*                  - NumByteToRead : number of bytes to read from the MSD.
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
  uint32_t i = 0;
  uint8_t rvalue = MSD_RESPONSE_FAILURE;

  /* MSD chip select low */
  MSD_CS_LOW();
  /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
  MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);

  /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
  if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  {
    /* Now look for the data token to signify the start of the data */
    if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
    {
      /* Read the MSD block data : read NumByteToRead data */
      for (i = 0; i < NumByteToRead; i++)
      {
        /* Save the received data */
        *pBuffer = MSD_ReadByte();
        /* Point to the next location where the byte read will be saved */
        pBuffer++;
      }
      /* Get CRC bytes (not really needed by us, but required by MSD) */
      MSD_ReadByte();
      MSD_ReadByte();
      /* Set response value to success */
      rvalue = MSD_RESPONSE_NO_ERROR;
    }
  }

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte: 8 Clock pulses of delay */
  MSD_WriteByte(DUMMY);
  /* Returns the reponse */
  return rvalue;
}

/*******************************************************************************
* Function Name  : MSD_WriteBuffer
* Description    : Writes many blocks on the MSD
* Input          : - pBuffer : pointer to the buffer containing the data to be
*                    written on the MSD.
*                  - WriteAddr : address to write on.
*                  - NumByteToWrite: number of data to write
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint32_t NumByteToWrite)
{
  uint32_t i = 0, NbrOfBlock = 0, Offset = 0;
  uint8_t rvalue = MSD_RESPONSE_FAILURE;

  /* Calculate number of blocks to write */
  NbrOfBlock = NumByteToWrite / BLOCK_SIZE;
  /* MSD chip select low */
  MSD_CS_LOW();

  /* Data transfer */
  while (NbrOfBlock --)
  {
    /* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */
    MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr + Offset, 0xFF);

    /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
    if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
    {
      return MSD_RESPONSE_FAILURE;
    }
    /* Send dummy byte */
    MSD_WriteByte(DUMMY);
    /* Send the data token to signify the start of the data */
    MSD_WriteByte(MSD_START_DATA_SINGLE_BLOCK_WRITE);
    /* Write the block data to MSD : write count data by block */
    for (i = 0; i < BLOCK_SIZE; i++)
    {
      /* Send the pointed byte */
      MSD_WriteByte(*pBuffer);
      /* Point to the next location where the byte read will be saved */
      pBuffer++;
    }
    /* Set next write address */
    Offset += 512;
    /* Put CRC bytes (not really needed by us, but required by MSD) */
    MSD_ReadByte();
    MSD_ReadByte();
    /* Read data response */
    if (MSD_GetDataResponse() == MSD_DATA_OK)
    {
      /* Set response value to success */
      rvalue = MSD_RESPONSE_NO_ERROR;
    }
    else
    {
      /* Set response value to failure */
      rvalue = MSD_RESPONSE_FAILURE;
    }
  }

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte: 8 Clock pulses of delay */
  MSD_WriteByte(DUMMY);
  /* Returns the reponse */
  return rvalue;
}

/*******************************************************************************
* Function Name  : MSD_ReadBuffer
* Description    : Reads multiple block of data from the MSD.
* Input          : - pBuffer : pointer to the buffer that receives the data read
*                    from the MSD.
*                  - ReadAddr : MSD's internal address to read from.
*                  - NumByteToRead : number of bytes to read from the MSD.
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
  uint32_t i = 0, NbrOfBlock = 0, Offset = 0;
  uint8_t rvalue = MSD_RESPONSE_FAILURE;

  /* Calculate number of blocks to read */
  NbrOfBlock = NumByteToRead / BLOCK_SIZE;
  /* MSD chip select low */
  MSD_CS_LOW();

  /* Data transfer */
  while (NbrOfBlock --)
  {
    /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
    MSD_SendCmd (MSD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF);
    /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
    if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
    {
      return  MSD_RESPONSE_FAILURE;
    }
    /* Now look for the data token to signify the start of the data */
    if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
    {
      /* Read the MSD block data : read NumByteToRead data */
      for (i = 0; i < BLOCK_SIZE; i++)
      {
        /* Read the pointed data */
        *pBuffer = MSD_ReadByte();
        /* Point to the next location where the byte read will be saved */
        pBuffer++;
      }
      /* Set next read address*/
      Offset += 512;
      /* get CRC bytes (not really needed by us, but required by MSD) */
      MSD_ReadByte();
      MSD_ReadByte();
      /* Set response value to success */
      rvalue = MSD_RESPONSE_NO_ERROR;
    }
    else
    {
      /* Set response value to failure */
      rvalue = MSD_RESPONSE_FAILURE;
    }
  }

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte: 8 Clock pulses of delay */
  MSD_WriteByte(DUMMY);
  /* Returns the reponse */
  return rvalue;
}

/*******************************************************************************
* Function Name  : MSD_GetCSDRegister
* Description    : Read the CSD card register.
*                  Reading the contents of the CSD register in SPI mode
*                  is a simple read-block transaction.
* Input          : - MSD_csd: pointer on an SCD register structure
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_GetCSDRegister(sMSD_CSD* MSD_csd)
{
  uint32_t i = 0;
  uint8_t rvalue = MSD_RESPONSE_FAILURE;
  uint8_t CSD_Tab[16];

  /* MSD chip select low */
  MSD_CS_LOW();
  /* Send CMD9 (CSD register) or CMD10(CSD register) */
  MSD_SendCmd(MSD_SEND_CSD, 0, 0xFF);

  /* Wait for response in the R1 format (0x00 is no errors) */
  if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  {
    if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
    {
      for (i = 0; i < 16; i++)
      {
        /* Store CSD register value on CSD_Tab */
        CSD_Tab = MSD_ReadByte();
      }
    }
    /* Get CRC bytes (not really needed by us, but required by MSD) */
    MSD_WriteByte(DUMMY);
    MSD_WriteByte(DUMMY);
    /* Set response value to success */
    rvalue = MSD_RESPONSE_NO_ERROR;
  }

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte: 8 Clock pulses of delay */
  MSD_WriteByte(DUMMY);

  /* Byte 0 */
  MSD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
  MSD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
  MSD_csd->Reserved1 = CSD_Tab[0] & 0x03;
  /* Byte 1 */
  MSD_csd->TAAC = CSD_Tab[1] ;
  /* Byte 2 */
  MSD_csd->NSAC = CSD_Tab[2];
  /* Byte 3 */
  MSD_csd->MaxBusClkFrec = CSD_Tab[3];
  /* Byte 4 */
  MSD_csd->CardComdClasses = CSD_Tab[4] << 4;
  /* Byte 5 */
  MSD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
  MSD_csd->RdBlockLen = CSD_Tab[5] & 0x0F;
  /* Byte 6 */
  MSD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
  MSD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
  MSD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
  MSD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
  MSD_csd->Reserved2 = 0; /* Reserved */
  MSD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10;
  /* Byte 7 */
  MSD_csd->DeviceSize |= (CSD_Tab[7]) << 2;
  /* Byte 8 */
  MSD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;
  MSD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
  MSD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
  /* Byte 9 */
  MSD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
  MSD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
  MSD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
  /* Byte 10 */
  MSD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
  MSD_csd->EraseGrSize = (CSD_Tab[10] & 0x7C) >> 2;
  MSD_csd->EraseGrMul = (CSD_Tab[10] & 0x03) << 3;
  /* Byte 11 */
  MSD_csd->EraseGrMul |= (CSD_Tab[11] & 0xE0) >> 5;
  MSD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x1F);
  /* Byte 12 */
  MSD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
  MSD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
  MSD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
  MSD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;
  /* Byte 13 */
  MSD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xc0) >> 6;
  MSD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
  MSD_csd->Reserved3 = 0;
  MSD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01);
  /* Byte 14 */
  MSD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
  MSD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
  MSD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
  MSD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
  MSD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
  MSD_csd->ECC = (CSD_Tab[14] & 0x03);
  /* Byte 15 */
  MSD_csd->msd_CRC = (CSD_Tab[15] & 0xFE) >> 1;
  MSD_csd->Reserved4 = 1;

  /* Return the reponse */
  return rvalue;
}

/*******************************************************************************
* Function Name  : MSD_GetCIDRegister
* Description    : Read the CID card register.
*                  Reading the contents of the CID register in SPI mode
*                  is a simple read-block transaction.
* Input          : - MSD_cid: pointer on an CID register structure
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_GetCIDRegister(sMSD_CID* MSD_cid)
{
  uint32_t i = 0;
  uint8_t rvalue = MSD_RESPONSE_FAILURE;
  uint8_t CID_Tab[16];

  /* MSD chip select low */
  MSD_CS_LOW();
  /* Send CMD10 (CID register) */
  MSD_SendCmd(MSD_SEND_CID, 0, 0xFF);

  /* Wait for response in the R1 format (0x00 is no errors) */
  if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  {
    if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
    {
      /* Store CID register value on CID_Tab */
      for (i = 0; i < 16; i++)
      {
        CID_Tab = MSD_ReadByte();
      }
    }
    /* Get CRC bytes (not really needed by us, but required by MSD) */
    MSD_WriteByte(DUMMY);
    MSD_WriteByte(DUMMY);
    /* Set response value to success */
    rvalue = MSD_RESPONSE_NO_ERROR;
  }

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte: 8 Clock pulses of delay */
  MSD_WriteByte(DUMMY);

  /* Byte 0 */
  MSD_cid->ManufacturerID = CID_Tab[0];
  /* Byte 1 */
  MSD_cid->OEM_AppliID = CID_Tab[1] << 8;
  /* Byte 2 */
  MSD_cid->OEM_AppliID |= CID_Tab[2];
  /* Byte 3 */
  MSD_cid->ProdName1 = CID_Tab[3] << 24;
  /* Byte 4 */
  MSD_cid->ProdName1 |= CID_Tab[4] << 16;
  /* Byte 5 */
  MSD_cid->ProdName1 |= CID_Tab[5] << 8;
  /* Byte 6 */
  MSD_cid->ProdName1 |= CID_Tab[6];
  /* Byte 7 */
  MSD_cid->ProdName2 = CID_Tab[7];
  /* Byte 8 */
  MSD_cid->ProdRev = CID_Tab[8];
  /* Byte 9 */
  MSD_cid->ProdSN = CID_Tab[9] << 24;
  /* Byte 10 */
  MSD_cid->ProdSN |= CID_Tab[10] << 16;
  /* Byte 11 */
  MSD_cid->ProdSN |= CID_Tab[11] << 8;
  /* Byte 12 */
  MSD_cid->ProdSN |= CID_Tab[12];
  /* Byte 13 */
  MSD_cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
  /* Byte 14 */
  MSD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
  /* Byte 15 */
  MSD_cid->ManufactDate |= CID_Tab[14];
  /* Byte 16 */
  MSD_cid->msd_CRC = (CID_Tab[15] & 0xFE) >> 1;
  MSD_cid->Reserved2 = 1;

  /* Return the reponse */
  return rvalue;
}

/*******************************************************************************
* Function Name  : MSD_SendCmd
* Description    : Send 5 bytes command to the MSD card.
* Input          : - Cmd: the user expected command to send to MSD card
*                  - Arg: the command argument
*                  - Crc: the CRC
* Output         : None
* Return         : None
*******************************************************************************/
void MSD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc)
{
  uint32_t i = 0x00;
  uint8_t Frame[6];

  /* Construct byte1 */
  Frame[0] = (Cmd | 0x40);
  /* Construct byte2 */
  Frame[1] = (uint8_t)(Arg >> 24);
  /* Construct byte3 */
  Frame[2] = (uint8_t)(Arg >> 16);
  /* Construct byte4 */
  Frame[3] = (uint8_t)(Arg >> 8);
  /* Construct byte5 */
  Frame[4] = (uint8_t)(Arg);
  /* Construct CRC: byte6 */
  Frame[5] = (Crc);

  /* Send the Cmd bytes */
  for (i = 0; i < 6; i++)
  {
    MSD_WriteByte(Frame);
  }
}

/*******************************************************************************
* Function Name  : MSD_GetDataResponse
* Description    : Get MSD card data response.
* Input          : None
* Output         : None
* Return         : The MSD status: Read data response xxx0<status>1
*                   - status 010: Data accecpted
*                   - status 101: Data rejected due to a crc error
*                   - status 110: Data rejected due to a Write error.
*                   - status 111: Data rejected due to other error.
*******************************************************************************/
uint8_t MSD_GetDataResponse(void)
{
  uint32_t i = 0;
  uint8_t response, rvalue;

  while (i <= 64)
  {
    /* Read resonse */
    response = MSD_ReadByte();
    /* Mask unused bits */
    response &= 0x1F;

    switch (response)
    {
      case MSD_DATA_OK:
      {
        rvalue = MSD_DATA_OK;
        break;
      }

      case MSD_DATA_CRC_ERROR:
        return MSD_DATA_CRC_ERROR;

      case MSD_DATA_WRITE_ERROR:
        return MSD_DATA_WRITE_ERROR;

      default:
      {
        rvalue = MSD_DATA_OTHER_ERROR;
        break;
      }
    }
    /* Exit loop in case of data ok */
    if (rvalue == MSD_DATA_OK)
      break;
    /* Increment loop counter */
    i++;
  }
  /* Wait null data */
  while (MSD_ReadByte() == 0);
  /* Return response */
  return response;
}

/*******************************************************************************
* Function Name  : MSD_GetResponse
* Description    : Returns the MSD response.
* Input          : None
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_GetResponse(uint8_t Response)
{
  uint32_t Count = 0xFFF;

  /* Check if response is got or a timeout is happen */
  while ((MSD_ReadByte() != Response) && Count)
  {
    Count--;
  }

  if (Count == 0)
  {
    /* After time out */
    return MSD_RESPONSE_FAILURE;
  }
  else
  {
    /* Right response got */
    return MSD_RESPONSE_NO_ERROR;
  }
}

/*******************************************************************************
* Function Name  : MSD_GetStatus
* Description    : Returns the MSD status.
* Input          : None
* Output         : None
* Return         : The MSD status.
*******************************************************************************/
uint16_t MSD_GetStatus(void)
{
  uint16_t Status = 0;

  /* MSD chip select low */
  MSD_CS_LOW();
  /* Send CMD13 (MSD_SEND_STATUS) to get MSD status */
  MSD_SendCmd(MSD_SEND_STATUS, 0, 0xFF);

  Status = MSD_ReadByte();
  Status |= (uint16_t)(MSD_ReadByte() << 8);

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte 0xFF */
  MSD_WriteByte(DUMMY);

  return Status;
}

/*******************************************************************************
* Function Name  : MSD_GoIdleState
* Description    : Put MSD in Idle state.
* Input          : None
* Output         : None
* Return         : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
*                                    - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
uint8_t MSD_GoIdleState(void)
{
  /* MSD chip select low */
  MSD_CS_LOW();
  /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
  MSD_SendCmd(MSD_GO_IDLE_STATE, 0, 0x95);

  /* Wait for In Idle State Response (R1 Format) equal to 0x01 */
  if (MSD_GetResponse(MSD_IN_IDLE_STATE))
  {
    /* No Idle State Response: return response failue */
    return MSD_RESPONSE_FAILURE;
  }
  /*----------Activates the card initialization process-----------*/
  do
  {
    /* MSD chip select high */
    MSD_CS_HIGH();
    /* Send Dummy byte 0xFF */
    MSD_WriteByte(DUMMY);

    /* MSD chip select low */
    MSD_CS_LOW();

    /* Send CMD1 (Activates the card process) until response equal to 0x0 */
    MSD_SendCmd(MSD_SEND_OP_COND, 0, 0xFF);
    /* Wait for no error Response (R1 Format) equal to 0x00 */
  }
  while (MSD_GetResponse(MSD_RESPONSE_NO_ERROR));

  /* MSD chip select high */
  MSD_CS_HIGH();
  /* Send dummy byte 0xFF */
  MSD_WriteByte(DUMMY);

  return MSD_RESPONSE_NO_ERROR;
}

/*******************************************************************************
* Function Name  : MSD_WriteByte
* Description    : Write a byte on the MSD.
* Input          : Data: byte to send.
* Output         : None
* Return         : None.
*******************************************************************************/
void MSD_WriteByte(uint8_t Data)
{
  /* Wait until the transmit buffer is empty */
  while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_TXE) == RESET);
  /* Send the byte */
  SPI_I2S_SendData(MSD_SPI, Data);

  /* Wait until a data is received */
  while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  /* Get the received data */
  SPI_I2S_ReceiveData(MSD_SPI);
  
}

/*******************************************************************************
* Function Name  : MSD_ReadByte
* Description    : Read a byte from the MSD.
* Input          : None.
* Output         : None
* Return         : The received byte.
*******************************************************************************/
uint8_t MSD_ReadByte(void)
{
  uint8_t Data = 0;

  /* Wait until the transmit buffer is empty */
  while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_TXE) == RESET);
  /* Send the byte */
  SPI_I2S_SendData(MSD_SPI, DUMMY);

  /* Wait until a data is received */
  while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  /* Get the received data */
  Data = SPI_I2S_ReceiveData(MSD_SPI);

  /* Return the shifted data */
  return Data;
}

/*******************************************************************************
* Function Name  : SPI_Config
* Description    : Initializes the MSD_SPI and CS pins.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef   SPI_InitStructure;

  /* MSD_SPI_PORT and MSD_CS_PORT Periph clock enable */
  RCC_APB2PeriphClockCmd(MSD_SPI_GPIO_PORT_CLOCK | MSD_CS_GPIO_PORT_CLOCK | \
                         RCC_APB2Periph_AFIO, ENABLE);

  /* MSD_SPI Periph clock enable */
#ifdef USE_STM3210B_EVAL
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
#elif defined (USE_STM3210C_EVAL)
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
#endif /* USE_STM3210B_EVAL */

  /* Remap the SPI pins if needed */
#ifdef SPI_REMAPPED
  //GPIO_PinRemapConfig(MSD_SPI_GPIO_REMAP, ENABLE);
#endif /* SPI_REMAPPED */

  /* Configure MSD_SPI pins: SCK, MISO and MOSI */
  GPIO_InitStructure.GPIO_Pin = MSD_SPI_PIN_SCK | MSD_SPI_PIN_MISO | MSD_SPI_PIN_MOSI;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//SPI模块对应的SCK、MISO、MOSI为AF引脚
  GPIO_Init(MSD_SPI_PORT, &GPIO_InitStructure);

  /* Configure CS pin */
  GPIO_InitStructure.GPIO_Pin = MSD_CS_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(MSD_CS_PORT, &GPIO_InitStructure);

  /* Configure SD POWER pin */
  GPIO_InitStructure.GPIO_Pin = MSD_POWER_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(MSD_POWER_PORT, &GPIO_InitStructure);
  GPIO_SetBits(MSD_POWER_PORT,MSD_POWER_PIN);        //SD卡电源控制,先断开SD卡电源

  /* Configure SD DEC pin */
  GPIO_InitStructure.GPIO_Pin = MSD_DET_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入PA4 pin: SD_DET SD卡检测,短接电路板上JP3
  GPIO_Init(MSD_DET_PORT, &GPIO_InitStructure);

  /* MSD_SPI Config */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(MSD_SPI, &SPI_InitStructure);
  
  SPI_Cmd(MSD_SPI, ENABLE); //MSD_SPI enable
}

void SPI_SetSpeed(uint8_t SpeedSet)
{
    SPI_InitTypeDef SPI_InitStructure ;
   
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;

    //如果速度设置输入0,则低速模式,非0则高速模式
        if(SpeedSet==SPI_SPEED_LOW)
    {
        SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256 ;
    }
    else
    {
        SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
    }

    SPI_Init(MSD_SPI, &SPI_InitStructure);

        SPI_Cmd(MSD_SPI, ENABLE);
}

/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

出0入0汤圆

 楼主| 发表于 2010-1-14 15:29:44 | 显示全部楼层
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name          : msd.h
* Author             : MCD Application Team
* Version            : V3.1.0
* Date               : 10/30/2009
* Description        : Header for msd.c file.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MSD_H
#define __MSD_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Private define ------------------------------------------------------------*/

/* Uncomment the line corresponding to the STMicroelectronics evaluation board
   used to run the example */
#if !defined (USE_STM3210B_EVAL) &&  !defined (USE_STM3210E_EVAL) && !defined (USE_STM3210C_EVAL)
//#define USE_STM3210B_EVAL
#define USE_STM3210E_EVAL
//#define USE_STM3210C_EVAL
#endif

/* Pins related Hardware Configuration defines */
/*
#if defined (USE_STM3210B_EVAL)

#define MSD_SPI                       SPI1
#define MSD_SPI_PORT                  GPIOA
#define MSD_SPI_GPIO_PORT_CLOCK       RCC_APB2Periph_GPIOA
#define MSD_SPI_PIN_SCK               GPIO_Pin_5
#define MSD_SPI_PIN_MISO              GPIO_Pin_6
#define MSD_SPI_PIN_MOSI              GPIO_Pin_7
#define MSD_CS_PORT                   GPIOC
#define MSD_CS_GPIO_PORT_CLOCK        RCC_APB2Periph_GPIOC
#define MSD_CS_PIN                    GPIO_Pin_12
//#define MSD_POWER_PORT                GPIOC
//#define MSD_POWER_GPIO_PORT_CLOCK     RCC_APB2Periph_GPIOC
//#define MSD_POWER_PIN                 GPIO_Pin_8

#elif defined (USE_STM3210E_EVAL)
*/
/* Uncomment this line to enable remapping of SPI pins */
//#define SPI_REMAPPED

#define MSD_SPI                       SPI2
#define MSD_SPI_PORT                  GPIOB
#define MSD_SPI_GPIO_PORT_CLOCK       RCC_APB2Periph_GPIOB
#define MSD_SPI_PIN_SCK               GPIO_Pin_13
#define MSD_SPI_PIN_MISO              GPIO_Pin_14
#define MSD_SPI_PIN_MOSI              GPIO_Pin_15
//#define MSD_SPI_GPIO_REMAP            0
#define MSD_CS_PORT                   GPIOB
#define MSD_CS_GPIO_PORT_CLOCK        RCC_APB2Periph_GPIOB
#define MSD_CS_PIN                    GPIO_Pin_12

//卡电源控制脚
#define MSD_POWER_PORT                GPIOC
#define MSD_POWER_GPIO_PORT_CLOCK     RCC_APB2Periph_GPIOC
#define MSD_POWER_PIN                 GPIO_Pin_8

//卡检测脚
#define MSD_DET_PORT                  GPIOA
#define MSD_DET_GPIO_PORT_CLOCK       RCC_APB2Periph_GPIOA
#define MSD_DET_PIN                   GPIO_Pin_4

//#elif defined (USE_STM3210C_EVAL)

/* Uncomment this line to enable remapping of SPI pins */
/*
#define SPI_REMAPPED

#define MSD_SPI                       SPI3
#define MSD_SPI_PORT                  GPIOC
#define MSD_SPI_GPIO_PORT_CLOCK       RCC_APB2Periph_GPIOC
#define MSD_SPI_PIN_SCK               GPIO_Pin_10
#define MSD_SPI_PIN_MISO              GPIO_Pin_11
#define MSD_SPI_PIN_MOSI              GPIO_Pin_12
#define MSD_SPI_GPIO_REMAP            GPIO_Remap_SPI3
#define MSD_CS_PORT                   GPIOA
#define MSD_CS_GPIO_PORT_CLOCK        RCC_APB2Periph_GPIOA
#define MSD_CS_PIN                    GPIO_Pin_4
//#define MSD_POWER_PORT                GPIOC
//#define MSD_POWER_GPIO_PORT_CLOCK     RCC_APB2Periph_GPIOC
//#define MSD_POWER_PIN                 GPIO_Pin_8

#endif*/
/* USE_STM3210B_EVAL */



/* Block Size */
#define BLOCK_SIZE    512

/* Dummy byte */
#define DUMMY         0xFF

/* Start Data tokens  */
/* Tokens (necessary because at nop/idle (and CS active) only 0xff is on the data/command line) */
#define MSD_START_DATA_SINGLE_BLOCK_READ    0xFE  /* Data token start byte, Start Single Block Read */
#define MSD_START_DATA_MULTIPLE_BLOCK_READ  0xFE  /* Data token start byte, Start Multiple Block Read */
#define MSD_START_DATA_SINGLE_BLOCK_WRITE   0xFE  /* Data token start byte, Start Single Block Write */
#define MSD_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD  /* Data token start byte, Start Multiple Block Write */
#define MSD_STOP_DATA_MULTIPLE_BLOCK_WRITE  0xFD  /* Data toke stop byte, Stop Multiple Block Write */

/* MSD functions return */
#define MSD_SUCCESS                0x00
#define MSD_FAIL                   0xFF

/* MSD reponses and error flags */
#define MSD_RESPONSE_NO_ERROR      0x00
#define MSD_IN_IDLE_STATE          0x01
#define MSD_ERASE_RESET            0x02
#define MSD_ILLEGAL_COMMAND        0x04
#define MSD_COM_CRC_ERROR          0x08
#define MSD_ERASE_SEQUENCE_ERROR   0x10
#define MSD_ADDRESS_ERROR          0x20
#define MSD_PARAMETER_ERROR        0x40
#define MSD_RESPONSE_FAILURE       0xFF

/* Data response error */
#define MSD_DATA_OK                0x05
#define MSD_DATA_CRC_ERROR         0x0B
#define MSD_DATA_WRITE_ERROR       0x0D
#define MSD_DATA_OTHER_ERROR       0xFF

/* Commands: CMDxx = CMD-number | 0x40 */
#define MSD_GO_IDLE_STATE          0   /* CMD0=0x40 */
#define MSD_SEND_OP_COND           1   /* CMD1=0x41 */
#define MSD_SEND_CSD               9   /* CMD9=0x49 */
#define MSD_SEND_CID               10  /* CMD10=0x4A */
#define MSD_STOP_TRANSMISSION      12  /* CMD12=0x4C */
#define MSD_SEND_STATUS            13  /* CMD13=0x4D */
#define MSD_SET_BLOCKLEN           16  /* CMD16=0x50 */
#define MSD_READ_SINGLE_BLOCK      17  /* CMD17=0x51 */
#define MSD_READ_MULTIPLE_BLOCK    18  /* CMD18=0x52 */
#define MSD_SET_BLOCK_COUNT        23  /* CMD23=0x57 */
#define MSD_WRITE_BLOCK            24  /* CMD24=0x58 */
#define MSD_WRITE_MULTIPLE_BLOCK   25  /* CMD25=0x59 */
#define MSD_PROGRAM_CSD            27  /* CMD27=0x5B */
#define MSD_SET_WRITE_PROT         28  /* CMD28=0x5C */
#define MSD_CLR_WRITE_PROT         29  /* CMD29=0x5D */
#define MSD_SEND_WRITE_PROT        30  /* CMD30=0x5E */
#define MSD_TAG_SECTOR_START       32  /* CMD32=0x60 */
#define MSD_TAG_SECTOR_END         33  /* CMD33=0x61 */
#define MSD_UNTAG_SECTOR           34  /* CMD34=0x62 */
#define MSD_TAG_ERASE_GROUP_START  35  /* CMD35=0x63 */
#define MSD_TAG_ERASE_GROUP_END    36  /* CMD36=0x64 */
#define MSD_UNTAG_ERASE_GROUP      37  /* CMD37=0x65 */
#define MSD_ERASE                  38  /* CMD38=0x66 */
#define MSD_READ_OCR               39  /* CMD39=0x67 */
#define MSD_CRC_ON_OFF             40  /* CMD40=0x68 */

/* Exported types ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
typedef struct _MSD_CSD      /*Card Specific Data*/
{
  __IO uint8_t  CSDStruct;            /* CSD structure */
  __IO uint8_t  SysSpecVersion;       /* System specification version */
  __IO uint8_t  Reserved1;            /* Reserved */
  __IO uint8_t  TAAC;                 /* Data read access-time 1 */
  __IO uint8_t  NSAC;                 /* Data read access-time 2 in CLK cycles */
  __IO uint8_t  MaxBusClkFrec;        /* Max. bus clock frequency */
  __IO uint16_t CardComdClasses;      /* Card command classes */
  __IO uint8_t  RdBlockLen;           /* Max. read data block length */
  __IO uint8_t  PartBlockRead;        /* Partial blocks for read allowed */
  __IO uint8_t  WrBlockMisalign;      /* Write block misalignment */
  __IO uint8_t  RdBlockMisalign;      /* Read block misalignment */
  __IO uint8_t  DSRImpl;              /* DSR implemented */
  __IO uint8_t  Reserved2;            /* Reserved */
  __IO uint16_t DeviceSize;           /* Device Size */
  __IO uint8_t  MaxRdCurrentVDDMin;   /* Max. read current @ VDD min */
  __IO uint8_t  MaxRdCurrentVDDMax;   /* Max. read current @ VDD max */
  __IO uint8_t  MaxWrCurrentVDDMin;   /* Max. write current @ VDD min */
  __IO uint8_t  MaxWrCurrentVDDMax;   /* Max. write current @ VDD max */
  __IO uint8_t  DeviceSizeMul;        /* Device size multiplier */
  __IO uint8_t  EraseGrSize;          /* Erase group size */
  __IO uint8_t  EraseGrMul;           /* Erase group size multiplier */
  __IO uint8_t  WrProtectGrSize;      /* Write protect group size */
  __IO uint8_t  WrProtectGrEnable;    /* Write protect group enable */
  __IO uint8_t  ManDeflECC;           /* Manufacturer default ECC */
  __IO uint8_t  WrSpeedFact;          /* Write speed factor */
  __IO uint8_t  MaxWrBlockLen;        /* Max. write data block length */
  __IO uint8_t  WriteBlockPaPartial;  /* Partial blocks for write allowed */
  __IO uint8_t  Reserved3;            /* Reserded */
  __IO uint8_t  ContentProtectAppli;  /* Content protection application */
  __IO uint8_t  FileFormatGrouop;     /* File format group */
  __IO uint8_t  CopyFlag;             /* Copy flag (OTP) */
  __IO uint8_t  PermWrProtect;        /* Permanent write protection */
  __IO uint8_t  TempWrProtect;        /* Temporary write protection */
  __IO uint8_t  FileFormat;           /* File Format */
  __IO uint8_t  ECC;                  /* ECC code */
  __IO uint8_t  msd_CRC;                  /* CRC */
  __IO uint8_t  Reserved4;            /* always 1*/
}
sMSD_CSD;

typedef struct _MSD_CID      /*Card Identification Data*/
{
  __IO uint8_t  ManufacturerID;       /* ManufacturerID */
  __IO uint16_t OEM_AppliID;          /* OEM/Application ID */
  __IO uint32_t ProdName1;            /* Product Name part1 */
  __IO uint8_t  ProdName2;            /* Product Name part2*/
  __IO uint8_t  ProdRev;              /* Product Revision */
  __IO uint32_t ProdSN;               /* Product Serial Number */
  __IO uint8_t  Reserved1;            /* Reserved1 */
  __IO uint16_t ManufactDate;         /* Manufacturing Date */
  __IO uint8_t  msd_CRC;                  /* CRC */
  __IO uint8_t  Reserved2;            /* always 1*/
}
sMSD_CID;


/* SPI总线速度设置*/
#define SPI_SPEED_LOW   0
#define SPI_SPEED_HIGH  1

//卡片选控制
#define MSD_CS_LOW()     GPIO_ResetBits(MSD_CS_PORT, MSD_CS_PIN)
#define MSD_CS_HIGH()    GPIO_SetBits(MSD_CS_PORT, MSD_CS_PIN)
//卡电源开关控制
#define MSD_POWER_ON()   GPIO_ResetBits(MSD_POWER_PORT, MSD_POWER_PIN)
#define MSD_POWER_OFF()  GPIO_SetBits(MSD_POWER_PORT, MSD_POWER_PIN)
//卡插入检测  0有卡
#define MSD_DET()        GPIO_ReadInputDataBit(MSD_DET_PORT, MSD_DET_PIN)

/*----- High layer function -----*/
uint8_t MSD_Init(void);
uint8_t MSD_WriteBlock(const uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);//WriteAddr=扇区地址*512
uint8_t MSD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);                        // ReadAddr=扇区地址*512
uint8_t MSD_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint32_t NumByteToWrite);
uint8_t MSD_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead);
uint8_t MSD_GetCSDRegister(sMSD_CSD* MSD_csd);
uint8_t MSD_GetCIDRegister(sMSD_CID* MSD_cid);

/*----- Medium layer function -----*/
void MSD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc);
uint8_t MSD_GetResponse(uint8_t Response);
uint8_t MSD_GetDataResponse(void);
uint8_t MSD_GoIdleState(void);
uint16_t MSD_GetStatus(void);

/*----- Low layer function -----*/
void MSD_WriteByte(uint8_t byte);
uint8_t MSD_ReadByte(void);

#endif /* __MSD_H */

/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

出0入0汤圆

 楼主| 发表于 2010-1-15 16:27:37 | 显示全部楼层
截止2010.01.15,FatFs最新版本为R0.07e,请参考文档说明
点击此处下载 ourdev_526545.rar(文件大小:181K) (原文件名:FatFs(最新版本为R0.07e)测试程序.rar)

出0入0汤圆

发表于 2010-1-15 16:40:38 | 显示全部楼层
顶下

出0入0汤圆

发表于 2010-1-15 19:59:26 | 显示全部楼层
大虾,偶顶你啊!

出0入0汤圆

发表于 2010-2-3 22:59:01 | 显示全部楼层
回复【楼主位】jiangjx
-----------------------------------------------------------------------

做个标记来学习

出0入0汤圆

发表于 2010-2-4 09:01:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-2 14:39:46 | 显示全部楼层
加你QQ的时候.需要你的大名?

出0入0汤圆

发表于 2010-3-3 22:11:08 | 显示全部楼层
MARK,有时间仔细学习

出0入0汤圆

发表于 2010-3-7 11:04:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-8 12:50:14 | 显示全部楼层
过路

出0入0汤圆

发表于 2010-3-8 16:51:28 | 显示全部楼层
回复【132楼】jiangjx
截止2010.01.15,FatFs最新版本为R0.07e,请参考文档说明
点击此处下载  
-----------------------------------------------------------------------

怎么只有文档,没有程序?!

出0入0汤圆

发表于 2010-3-8 18:12:18 | 显示全部楼层
正需要啊,多谢了,下载后好好研究一下。

出0入0汤圆

发表于 2010-3-8 21:10:12 | 显示全部楼层
MARK,有时间仔细学习

出0入0汤圆

发表于 2010-3-9 16:56:36 | 显示全部楼层
标记 正在测试R0.07e版本

出0入0汤圆

发表于 2010-3-19 23:24:20 | 显示全部楼层
请问jiangjx大虾,您用ST官方的SD卡驱动的FATFS接口函数代码可以发出来参考一下吗?我最近用官方的SD驱动移植到FATFS中的时候,总是返回“没有文件系统”,实在是找不到什么原因!

QQ:543762900

出0入0汤圆

 楼主| 发表于 2010-3-22 10:48:05 | 显示全部楼层
回【145楼】 xld007  对于地址是采用的是字节地址,而不是扇区地址。这个地方很容易出错
附:FATFS接口函数代码


/*-----------------------------------------------------------------------
/  Low level disk interface modlue include file  R0.07   (C)ChaN, 2009
/-----------------------------------------------------------------------*/

#ifndef _DISKIO

#define _READONLY        0        /* 1: Read-only mode */
#define _USE_IOCTL        1

#include "integer.h"
#include ".\SDMMC\msd.h"
#include ".\NAND\nand.h"
#include ".\SPI_FLASH\dataflash.h"
#include ".\RTC\rtc.h"

#define SPI_FLASH            2
#define NAND_FLASH      1
#define MMC_SD                0

#define SPI_FLASH_EN        1
#define NAND_FLASH_EN        1
#define MMC_SD_EN                1

#if MMC_SD_EN==1
  #define MMC_disk_initialize()                 MSD_Init()
  #define MMC_disk_status()                            MSD_DET()
  #define MMC_disk_read(buff, sector, count)    MSD_ReadBlock(buff, sector*512, count*512)
  #define MMC_disk_write(buff, sector, count)   MSD_WriteBlock(buff, sector*512, count*512)
#else
  #define MMC_disk_initialize()                 0x01
  #define MMC_disk_status()                            0x01
  #define MMC_disk_read(buff, sector, count)   
  #define MMC_disk_write(buff, sector, count)   
#endif

//at45db161d flash 2M
#if SPI_FLASH_EN==1
  #define FLASH_disk_initialize()               SPI_FLASH_Init()
  #define FLASH_disk_status()                        0x00
  #define FLASH_disk_read(buff, sector, count)  At45db161d_Read(buff, sector*512, count*512)
  #define FLASH_disk_write(buff, sector, count) At45db161d_Write(buff, sector*512, count*512)
#else
  #define FLASH_disk_initialize()               
  #define FLASH_disk_status()                        0x01
  #define FLASH_disk_read(buff, sector, count)  
  #define FLASH_disk_write(buff, sector, count)
#endif

//NAND flash 128M
#if NAND_FLASH_EN==1
  #define NAND_disk_initialize()                NAND_Init()
  #define NAND_disk_status()                        0x00
  #define NAND_disk_read(buff, sector, count)   FlashReadOneSector(buff, sector*512, 0)
  #define NAND_disk_write(buff, sector, count)  FlashWriteOneSector(buff, sector*512, 0)
#else
  #define NAND_disk_initialize()               
  #define NAND_disk_status()                        0x01
  #define NAND_disk_read(buff, sector, count)   
  #define NAND_disk_write(buff, sector, count)  
#endif

DWORD get_fattime(void);                                               
struct tm get_Calendarfattime(DWORD date,DWORD time);//得到文件Calendar格式的建立文件日期



/* Status of Disk Functions */
typedef BYTE        DSTATUS;

/* Results of Disk Functions */
typedef enum {
        RES_OK = 0,                /* 0: Successful */
        RES_ERROR,                /* 1: R/W Error */
        RES_WRPRT,                /* 2: Write Protected */
        RES_NOTRDY,                /* 3: Not Ready */
        RES_PARERR                /* 4: Invalid Parameter */
} DRESULT;


/*---------------------------------------*/
/* Prototypes for disk control functions */

BOOL assign_drives (int argc, char *argv[]);
DSTATUS disk_initialize (BYTE);
DSTATUS disk_status (BYTE);
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
#if        _READONLY == 0
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
#endif
DRESULT disk_ioctl (BYTE, BYTE, void*);



/* Disk Status Bits (DSTATUS) */

#define STA_NOINIT                0x01        /* Drive not initialized */
#define STA_NODISK                0x02        /* No medium in the drive */
#define STA_PROTECT                0x04        /* Write protected */


/* Command code for disk_ioctrl() */

/* Generic command */
#define CTRL_SYNC                        0        /* Mandatory for write functions */
#define GET_SECTOR_COUNT        1        /* Mandatory for only f_mkfs() */
#define GET_SECTOR_SIZE                2        /* Mandatory for multiple sector size cfg */
#define GET_BLOCK_SIZE                3        /* Mandatory for only f_mkfs() */
#define CTRL_POWER                        4
#define CTRL_LOCK                        5
#define CTRL_EJECT                        6
/* MMC/SDC command */
#define MMC_GET_TYPE                10
#define MMC_GET_CSD                        11
#define MMC_GET_CID                        12
#define MMC_GET_OCR                        13
#define MMC_GET_SDSTAT                14
/* ATA/CF command */
#define ATA_GET_REV                        20
#define ATA_GET_MODEL                21
#define ATA_GET_SN                        22


#define _DISKIO
#endif

出0入0汤圆

发表于 2010-3-22 15:22:20 | 显示全部楼层
好东西,标记下

出0入0汤圆

发表于 2010-3-22 19:34:45 | 显示全部楼层
实在是太感谢了,我这就去试试!

出0入0汤圆

 楼主| 发表于 2010-3-22 20:02:49 | 显示全部楼层
找不到文件系统从以下两点着手:
1、调试好读写扇区函数,至少要保证读扇区正常;
2、在电脑上格式化SD卡;

出0入0汤圆

发表于 2010-3-22 21:47:46 | 显示全部楼层
恩,再次感谢!这两点是没问题滴……
问题出在count偶没有×512

出0入0汤圆

 楼主| 发表于 2010-3-29 09:14:14 | 显示全部楼层
count 指的是要读写的字节数

出0入0汤圆

发表于 2010-4-2 12:46:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-10 21:26:22 | 显示全部楼层
很重要的顶一下。

出0入0汤圆

发表于 2010-4-22 13:09:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-26 20:44:04 | 显示全部楼层
楼主可否发一下你用的开发平台啊?

出0入0汤圆

发表于 2010-4-28 15:31:01 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-4-28 16:27:22 | 显示全部楼层
强烈关注,学习

出0入0汤圆

发表于 2010-4-28 18:59:25 | 显示全部楼层
MARK 文件系统
MARK FS

出0入0汤圆

发表于 2010-4-29 11:30:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-8 23:44:04 | 显示全部楼层
好,谢谢,mark

出0入0汤圆

发表于 2010-6-10 00:12:18 | 显示全部楼层
请为有没有 SDIO 版本?

出0入0汤圆

发表于 2010-6-27 23:07:00 | 显示全部楼层
FATFS_LBflag
标记。

出0入0汤圆

发表于 2010-6-27 23:39:33 | 显示全部楼层
FATFS R0.08 2010 已经出来了
为什么不能 Format??

出0入0汤圆

发表于 2010-6-27 23:49:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-28 15:06:49 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2010-7-13 15:45:02 | 显示全部楼层
太强大了,mark

出0入0汤圆

发表于 2010-7-17 10:44:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-17 11:59:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-10 13:36:54 | 显示全部楼层
移植成功,楼主的程序起了很大作用。特此感谢。

出0入0汤圆

发表于 2010-8-17 03:13:13 | 显示全部楼层
研究非常深入~!

出0入0汤圆

发表于 2010-8-31 15:35:29 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-1 09:36:10 | 显示全部楼层
0.08a出来了 有不有最新的 + 论坛反馈修补bug 版本? 哈哈

出0入0汤圆

发表于 2010-9-16 21:17:33 | 显示全部楼层
顶啊  我用的是SDIO模式,只是不知道如何把一个记事本的内容全部读取,而不是仅仅是开始的512字节,余下的就不会读了,希望高人回答,谢谢!

出0入0汤圆

发表于 2010-9-16 23:34:12 | 显示全部楼层
顶你啊,谢谢!

出0入0汤圆

发表于 2010-9-20 11:04:23 | 显示全部楼层
好贴,绝对好贴,下载看看先

出0入0汤圆

发表于 2010-9-20 15:07:32 | 显示全部楼层
没搞清楚硬件如何连线?

PA5: SPI_CLK
PA6: MISO
PA7: MOSI

PD9: CS
PD10:????????

PA2:SD卡插入检测

-----------------

PD10是作什么的啊?

出0入0汤圆

发表于 2010-9-20 16:31:05 | 显示全部楼层
MARK FATFS

出0入0汤圆

发表于 2010-9-20 16:53:33 | 显示全部楼层
哦, 找到了,PD10是给控制给SD卡加电的。 这是万利板子上的

出0入0汤圆

发表于 2010-9-20 17:46:48 | 显示全部楼层
呵呵,楼主的代码很整齐,用心之作。

出0入0汤圆

发表于 2010-9-24 23:10:08 | 显示全部楼层
截止2010.01.15,FatFs最新版本为R0.07e,请参考文档说明
点击此处下载 ourdev_526545.rar(文件大小:181K) (原文件名:FatFs(最新版本为R0.07e)测试程序.rar)  
————————————————————————————————————————————
这个没有代码呀,楼主

出0入0汤圆

发表于 2010-9-25 11:15:28 | 显示全部楼层
Mark

出0入0汤圆

发表于 2010-9-25 17:47:38 | 显示全部楼层
好贴必mark

出0入0汤圆

发表于 2010-9-27 21:42:17 | 显示全部楼层
这么好的东西,居然没有裤子穿,太不公平了

出0入0汤圆

发表于 2010-9-29 14:14:47 | 显示全部楼层
回复【楼主位】jiangjx  
-----------------------------------------------------------------------

楼主我测试了一下,我的一个128m的fat的文件系统好使,不过fat32的就不行了,不知为什么,上面的一个哥们儿说他测试fat16和32都好用,不知那兄弟怎么测试的

出0入0汤圆

 楼主| 发表于 2010-9-29 15:28:52 | 显示全部楼层
这个SPI接口驱动兼容性不还很好有些卡识别不了 高速SDHC是不行的
ST 官方网站提供有SDIO接口的驱动,那个兼容性很好 支持大容量高速SDHC卡

出0入0汤圆

发表于 2010-9-30 10:14:06 | 显示全部楼层
不错,mark

出0入0汤圆

发表于 2010-10-2 13:12:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-12 23:09:27 | 显示全部楼层
楼主:
  问一个“新奇”的问题,为什么重编你的工程。那么多中文,却没有warning:  #870-D: invalid multibyte character sequence

方便的话透露一下。

出0入0汤圆

发表于 2010-10-13 20:33:21 | 显示全部楼层
加编译选项中加入一句“--diag_remark=870”,就可以解决了哈哈。


(原文件名:关闭汉字警告.GIF)

出0入0汤圆

发表于 2010-10-29 10:29:16 | 显示全部楼层
好帖啊

出0入0汤圆

发表于 2010-10-29 13:11:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-29 13:36:20 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-10-29 21:03:35 | 显示全部楼层
many thanks!!mark

出0入0汤圆

发表于 2010-11-10 10:43:05 | 显示全部楼层
好帖,学习中。

出0入0汤圆

发表于 2010-11-10 17:02:45 | 显示全部楼层
回复【180楼】huasoft
-----------------------------------------------------------------------

请问一下PD10是用什么方式给SD卡加电的,不太明白,谢谢!

出0入0汤圆

发表于 2010-11-13 10:38:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-30 19:30:01 | 显示全部楼层
不错

出0入0汤圆

发表于 2010-11-30 20:57:57 | 显示全部楼层
mark~

出0入0汤圆

发表于 2010-12-1 20:24:18 | 显示全部楼层
mark....

出0入0汤圆

发表于 2010-12-7 17:54:53 | 显示全部楼层
强烈学习

出0入0汤圆

发表于 2011-1-7 09:02:25 | 显示全部楼层
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 06:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表