打印
[应用相关]

SD卡读写速度

[复制链接]
10974|32
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
beety|  楼主 | 2009-9-1 22:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
香主,我跑ST的mass_storage例程,测试了下用TF卡做U盘的速度,才300kB/s左右,太慢了,达不到实际应用,分析了下,好像是sdio操作太慢,有没有方法提高sdio操作速度的方法呢?
沙发
seawwh| | 2009-9-2 10:41 | 只看该作者
我的实验结果是: MicroSD 卡  4bits总线,写入8KBytes 需要 2-4ms 取决于卡的质量。
对应的速度为 4M~2MKBytes/s

使用特权

评论回复
板凳
beety|  楼主 | 2009-9-2 19:13 | 只看该作者
ls能不能传授下绝技?或者给个联系方式,交个朋友啊,我被这个问题困惑了好久了!

使用特权

评论回复
地板
wjc3k| | 2009-9-3 09:06 | 只看该作者
Read TEST ............................................................................

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

Card Detection OK!

Card information OK!
card size=1019215872 Bytes
Card Selection OK!

Set SD Mode OK!

Set DMA Mode OK!

Read File 10672072 bufsize=512
Read bufsize=512  10672072/7577992 =  1.408 MB/S

Read File 10672072 bufsize=1024
Read bufsize=1024  10672072/4273545 =  2.497 MB/S

Read File 10672072 bufsize=2048
Read bufsize=2048  10672072/2604225 =  4.098 MB/S

Read File 10672072 bufsize=4096
Read bufsize=4096  10672072/1801998 =  5.922 MB/S

Read File 10672072 bufsize=8192
Read bufsize=8192  10672072/1796841 =  5.939 MB/S

Read File 10672072 bufsize=16384
Read bufsize=16384  10672072/1794441 =  5.947 MB/S

FatFS Test OK!


Write TEST ............................................................................

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

Card Detection OK!

Card information OK!
card size=1019215872 Bytes
Card Selection OK!

Set SD Mode OK!

Set DMA Mode OK!

Create File OK!
Read/Write bufsize=512  4194304/24955691 =  0.168 MB/S

Create File OK!
Read/Write bufsize=1024  4194304/11469412 =  0.366 MB/S

Create File OK!
Read/Write bufsize=2048  4194304/2887282 =  1.453 MB/S

Create File OK!
Read/Write bufsize=4096  4194304/1712439 =  2.449 MB/S

Create File OK!
Read/Write bufsize=8192  4194304/1717044 =  2.443 MB/S

Create File OK!
Read/Write bufsize=16384  4194304/1720713 =  2.438 MB/S

FatFS Test OK!

使用特权

评论回复
5
beety|  楼主 | 2009-9-3 10:21 | 只看该作者
呵呵,ls的都是一些调试信息,我这些也都是设置成功了的,但是速度还是上不去啊,我用PC读我的1G的TF卡,速度有3~4M/s,说明这张卡可以不是慢卡,但是用ST的例程跑就变得好慢了,我还是用SDIO 4bit DMA模式,倒底时间消耗在哪里一时还找不到方向,希望各位大侠能指点一下方向

使用特权

评论回复
6
beety|  楼主 | 2009-9-3 13:20 | 只看该作者
自己顶一下

使用特权

评论回复
7
fangui| | 2009-9-3 20:29 | 只看该作者
我也想知道答案哦,看来很多人都遇到了这个问题啊,支持lz一下!

使用特权

评论回复
8
mr.king| | 2009-9-3 20:50 | 只看该作者
以前好像实验SPI口,扇区(512字节)读是360us,SCK=36MHz,其中前部分有从15us起到195us一直在反复查询SD卡对块读命令的响应。SDIO没试过

使用特权

评论回复
9
seawwh| | 2009-9-4 09:10 | 只看该作者
ls能不能传授下绝技?或者给个联系方式,交个朋友啊,我被这个问题困惑了好久了!
beety 发表于 2009-9-2 19:13


你每次写入的扇区有多少? 如果太少,开销会大很多

使用特权

评论回复
10
beety|  楼主 | 2009-9-4 16:25 | 只看该作者
没次扇区操作是512,每秒操作是330kB,太慢了吧

