纬图虚拟仪器论坛

 找回密码
 立即注册
搜索
查看: 48203|回复: 51

STM32例程之FATFS移植(SDIO 4-Bit查询模式)(源码下载)

[复制链接]
发表于 2012-8-2 15:46:00 | 显示全部楼层 |阅读模式
本帖最后由 wdluo 于 2012-8-6 15:51 编辑

STM32F103的FATFS文件系统移植,特性:
1、SDIO的4位总线查询操作模式,比SPI模式快很多。
2、支持长文件名。
3、支持中文文件名(包括文件夹)。
主函数功能:
1、创建一个文件,并写入测试数据。
2、打卡刚刚创建的文件,读取文件内容并打印输出。
3、扫描SD卡里面的所有文件(包括文件夹)。
4、统计SD容量空间使用情况。
程序运行结果:
文件读写.jpg
文件读写2.jpg
源码下载:
sdio_fatfs.rar (1.28 MB, 下载次数: 4611)
回复

使用道具 举报

 楼主| 发表于 2012-8-2 16:44:50 | 显示全部楼层
本帖最后由 wdluo 于 2012-8-14 21:50 编辑

再上传一些关于SD的资料:
中文版SD卡操作资料.pdf (517.58 KB, 下载次数: 1353)
回复 支持 1 反对 0

使用道具 举报

发表于 2012-8-2 16:33:34 | 显示全部楼层
???传说中得沙发
回复 支持 反对

使用道具 举报

发表于 2012-8-2 17:20:10 | 显示全部楼层
好资料,谢谢分享!
回复 支持 反对

使用道具 举报

发表于 2012-8-2 18:09:02 | 显示全部楼层
好资料,谢谢分享
回复 支持 反对

使用道具 举报

发表于 2012-8-3 09:45:50 | 显示全部楼层
好全的资料 谢谢分享
回复 支持 反对

使用道具 举报

发表于 2012-8-14 17:03:01 | 显示全部楼层

回帖奖励 +2

谢谢,真的很有用!!!
回复 支持 反对

使用道具 举报

发表于 2012-8-16 10:11:01 | 显示全部楼层
楼主很强大,很好很好,顶!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-16 10:59:03 | 显示全部楼层
Herossx 发表于 2012-8-16 10:11
楼主很强大,很好很好,顶!

回复 支持 反对

使用道具 举报

发表于 2012-8-18 11:50:26 | 显示全部楼层
非常好,谢谢
回复 支持 反对

使用道具 举报

发表于 2012-8-19 08:10:53 | 显示全部楼层
很好的资料! 谢谢楼主分享!
回复 支持 反对

使用道具 举报

发表于 2012-8-19 16:36:15 | 显示全部楼层
开始学习FAT,谢谢楼主分享!
回复 支持 反对

使用道具 举报

发表于 2012-9-19 11:41:33 | 显示全部楼层
非常感谢楼主的分享!下来好好研究
回复 支持 反对

使用道具 举报

发表于 2012-9-26 18:45:44 | 显示全部楼层
非常感谢分享  。。。。  版主强大啊,,,
回复 支持 反对

使用道具 举报

发表于 2012-10-2 18:55:07 | 显示全部楼层
积分不够 发帖子
回复 支持 反对

使用道具 举报

发表于 2012-10-13 20:01:59 | 显示全部楼层
我把程序移植到我的板子上,为什么有的卡可以  有的卡不行呢   4G卡可以   而256M 1G卡就不行了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-13 20:24:09 | 显示全部楼层
csrbzhb 发表于 2012-10-13 20:01
我把程序移植到我的板子上,为什么有的卡可以  有的卡不行呢   4G卡可以   而256M 1G卡就不行了

调试下底层函数接口吧,可能兼容性不是很好,这个程序在2G和4G卡测试OK的,1G的卡驱动方式有点不一样,但是理论上程序是做到兼容的,你找到问题了也可以提出来,然后我再改进改进!
回复 支持 反对

