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

STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码  

[复制链接]
ren0zhe 发布时间:2013-11-20 09:57
第十五节 SD文件系统的学习
详细内容请看附件

本节我们通过科星F107开发板的SPI接口对SD卡进行数据的读写。主要学习的内容就是SPI的配置与文件系统的移植。这里我们用到的文件系统是FatFs, FatFS 是一个通用的文件系统模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 的编写遵循ANSI C,因此不依赖于硬件平台。它可以嵌入到便宜的微控制器中,如 8051, PIC, AVR, SH, Z80, H8, ARM 等等,不需要做任何修改。
         

最顶层是应用层,使用者无需理会FatFs Module 的内部结构和复杂的FAT 协议,只需

要调用FatFs Module 提供给用户的一系列应用接口函数,如f_openf_readf_write f_close

等,就可以像在PC 上读/写文件那样简单。

中间层FatFs Module 实现了FAT 文件读/写协议。FatFs Module 的完全版提供的是ff.c

ff.h,简化版Tiny-FatFs 提供的是tff.ctff.h。除非有必要,使用者一般不用修改,使用时将

需要版本的头文件直接包含进去即可。

需要使用者编写移植代码的是FatFs Module 提供的底层接口,它包括存储媒介读/写

接口Disk I/O 和供给文件创建修改时间的实时时钟。


                        本例程的程序结构图
                  

RTC_time.c

Diskio.c

SD_driver.c

ff.c

fatfs.c


程序的编写

下面我们开始代码的编写:

1、  主函数的编写

int main(void)

{

  RCC_Configuration();

  GPIO_Configuration();

  USART_Configuration();

  SPI_Configuration();

  FATFS_TEST();   //FATFS常用功能测试函数

  while (1)

  {

  }

}

这里新接触的配置函数就是SPI的配置了,也是使用库提供的结构体对SPI进行定义,更多的SPI的介绍,我们这里就不多说了,MCU的芯片手册写的也很清楚了,这里复制过来也没啥意思。下面我们看一下SPI的配置函数,代码如下:

void SPI_Configuration(void)

{

  SPI_InitTypeDef   SPI_InitStructure;

/* SPI3 Config */

    //一开始SD初始化阶段,SPI<i>时钟频率必须<span lang="EN-US" style="color:#4F81BD;mso-themecolor:accent1">SD卡驱动函数的编写

这里使用文件SD_driver.cSD_driver.h来写出SD读写的一些驱动函数。

函数列表如下:

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

/* SD卡类型定义 */

#define SD_TYPE_MMC     0

#define SD_TYPE_V1      1

#define SD_TYPE_V2      2

#define SD_TYPE_V2HC    4


/* SPI总线速度设置*/

#define SPI_SPEED_LOW   0

#define SPI_SPEED_MID   1

#define SPI_SPEED_HIGH  2

/* SD传输数据结束后是否释放总线宏定义 */

#define NO_RELEASE      0

#define RELEASE         1


/* SD卡指令表 */

#define CMD0    0       //卡复位

#define CMD9    9       //命令9 ,读CSD数据

#define CMD10   10      //命令10,读CID数据

#define CMD12   12      //命令12,停止数据传输

#define CMD16   16      //命令16,设置SectorSize 应返回0x00

#define CMD17   17      //命令17,读sector

#define CMD18   18      //命令18,读Multi sector

#define ACMD23  23      //命令23,设置多sector写入前预先擦除Nblock

#define CMD24   24      //命令24,写sector

#define CMD25   25      //命令25,写Multi sector

#define ACMD41  41      //命令41,应返回0x00

#define CMD55   55      //命令55,应返回0x01

#define CMD58   58      //命令58,读OCR信息

#define CMD59   59      //命令59,使能/禁止CRC,应返回0x00


/* Private macro -------------------------------------------------------------*/

//SDCS片选使能端操作:

#define SD_CS_ENABLE()      GPIO_ResetBits(GPIOD,GPIO_Pin_2)   //选中SD

#define SD_CS_DISABLE()     GPIO_SetBits(GPIOD,GPIO_Pin_2)     //不选中SD

#define SD_PWR_ON()         GPIO_ResetBits(GPIOD,GPIO_Pin_10)  //SD卡上电

#define SD_PWR_OFF()        GPIO_SetBits(GPIOD,GPIO_Pin_10)    //SD卡断电

#define SD_DET()             1 // !GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) //检测有卡

                                                                    //1- 0-


/* Private function prototypes -----------------------------------------------*/

//void SPI_Configuration(void);

void SPI_SetSpeed(u8 SpeedSet);


u8 SPI_ReadWriteByte(u8 TxData);                //SPI总线读写一个字节

u8 SD_WaitReady(void);                          //等待SD卡就绪

u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc);     //SD卡发送一个命令

u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc);

u8 SD_Init(void);                               //SD卡初始化

                                                //

u8 SD_ReceiveData(u8 *data, u16 len, u8 release);//SD卡读数据

u8 SD_GetCID(u8 *cid_data);                     //SDCID

u8 SD_GetCSD(u8 *csd_data);                     //SDCSD

u32 SD_GetCapacity(void);                       //SD卡容量