使用特权

评论回复
11
wjc3k| | 2009-9-4 16:59 | 只看该作者
fAST?
1.SDIO (4BIT MODE.)
2. DMA.
3. BLOCK MODE(SD_ReadMultiBlocks/SD_WriteMultiBlocks)

Read File 10672072 bufsize=512
Read bufsize=512  10672072/7577992 =  1.408 MB/S

Read File 10672072 bufsize=1024
Read bufsize=1024  10672072/4273545 =  2.497 MB/S

Read File 10672072 bufsize=2048
Read bufsize=2048  10672072/2604225 =  4.098 MB/S

Read File 10672072 bufsize=4096
Read bufsize=4096  10672072/1801998 =  5.922 MB/S

Read File 10672072 bufsize=8192
Read bufsize=8192  10672072/1796841 =  5.939 MB/S

Read File 10672072 bufsize=16384
Read bufsize=16384  10672072/1794441 =  5.947 MB/S

使用特权

评论回复
12
beety|  楼主 | 2009-9-4 19:17 | 只看该作者
我是用USB+TF卡操作FAT32 DMA4bit 速度330k/s,哪一块操作会消耗那么多时间呢?LS能不能贴点SDWriteBlock或者SDReadBlock的源码出来啊,DMA模式的,先谢了,或者加我QQ: 1069871108,我们私聊下也好!

使用特权

评论回复
13
fangui| | 2009-9-5 10:15 | 只看该作者
期待中。。。

使用特权

评论回复
14
seawwh| | 2009-9-5 11:48 | 只看该作者
几点建议:

  1.  每次写入多个扇区,可以大大提高速度, 11楼的例子就说明了这个问题。
  2.  MicroSD卡的质量有些不同, 比如KingStone 的卡,一般写入时间3-4ms (For 8KByte),但是有时会突然需要180ms 的时间, 程序设计需要考虑这个现象。最直接的办法是加大缓冲区, 延长写入间隔。
  3. SanDisk的性能要好一些,中间不会出现某些写入时间过长的现象, Toshiba 和 KingStone 是一样的品牌.

   联系邮箱:  seawwh@sina.com

使用特权

评论回复
15
ch_worm| | 2009-9-5 12:25 | 只看该作者
标志一下 好东西···

使用特权

评论回复
16
beety|  楼主 | 2009-9-5 15:41 | 只看该作者
有两个问题想确认一下,你们是不是都是在用ST公司提供的库函数下测得的,因为我现在不敢肯定是不是ST提供的库没有优化才导致TF卡读写速度慢,还是说我的卡比较慢,按道理说我的卡不会慢的,虽然不是KingStone、Toshiba等品牌的卡,但是在PC上的速度也达到了3~4M/s ,我把我的读写函数贴出来,请高手们看看哪里需要修改的地方:

使用特权