使用道具 举报

发表于 2012-10-18 09:37:06 | 显示全部楼层
我顶你!!!支持!!! 我是边城。顶起来
回复 支持 反对

使用道具 举报

发表于 2012-10-18 20:48:58 | 显示全部楼层
好资料  谢谢分享
回复 支持 反对

使用道具 举报

发表于 2012-11-8 13:58:56 | 显示全部楼层
楼主  为啥加载文件系统ok  但是f_open就不行  返回的是FR_DISK_ERR
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-8 16:15:11 | 显示全部楼层
maduidui 发表于 2012-11-8 13:58
楼主  为啥加载文件系统ok  但是f_open就不行  返回的是FR_DISK_ERR

可能是底层驱动函数的问题,仔细检查下底层读写函数吧
回复 支持 反对

使用道具 举报

发表于 2012-11-19 17:43:12 | 显示全部楼层
好资料!谢谢了!
回复 支持 反对

使用道具 举报

发表于 2012-11-19 17:44:57 | 显示全部楼层
看帖看完了至少要顶一下,还可以加入到淘帖哦!
回复 支持 反对

使用道具 举报

发表于 2012-11-19 17:45:50 | 显示全部楼层
不错,又占了一个沙发!
回复 支持 反对

使用道具 举报

发表于 2012-11-19 17:47:39 | 显示全部楼层
以后会多多学习的!谢谢!
回复 支持 反对

使用道具 举报

发表于 2012-11-21 01:26:04 | 显示全部楼层
不知是否試過STM32F4的SDIO
只能讀的到容量
但是不能讀寫檔案

STM32F1都可以, 不知道是不是庫的問題...
回复 支持 反对

使用道具 举报

发表于 2012-11-21 01:28:44 | 显示全部楼层
不知是否做過STM32F4的SDIO?
目前只讀的到容量, 沒辦法讀寫 ...

不知道是不是庫的問題
STM32F1都可以的說 ...

回复 支持 反对

使用道具 举报

发表于 2012-11-23 11:40:36 | 显示全部楼层
资料真的很全面
回复 支持 反对

使用道具 举报

发表于 2012-11-25 11:47:10 | 显示全部楼层
太好了,顶!
回复 支持 反对

使用道具 举报

发表于 2012-12-1 09:43:01 | 显示全部楼层
再次下载!呵呵!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-12-11 11:37:38 | 显示全部楼层
有人反映用这个程序1G的卡无法正常使用,能初始化成功,但是读文件出错,今天我特意调试了下,发现确实有这个问题,不过解决问题的办法很简单,在SD_ReadBlock()函数里面的发送命令CMD17(READ_SINGLE_BLOCK)的前面发送CMD16就行了,具体代码如下:

  /* Set Block Size for Card */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_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(SD_CMD_SET_BLOCKLEN);

  if (SD_OK != errorstatus)
  {
      return(errorstatus);
  }
这个函数的整个代码如下:

/**
  * @brief  Allows to read one block from a specified address in a card. The Data
  *         transfer can be managed by DMA mode or Polling mode.
  * @note   This operation should be followed by two functions to check if the
  *         DMA Controller and SD Card status.
  *          - SD_ReadWaitOperation(): this function insure that the DMA
  *            controller has finished all data transfer.
  *          - SD_GetStatus(): to check that the SD Card has finished the
  *            data transfer and it is ready for data.            
  * @param  readbuff: pointer to the buffer that will contain the received data
  * @param  ReadAddr: Address from where data are to be read.  
  * @param  BlockSize: the SD card Data block size. The Block size should be 512.
  * @retval SD_Error: SD Card Error code.
  */

SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize)
{
  SD_Error errorstatus = SD_OK;
#if defined (SD_POLLING_MODE)
  uint32_t count = 0, *tempbuff = (uint32_t *)readbuff;
#endif

  TransferError = SD_OK;
  TransferEnd = 0;
  StopCondition = 0;
  
  SDIO->DCTRL = 0x0;
  //SDIO->DLEN = 0;
  
  if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  {
    BlockSize = 512;
    ReadAddr >>= 9;
  }

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) 9 << 4;//SDCardInfo
  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);

  /* Set Block Size for Card */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_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(SD_CMD_SET_BLOCKLEN);

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

  /*!< Send CMD17 READ_SINGLE_BLOCK */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_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(SD_CMD_READ_SINGLE_BLOCK);

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

#if defined (SD_POLLING_MODE)  
  /*!< In case of single block transfer, no need of stop transfer at all.*/
  /*!< Polling mode */
  while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))
  {
    if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)
    {
      for (count = 0; count < 8; count++)
      {
        *(tempbuff + count) = SDIO->FIFO;//SDIO_ReadData();
      }
      tempbuff += 8;
    }
  }

  if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
    errorstatus = SD_DATA_TIMEOUT;
    return(errorstatus);
  }
  else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
    errorstatus = SD_DATA_CRC_FAIL;
    return(errorstatus);
  }
  else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
    errorstatus = SD_RX_OVERRUN;
    return(errorstatus);
  }
  else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_STBITERR);
    errorstatus = SD_START_BIT_ERR;
    return(errorstatus);
  }
  while (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
  {
    *tempbuff = SDIO->FIFO;//SDIO_ReadData();
    tempbuff++;
  }
  
  /*!< Clear all the static flags */
  SDIO_ClearFlag(SDIO_STATIC_FLAGS);

#elif defined (SD_DMA_MODE)
    SDIO_ITConfig(SDIO_IT_RXOVERR|SDIO_IT_DTIMEOUT|SDIO_IT_DCRCFAIL|SDIO_IT_DATAEND, ENABLE);
    SDIO_DMACmd(ENABLE);
    SD_LowLevel_DMA_RxConfig((uint32_t *)readbuff, BlockSize);
#endif

  return(errorstatus);
}
回复 支持 反对

使用道具 举报

发表于 2013-1-26 09:57:51 | 显示全部楼层
顶起先~  高手,有的问题问您下~ 我下载后会卡死截图里面的的那个,disk_read里面的while上。。。。

图
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-26 11:22:22 | 显示全部楼层
flutters 发表于 2013-1-26 09:57
顶起先~  高手,有的问题问您下~ 我下载后会卡死截图里面的的那个,disk_read里面的while上。。。。

首先确定硬件链接正确,其次检查SD卡读写时钟,尽量先降低时钟试试
回复 支持 反对

使用道具 举报

发表于 2013-3-5 19:41:49 | 显示全部楼层
谢谢LZ,正学习
回复 支持 反对

使用道具 举报

发表于 2013-3-5 23:43:56 | 显示全部楼层
楼主辛苦了!
回复 支持 反对

使用道具 举报

发表于 2013-3-6 16:55:43 | 显示全部楼层
楼主啊 ,请教个问题啊 ,里面的printf函数不是库里面的吗?  怎么就能直接用串口打印出来啊 ? 这里面是怎样关联的啊?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-6 18:08:49 | 显示全部楼层
wulong 发表于 2013-3-6 16:55
楼主啊 ,请教个问题啊 ,里面的printf函数不是库里面的吗?  怎么就能直接用串口打印出来啊 ? 这里面是怎 ...

重载printf()底层函数即可
回复 支持 反对

使用道具 举报

发表于 2013-3-10 08:40:40 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

发表于 2013-3-19 21:30:16 | 显示全部楼层
mark                     
回复 支持 反对

使用道具 举报

发表于 2013-3-22 17:53:00 | 显示全部楼层

好资料,谢谢分享!
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|纬图虚拟仪器

GMT+8, 2024-12-22 11:44 , Processed in 0.185914 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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