立即注册 找回密码

微雪课堂

搜索
微雪课堂 首页 STM32 STM32CubeMX系列教程 查看内容

STM32CubeMX系列教程18:文件系统FATFS

2016-5-3 18:20| 发布者: MyMX1213| 查看: 34618| 评论: 11|原作者: MyMX1213

摘要: 上一章我们介绍了SD卡读写操作,本章讲过如何通过FATFS文件系统读写SD卡内部的文件
FATFS简介

    FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。它可以被嵌入到低成本的微控制器中,如AVR, 8051, PIC, ARM等等。兼容Windows文件系统。
关于FATFS文件系统的API函数介绍,底层移植接口和例程等可以查到FATFS官网。


        结合STM32cubeMX软件移植FATFS文件系统非常简单。本章程序在上一章SDMMC工程的基础上修改,复制串口SDMMC的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。在中间件中选择SD卡,在SD上建立文件系统。


在FATFS配置中选择简体中文字GBK编码支持中文,使能长文件名,缓存存储在堆(STACK)中。


        点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。


        生成报告以及代码,编译程序。在fatfs.c文件中可以看到FATFS初始化函数。在bsp_drver_sd.c文件中可以看到SD卡的板级操作函数,包括SD初始化,读写擦除块操作函数。在sd_diskio.c文件中可以看到FATFS文件系统移植的底层操作函数。


删除上一章SDMMC的应用程序。在main.c文件前添加变量。fs为文件系统工作区,fil为文件对象结构的指针。rtext/wtext分别为读写缓存,bytesread/byteswritten分别存储读写的字节数。filename存储文件名(FATFS文件系统配置时使能了长文件名,最长255字节,若不支持长文件名,则文件名最多8个字节)。

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
FATFS fs;                 // Work area (file system object) for logical drive
FIL fil;                  // file objects
 
uint32_t byteswritten;                /* File write counts */
uint32_t bytesread;                   /* File read counts */
uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
uint8_t rtext[100];                     /* File read buffers */
char filename[] = "STM32cube.txt";
/* USER CODE END PV */

在main函数中添加应用程序。程序中首先注册一个文件系统对象,然后新建STM32cube.txt文件,将数据写文件中再读出来,判断文件系统是否工作正常。

/* USER CODE BEGIN 2 */
    printf("\r\n ****** FatFs Example ******\r\n\r\n");
 
    /*##-1- Register the file system object to the FatFs module ##############*/
    retSD = f_mount(&fs, "", 0);
    if(retSD)
    {
        printf(" mount error : %d \r\n",retSD);
        Error_Handler();
    }
    else
        printf(" mount sucess!!! \r\n");
     
    /*##-2- Create and Open new text file objects with write access ######*/
    retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE);
    if(retSD)
        printf(" open file error : %d\r\n",retSD);
    else
        printf(" open file sucess!!! \r\n");
     
    /*##-3- Write data to the text files ###############################*/
    retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten);
    if(retSD)
        printf(" write file error : %d\r\n",retSD);
    else
    {
        printf(" write file sucess!!! \r\n");
        printf(" write Data : %s\r\n",wtext);
    }
     
    /*##-4- Close the open text files ################################*/
    retSD = f_close(&fil);
    if(retSD)
        printf(" close error : %d\r\n",retSD);
    else
        printf(" close sucess!!! \r\n");
     
    /*##-5- Open the text files object with read access ##############*/
    retSD = f_open(&fil, filename, FA_READ);
    if(retSD)
        printf(" open file error : %d\r\n",retSD);
    else
        printf(" open file sucess!!! \r\n");
     
    /*##-6- Read data from the text files ##########################*/
    retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread);
    if(retSD)
        printf(" read error!!! %d\r\n",retSD);
    else
    {
        printf(" read sucess!!! \r\n");
        printf(" read Data : %s\r\n",rtext);
    }
     
    /*##-7- Close the open text files ############################*/
    retSD = f_close(&fil);
    if(retSD)  
        printf(" close error!!! %d\r\n",retSD);
    else
        printf(" close sucess!!! \r\n");
     
    /*##-8- Compare read data with the expected data ############*/
    if(bytesread == byteswritten)
    { 
        printf(" FatFs is working well!!!\r\n");
    }
  /* USER CODE END 2 */

在main.c文件后面添加错误处理函数。

/* USER CODE BEGIN 4 */
static void Error_Handler(void)
{
  printf("something wrong ....\r\n");
    /* User may add here some code to deal with this error */
  while(1)
  {
  }
}
/* USER CODE END 4 */


在main.c文件前面添加错误处理函数声明。

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
static void Error_Handler(void);
/* USER CODE END PFP */


编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。




下载简介一下FATFS的几个操作函数。
1.f_mount
在FatFs模块上注册、注销一个工作区(文件系统对象)。
FRESULT f_mount (
    FATFS* fs,         /* Pointer to the file system object (NULL:unmount)*/
    const TCHAR* path,    /* Logical drive number to be mounted/unmounted */
    BYTE opt           /* 0:Do not mount (delayed mount), 1:Mount immediately */
)

参数
fs 工作区(文件系统对象)指针
path  注册/注销工作区的逻辑驱动器号
opt      注册或注销选项


2.f_open
创建/打开一个文件对象
FRESULT f_open (
    FIL* fp,           /* Pointer to the blank file object */
    const TCHAR* path,    /* Pointer to the file name */
    BYTE mode          /* Access mode and file open mode flags */
)
fp   将被创建的文件对象结构的指针
path  文件名指针,指定将创建或打开的文件名
mode 访问类型和打开方法,由一下标准的一个组合指定的。