评论回复
17
beety|  楼主 | 2009-9-5 15:43 | 只看该作者
SD_Error SD_WriteBlock(u32 addr, u32 *writebuff, u16 BlockSize)
{
  SD_Error errorstatus = SD_OK;
  u8  power = 0, cardstate = 0;
  u32 timeout = 0, bytestransferred = 0;
  u32 cardstatus = 0, count = 0, restwords = 0;
  u32 *tempbuff = writebuff;

  if (writebuff == NULL)
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }

  TransferError = SD_OK;
  TransferEnd = 0;
  TotalNumberOfBytes = 0;

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = 0;
  SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_512b;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable;
  SDIO_DataConfig(&SDIO_DataInitStructure);
  SDIO_DMACmd(DISABLE);

  if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  {
    errorstatus = SD_LOCK_UNLOCK_FAILED;
    return(errorstatus);
  }

  if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  {
    BlockSize = 512;
    addr /= 512;
  }
  
  /* Set the block size, both on controller and card */
  if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
  {
    power = convert_from_bytes_to_power_of_two(BlockSize);

    SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize;
    SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN);

    if (errorstatus != SD_OK)
    {
      return(errorstatus);
    }
  }
  else
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }

  /* Wait till card is ready for data Added */
  SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16);
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SDIO_SEND_STATUS);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }

  cardstatus = SDIO_GetResponse(SDIO_RESP1);

  timeout = SD_DATATIMEOUT;

  while (((cardstatus & 0x00000100) == 0) && (timeout > 0))
  {
    timeout--;
    SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16);
    SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SDIO_SEND_STATUS);

    if (errorstatus != SD_OK)
    {
      return(errorstatus);
    }
    cardstatus = SDIO_GetResponse(SDIO_RESP1);
  }

  if (timeout == 0)
  {
    return(SD_ERROR);
  }

  /* Send CMD24 WRITE_SINGLE_BLOCK */
  SDIO_CmdInitStructure.SDIO_Argument = addr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_WRITE_SINGLE_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SDIO_WRITE_SINGLE_BLOCK);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }

  TotalNumberOfBytes = BlockSize;
  StopCondition = 0;
  SrcBuffer = writebuff;

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);


  if (DeviceMode == SD_DMA_MODE)
  {
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE);
    DMA_TxConfiguration(writebuff, BlockSize);
    SDIO_DMACmd(ENABLE);
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}

  }

  /* Clear all the static flags */
  SDIO_ClearFlag(SDIO_STATIC_FLAGS);

  /* Wait till the card is in programming state */
  errorstatus = IsCardProgramming(&cardstate);

  while ((errorstatus == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
  {
    errorstatus = IsCardProgramming(&cardstate);
  }

  return(errorstatus);
}

使用特权

评论回复
18
beety|  楼主 | 2009-9-5 15:45 | 只看该作者
SD_Error SD_ReadBlock(u32 addr, u32 *readbuff, u16 BlockSize)
{
  SD_Error errorstatus = SD_OK;
  u32 count = 0, *tempbuff = readbuff;
  u8 power = 0;

  if (NULL == readbuff)
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }

  TransferError = SD_OK;
  TransferEnd = 0;
  TotalNumberOfBytes = 0;

  /* Clear all DPSM configuration */
  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = 0;
  SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable;
  SDIO_DataConfig(&SDIO_DataInitStructure);
  SDIO_DMACmd(DISABLE);

  if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  {
    errorstatus = SD_LOCK_UNLOCK_FAILED;
    return(errorstatus);
  }
  
  if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  {
    BlockSize = 512;
    addr /= 512;
  }
  if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
  {
    power = convert_from_bytes_to_power_of_two(BlockSize);

    /* Set Block Size for Card */
    SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize;
    SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN);

    if (SD_OK != errorstatus)
    {
      return(errorstatus);
    }
  }
  else
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);

  TotalNumberOfBytes = BlockSize;
  StopCondition = 0;
  DestBuffer = readbuff;

  /* Send CMD17 READ_SINGLE_BLOCK */
  SDIO_CmdInitStructure.SDIO_Argument = (u32)addr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_READ_SINGLE_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SDIO_READ_SINGLE_BLOCK);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }
  
  if (DeviceMode == SD_DMA_MODE)
  {
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
    SDIO_DMACmd(ENABLE);
    DMA_RxConfiguration(readbuff, BlockSize);
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}
  }
  return(errorstatus);
}

使用特权

评论回复
19
wjc3k| | 2009-9-6 01:30 | 只看该作者
本帖最后由 wjc3k 于 2009-9-6 01:51 编辑

here is function for FATFS.  ( ST SDCARD.C   ,Sandisk 1GB DMA:24M)

/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
#define MULTI_BLOCK

#define MAX_BLOCK_SIZE 512
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) */
)
{
        u32 *pbuf=(u32 *)(buff);
        SD_Error err;
//        u8 c;

#ifdef MULTI_BLOCK
        if( count == 1 )
                err = SD_ReadBlock(sector*S_MAX_SIZ,(u32 *)pbuf,MAX_BLOCK_SIZE);
        else
        {
                err = SD_ReadMultiBlocks(sector*S_MAX_SIZ, (u32 *)pbuf, MAX_BLOCK_SIZE, count);
        }
        if( err != SD_OK ) return( RES_ERROR);
#else
        while(count--)
        {
                err = SD_ReadBlock(sector*S_MAX_SIZ,(u32 *)pbuf,MAX_BLOCK_SIZE);
                if( err != SD_OK ) return( RES_ERROR);
                pbuf+=(MAX_BLOCK_SIZE>>2);
                sector++;
        }
#endif
        return(RES_OK);
}