u8 SD_ReadSingleBlock(u32 sector, u8 *buffer);             //读一个sector

u8 SD_WriteSingleBlock(u32 sector,const u8 *buffer);       //写一个sector

u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count);    //读多个sector

u8 SD_WriteMultiBlock(u32 sector,const u8 *data, u8 count);//写多个sector


3、  文件系统的移植

FatFs文件系统主要有以下函数:

/*-函数详细的解释请查阅附录,点击链接也可以到----*/

/* FatFs module application interface                  */


FRESULT f_mount (BYTE, FATFS*);                                  /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const char*, BYTE);                         /* Open or create a file */
FRESULT f_read (FIL*, void*, UINT, UINT*);                        /* Read data from a file */
FRESULT f_write (FIL*, const void*, UINT, UINT*);  /* Write data to a file */
FRESULT f_lseek (FIL*, DWORD);                                           /* Move file pointer of a file object */
FRESULT f_close (FIL*);                                                                      /* Close an open file object */
FRESULT f_opendir (DIR*, const char*);                              /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*);                                             /* Read a directory item */
FRESULT f_stat (const char*, FILINFO*);                             /* Get file status */
FRESULT f_getfree (const char*, DWORD*, FATFS**);     /* Get number of free clusters on the drive */
FRESULT f_truncate (FIL*);                                                                /* Truncate file */
FRESULT f_sync (FIL*);                                                              /* Flush cached data of a writing file */
FRESULT f_unlink (const char*);                                             /* Delete an existing file or directory */
FRESULT    f_mkdir (const char*);                                                    /* Create a new directory */
FRESULT f_chmod (const char*, BYTE, BYTE);                    /* Change file/dir attriburte */
FRESULT f_utime (const char*, const FILINFO*);               /* Change file/dir timestamp */
FRESULT f_rename (const char*, const char*);                 /* Rename/Move a file or directory */
FRESULT f_mkfs (BYTE, BYTE, WORD);                       /* Create a file system on the drive */


4、  底层接口I/O函数的编写

底层驱动是必须由用户自己完成的,函数均放在文件diskio.c中,函数如下:

/* Prototypes for disk control functions */

DSTATUS disk_initialize (BYTE);

DSTATUS disk_status (BYTE);

DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);

DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);

DRESULT disk_ioctl (BYTE, BYTE, void*);

DWORD get_fattime (void);

6 个接口函数的详细信息如下图所示。

Disk I/O 函数结构图

因为FatFs 模块完全与磁盘I/O 层分开,因此需要下面的函数来实现底层物理磁盘的读写与获取当前时间。底层磁盘I/O 模块并不是FatFs 的一部分,并且必须由用户提供。下面的函数位于diskio.c 中。

1)disk_initialize
         2) disk_status
         3) disk_read
         4)disk_write
         5)disk_ioctl
6) get_fattime

5、  应用层函数的编写

我们这个例程要实现的8个功能如下:


每一个功能都对应一个函数,各个函数如下:

// 0  读取磁盘容量 The f_getfree function gets number of the free clusters

void Test_f_getfree(void);

//1   读磁盘目录 The f_readdir function reads directory entries.

void Test_f_readdir(void);

//2    创建目录   The f_mkdir function creates a new directory

void Test_f_mkdir(void);

//3    读取文件   The f_read function reads data from a file.

void Test_f_read(void);

//4    文件拷贝   The f_write writes data to a file.

void Test_f_write(void);

//5    重命名    Rename file or directory

void Test_f_rename(void);

//6    删除文件   The f_unlink removes file or directory

void Test_f_unlink(void);

//7    格式化     The f_mkfs fucntion creates a file system on the drive.

void Test_f_mkfs(void);



8个函数的调用是通过一个二维的函数指针数组完成的,该数组如下:

void *FATFS_Function[][2]=

{

    (void*)Test_f_getfree, "磁盘容量",

    (void*)Test_f_readdir, "读目录  ",

    (void*)Test_f_mkdir,   "创建路径",

    (void*)Test_f_read,    "读文件  ",

    (void*)Test_f_write,   "文件拷贝",

    (void*)Test_f_rename,  "重命名  ",

    (void*)Test_f_unlink,  "删除文件",

    (void*)Test_f_mkfs,    "格式化  ",

    0x00,0x00

};

8个函数完成的功能都是调用FatFs文件系统里的函数,FatFs文件系统的函数前面已经列出了列表,在本节最后面我们也附上了函数的详细定义及用法,请查阅。下面我们着重分析一下这几个应用函数:

0//The f_getfree function gets number of the free clusters

void Test_f_getfree(void)

