17619|28

67

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

SD卡读写速度 [复制链接]

                                 香主,我跑ST的mass_storage例程,测试了下用TF卡做U盘的速度,才300kB/s左右,太慢了,达不到实际应用,分析了下,好像是sdio操作太慢,有没有方法提高sdio操作速度的方法呢?
此帖出自stm32/stm8论坛

最新回复

                                 我在用STM32的SDIO时 SD_ReadMultiBlocks很正常,测试了N张卡,读取一个20MB的TXT,平均速度10.06MB/S 但是SD_WriteMultiBlocks就不正常了,创建一个文件竟然内容全是0x00,说明根本就没写进去,然后我用SD_WriteBlock来一块一块得写,总算是能正常写入了,但是速度仅有60~150KB/S,慢得没法接受..  详情 回复 发表于 2009-10-5 09:58
点赞 关注
 

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
我的实验结果是: MicroSD 卡  4bits总线,写入8KBytes 需要 2-4ms 取决于卡的质量。
对应的速度为 4M~2MKBytes/s
此帖出自stm32/stm8论坛
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
                                 ls能不能传授下绝技?或者给个联系方式,交个朋友啊,我被这个问题困惑了好久了!
此帖出自stm32/stm8论坛
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

4
 
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!
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

5
 
                                 呵呵,ls的都是一些调试信息,我这些也都是设置成功了的,但是速度还是上不去啊,我用PC读我的1G的TF卡,速度有3~4M/s,说明这张卡可以不是慢卡,但是用ST的例程跑就变得好慢了,我还是用SDIO 4bit DMA模式,倒底时间消耗在哪里一时还找不到方向,希望各位大侠能指点一下方向
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

6
 
                                 自己顶一下
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

7
 
                                 我也想知道答案哦,看来很多人都遇到了这个问题啊,支持lz一下!
此帖出自stm32/stm8论坛
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

8
 
                                 以前好像实验SPI口,扇区(512字节)读是360us,SCK=36MHz,其中前部分有从15us起到195us一直在反复查询SD卡对块读命令的响应。SDIO没试过
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

9
 
ls能不能传授下绝技?或者给个联系方式,交个朋友啊,我被这个问题困惑了好久了!
你每次写入的扇区有多少? 如果太少,开销会大很多
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

10
 
                                 没次扇区操作是512,每秒操作是330kB,太慢了吧
此帖出自stm32/stm8论坛
 
 
 

回复

51

帖子

0

TA的资源

一粒金砂(初级)

11
 
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
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

12
 
                                 我是用USB+TF卡操作FAT32 DMA4bit 速度330k/s,哪一块操作会消耗那么多时间呢?LS能不能贴点SDWriteBlock或者SDReadBlock的源码出来啊,DMA模式的,先谢了,或者加我QQ: 1069871108,我们私聊下也好!
此帖出自stm32/stm8论坛
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(初级)

13
 
                                 期待中。。。
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

14
 
几点建议:

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

   联系邮箱:  seawwh@sina.com
此帖出自stm32/stm8论坛
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(中级)

15
 
                                 标志一下 好东西···
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

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

回复

77

帖子

0

TA的资源

一粒金砂(初级)

17
 
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);
}
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

18
 
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);
}
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

19
 


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 */
此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

20
 
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);
}
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表