/*-----------------------------------------------------------------------*/
/* 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) */
)
{
        u32 *pbuf=(u32 *)(buff);
        SD_Error err;

#ifdef MULTI_BLOCK
        if( count == 1 )
                err = SD_WriteBlock(sector*S_MAX_SIZ,(u32 *)pbuf,MAX_BLOCK_SIZE);
        else
                err = SD_WriteMultiBlocks(sector*S_MAX_SIZ, (u32 *)pbuf, MAX_BLOCK_SIZE, count);
        
        if( err != SD_OK )
        {
                printf("Write Blocks:%d %d Failed!\r\n",sector,count);
                return( RES_ERROR);
        }
        
#else               
        while(count--)
        {
          err = SD_WriteBlock(sector*S_MAX_SIZ, (u32 *)pbuf, MAX_BLOCK_SIZE);
                if( err != SD_OK ) return( RES_ERROR);
                pbuf+=(MAX_BLOCK_SIZE>>2);
                sector++;
        }
#endif
        return(RES_OK);
}
#endif /* _READONLY */

使用特权

评论回复
20
beety|  楼主 | 2009-9-6 17:22 | 只看该作者
LS的代码只是上层的调用,对于提高速度没有帮助,我简化了读写操作,读的操作提高了些,可以达到650k/s,但是写的速度还是上不去,我把代码贴出来,高手们能不能帮我分析下,还可以如何优化代码,提高速度:
SD_Error SD_ReadBlock(u32 addr, u32 *readbuff, u16 BlockSize)
{
  SD_Error errorstatus = SD_OK;
  u8 power = 0;
SDIO_CmdInitTypeDef SDIO_CmdInitStructure;
SDIO_DataInitTypeDef SDIO_DataInitStructure;

  if (NULL == readbuff)
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }
    power = 9;

    SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize;
    SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN);

    if (SD_OK != errorstatus)
    {
      return(errorstatus);
    }
  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);
  /* Send CMD17 READ_SINGLE_BLOCK */
  SDIO_CmdInitStructure.SDIO_Argument = (u32)addr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_READ_SINGLE_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SDIO_READ_SINGLE_BLOCK);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }
    SDIO_DMACmd(ENABLE);
    DMA_RxConfiguration(readbuff, BlockSize);
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}
  return(errorstatus);
  }
SD_Error SD_WriteBlock(u32 addr, u32 *writebuff, u16 BlockSize)
{
  SD_Error errorstatus = SD_OK;
  u8  power = 0, cardstate = 0;
SDIO_CmdInitTypeDef SDIO_CmdInitStructure;
SDIO_DataInitTypeDef SDIO_DataInitStructure;

  if (writebuff == NULL)
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }  
    power = 9;
    SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize;
    SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN);

    if (errorstatus != SD_OK)
    {
      return(errorstatus);
    }

  /* Wait till card is ready for data Added */
  SDIO_CmdInitStructure.SDIO_Argument = (u32) (RCA << 16);
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SDIO_SEND_STATUS);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }

//  cardstatus = SDIO_GetResponse(SDIO_RESP1);

  /* Send CMD24 WRITE_SINGLE_BLOCK */
  SDIO_CmdInitStructure.SDIO_Argument = addr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_WRITE_SINGLE_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SDIO_WRITE_SINGLE_BLOCK);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }


  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);

    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE);
    DMA_TxConfiguration(writebuff, BlockSize);
    SDIO_DMACmd(ENABLE);
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}

  /* Clear all the static flags */
  SDIO_ClearFlag(SDIO_STATIC_FLAGS);

  errorstatus = IsCardProgramming(&cardstate);
  while ((errorstatus == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
  {
    errorstatus = IsCardProgramming(&cardstate);
  }
  return(errorstatus);
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

13

帖子

0

粉丝