{

    FATFS fs;

    FATFS *pfs;

    DWORD clust;

    FRESULT res;         // FatFs function common result code


    //检测磁盘是否插好

    if( disk_detect_OK()==FALSE )

      return;


    pfs=&fs;//指向

// Register a work area for logical drive 0

//温馨提示:该函数是文件系统FatFs里的函数,详细说明请查阅本章节最后的附录,可以用Ctrl+F快捷键,弹出搜索框,输入该函数名,找到该函数。以下类似函数均可以这样找到详细说明,不再赘述。该类函数我们会标记红色,并加粗,请留意。比如f_mount, 解释如下:



f_mount(0, &fs);


// 获取空闲簇Get free clusters 空闲簇的值存在clust

    res = f_getfree("/", &clust, &pfs);//必须是根目录,默认磁盘0


    if ( res==FR_OK )

    {

        // Get free space 这里是打印显示出 SD卡总的空间大小以及剩余空间大小

              //计算方法:

//   总空间大小   最大簇数×每簇的扇区数÷2÷1024

//  剩余空间大小  空闲簇数×每簇的扇区数÷2÷1024

        printp("\r\n%d MB total disk space.\r\n%d MB available on the disk.\r\n",

        (DWORD)(pfs->max_clust - 2) * pfs->csize /2/1024,

        clust * pfs->csize /2/1024);

    }

    else

      die(res);//测试函数执行结果分析


    // Unregister a work area before discard it

    f_mount(0, NULL);

}




//1  读取目录 The f_readdir function reads directory entries.

void Test_f_readdir(void)

{

    FATFS fs;        // Work area (file system object) for logical drive

    char path[20];


    //检测磁盘是否插好

    if( disk_detect_OK()==FALSE )

      return;


    f_mount(0, &fs); // Register a work area for logical drive 0


    printp("\r\nread directory:>/");//默认输出主目录下的文件


    USART_Scanf_Name(path);//通过串口输入路径名


    //扫描当前路径下子文件夹,并输出到串口

    scan_current_folder(path);      

    //扫描当前路径下文件,并输出到串口

    scan_current_files(path);


    f_mount(0, NULL);// Unregister a work area before discard it         

}




//2  读取目录  The f_mkdir function creates a new directory

void Test_f_mkdir(void)

{

    FATFS fs;       // Work area (file system object) for logical drive

    FRESULT res;     // FatFs function common result code

    char path[20];

    //检测磁盘是否插好

    if( disk_detect_OK()==FALSE )

      return;

    f_mount(0, &fs); // Register a work area for logical drive 0

    printp("\r\nmake directory:>");

    USART_Scanf_Name(path);//通过串口输入路径名

    res = f_mkdir(path);

    die(res);//测试函数执行结果分析

    f_mount(0, NULL);// Unregister a work area before discard it

}



//3   读文件 The f_read function reads data from a file.

void Test_f_read(void)

{

    //用来记录读文件起始时间、结束时间

    struct tm time_start,time_end ;

    //用来记录读文件起始时间、结束时间 ,unix时间格式,用来记录时间差。

    time_t unix_start,unix_end,interval;

    char path[20];

    //检测磁盘是否插好

    if( disk_detect_OK()==FALSE )

      return;

    //printp("\r\nread filebbbb:>");

    // Register a work area for logical drive 0

    f_mount(0, &fs);


    printp("\r\nread file:>");

    USART_Scanf_Name(path);//通过串口输入文件路径名

    //Open source file

    res = f_open(&fsrc, path, FA_OPEN_EXISTING | FA_READ);

    die(res);

    //buffer空间设大一点,会提高读的速度。

    //如果文件实际大小512byte

    //设为buffer[512]时,只需要循坏一次,如果设为buffer[1],需要循坏512次。

    //下面两行主要是去除1s误差。

    //Read_File_Flag = 0;

    //while( Read_File_Flag==0 );


    //time_start=Time_GetCalendarTime();//记录开始读时间

    //unix_start=Time_ConvCalendarToUnix(time_start);



    //输出提示..

    if( res==FR_OK )

      printp("\r\nread file start time :%02d:%02d:%02d\r\nplease waiting...\r\n", time_start.tm_hour, time_start.tm_min, time_start.tm_sec);

    for (;;)

    {

        //清除缓存

<span lang="EN-US">        for(i=0;iRTC函数的编写

15科星F107开发板学习笔记—SD卡上文件系统FatFs的学习.pdf

下载

2.25 MB, 下载次数: 948

1 收藏 9 评论37 发布时间:2013-11-20 09:57

举报

37个回答
ren0zhe 回答时间:2013-11-20 09:59:14

回复:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

 SD卡读写数据,FatFS文件系统 源码

15科星F107开发板学习笔记源码—SD卡上文件系统FatFs的学习.rar

下载

863.7 KB, 下载次数: 883

沐紫 回答时间:2013-11-20 10:11:23

RE:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

支持支持!
qinkaiabc 回答时间:2013-11-23 15:55:38

RE:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

支持支持!
二月鸟 回答时间:2013-11-27 09:43:25

RE:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

不错,看起来写的很详细。。支持!
boldchild123 回答时间:2013-11-27 17:48:04

RE:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

来学习,取经中,,
少韶 回答时间:2014-3-19 20:49:35

RE:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

,学习学习
1942-406215 回答时间:2014-4-22 10:21:12

回复:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

学习了
xuyp188-265233 回答时间:2014-6-2 13:51:17

回复:STM32 FatFs文件系统 移植,SD读写数据 58页笔记+源码

好东西!
caizhiwei 回答时间:2015-4-10 10:09:00
学习了~~~
1234下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

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