模式                      描述  
FA_READ   指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问。   
FA_WRITE   指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问。   
FA_OPEN_EXISTING  打开文件。如果文件不存在,则打开失败。(默认)  
FA_OPEN_ALWAYS   如果文件存在,则打开;否则,创建一个新文件。  
FA_CREATE_NEW   创建一个新文件。如果文件已存在,则创建失败。   
FA_CREATE_ALWAYS  创建一个新文件。如果文件已存在,则它将被截断并覆盖。

3.f_close
关闭一个打开的文件
FRESULT f_close (
    FIL *fp        /* Pointer to the file object to be closed */
)

fp 指向将被关闭的已打开的文件对象结构的指针。

4.f_read
从一个打开的文件中读取数据
FRESULT f_read (
    FIL* fp,      /* Pointer to the file object */
    void* buff,        /* Pointer to data buffer */
    UINT btr,      /* Number of bytes to read */
    UINT* br       /* Pointer to number of bytes read */
)

fp   指向将被读取的已打开的文件对象结构的指针
buff  指向存储读取数据的缓冲区的指针
btr  要读取的字节数
br 指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数。

5.f_write
写入数据到一个已打开的文件
FRESULT f_write (
    FIL* fp,           /* Pointer to the file object */
    const void *buff, /* Pointer to the data to be written */
    UINT btw,          /* Number of bytes to write */
    UINT* bw           /* Pointer to number of bytes written */
)

fp   指向将被写入的已打开的文件对象结构的指针
buff  指向存储写入数据的缓冲区的指针
btr  要写入的字节数
br 指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数。

另外FatFs还有很多API操作函数,在这里不再作详细的介绍,详细信息请查看FatFs文件系统官网。




410

顶一下

刚表态过的朋友 (410 人)

相关阅读

发表评论

最新评论

引用 游客 2019-7-26 23:21
: 请问FATFS内的第四个选项Platform Settings是什么?我更新了最新版本的CubeMX,改变了好多东西。Platform Settings无法设置,不知道是为什么。 ...
平台设置:这个选项Detect SDIO目的 SD卡插进去的时候硬件有一个接口会起作用,以此来判断有没有SD卡插进来。这个选项就是要选择这个脚的。这个脚必须是输入类型!
引用 游客 2019-2-2 11:28
请问FATFS内的第四个选项Platform Settings是什么?我更新了最新版本的CubeMX,改变了好多东西。Platform Settings无法设置,不知道是为什么。
引用 游客 2018-12-22 22:54
大家注意一个问题。查一下读取和写入的时候,会调用DMA的相关函数。那个BSP_DMA_READBLOCKS这附近没有对于通道的初始化设置。
引用 游客 2018-8-27 18:59
无法运行。
mount sucess!!!
open file error : 13
write file error : 9
close error : 9
引用 游客 2018-6-15 11:09
能不能同时写两个文件,比如一个文件写运行记录,另一个写接收到的数据
引用 游客 2018-5-24 16:19
mount sucess!!!
open file error : 13
write file error : 9
close error : 9
我照例子也是出现了上述错误,请求援助
引用 MyMX1213 2016-9-28 18:28
另外SDMMC中断优先级要比DMA中断的优先级高。
引用 MyMX1213 2016-9-28 18:26
你检查一下工程里面DMA和SDMMC中断有没有开启,另外堆栈一定要设置大一点,另外是如果允许过SDMMC示例程序,里面是没有文件系统的,要格式化过才可以。
如果还不行可以加我QQ:2853908288
引用 yycqz 2016-9-27 17:39
retSD = f_mount(&fs, "", 0); 看ff.c中的函数,最后参数是0表示不立即mount,fatfs官方文件是说下次用到时mount,意思就是下面调用f_open时进行对吧。试过,此处改成1与0都可以,改成1时未断电复位重新调试会报错,mount失败,若每次断电重上电则不会。但结果是这样的

****** FatFs Example ******

mount sucess!!!
open file sucess!!!
write file error : 1
close error : 1
open file error : 16
read error!!! 9
close error!!! 9
FatFs is working well!!!
打开成功,但写入时出现错误,查了错误号1是硬件错误,出现在底层I/O时。
仍不清楚怎么回事,对比了open746i的源代码,main里面的函数是一致的。其他也都是默认的。
只不过我的cubemx版本是4.16.1,cubef7版本是1.4.1都是最新版本,但我看里面的文件没什么变化。
不知道为什么?
引用 MyMX1213 2016-9-26 09:12
这个是没有问题的,你可以下载Open746的完整代码参考一下,看有没有哪里不一致。
引用 yycqz 2016-9-25 22:15
这个例子似乎不正确,按讲义修改运行提示出错,串口调试助手显示, ****** FatFs Example ******

mount sucess!!!
open file error : 13
write file error : 9
close error : 9
open file error : 13
read error!!! 9
close error!!! 9
FatFs is working well!!!
开始时的
    /*##-1- Register the file system object to the FatFs module ##############*/
    retSD = f_mount(&fs, "", 0);
里面参数是0,不是1,并没有mount工作区吧

查看全部评论(11)

CubeMX教程

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2019-11-17 10:06 , Processed in 0.020582 second(s), 19 queries .

Powered by Discuz! X3.2 © 2001-2013 Comsenz Inc & Style Design

返回顶部