继上一篇文章连接好FatFs与SD卡后,这里开始介绍如何配置操作FatFs。
第一步、建立文件系统和文件结构变量,相当于为文件系统以及文件开辟一个实体,如下图
第二步、加载文件系统(Mount or Unmount),这里需要调用f_mount函数,函数格式如下
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相当于你加载的磁盘符,这里默认为"0:/",也就是磁盘符为0.
opt是加载选项,这里设置为1,立即加载。
当其返回FR_OK时,说明加载成功,其他一些返回状态见ff.h,这里不再列举了
然后调用f_mount函数即可,如下图
第三步、加载好文件系统后,下面就可以操作文件系统了,在创建文件之前,我先创建个路径(其实路径也可以不用创建,那样的话就在跟目录下了)
创建目录需要调用f_mkdir函数,函数格式如下
FRESULT f_mkdir (
const TCHAR* path/* Pointer to the directory path */
)
其只有一个参数path,为指向所创建目录的指针。
同样,其返回FR_OK说明创建成功
调用f_mkdir函数,如下图
其中,文件夹格式为年_月,文件名格式日_时。
第四步、文件夹路径创建好后,就可以创建文件了,文件系统通过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为文件路径,这里需要注意,这里的文件路径必须要包含之前文件夹名以及文件名,例如我想在16_12文件夹中创建15_13文件,需要将路径赋值为
"0:/16_12/15_13.txt",如果该路径只加文件名的话,还是会将文件创建在根目录下的。
参数mode为操作选项,我们这里赋值为FA_WRITE | FA_OPEN_ALWAYS表示以写的方式打开或创建文件,如果文件存在,则打开,如果文件不存在则创建。
调用该函数如果返回FR_OK,则说明文件打开成功。
第五步、向文件中写入数据,直接调用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为写入数据缓冲区
btw为写入数据长度
bw为btw的指针
调用过程如下
f_lseek(fil,fil->fsize);
Sd_Fat_Data.File_Wt_Flg = f_write(fil, Sd_Fat_Data.BMS_Str_Buffer, index, &bw);
我这里的数据比较长,就不截图了。有一点注意的是,在多次重复写入一个文件前,需要调用一下f_lseek(fil,fil->fsize); 其作用就是定位到你要写入的文件的末端,这样写入的数据才不会覆盖文件原有的数据。
第六步、文件写好后,如果不想继续操作,就可以关闭文件并卸载文件系统工作区间了
f_close(&Fil);
f_mount(NULL,"0:/",1);
注:在测试过程中遇到的问题现象
1、我在实际应用中是每500ms向文件中写2000字节左右的数据,刚开始操作是每写一次文件前打开文件,写好后再关闭文件。
后来经测试发现,在连续几十小时写入文件没有出现任何错误的情况下(打开或写入文件出错的情况下向上位机发送标识),SD卡文件夹中出现了很多莫名其妙的文件,在电脑端打不开也删不了。出现这种问题实在是找不出原因,所以究其根本,既然是出现了很多乱七八糟的文件,那应该是在打开文件的时候,文件路径指针指飞的原因。
后来改进了自己的方法,因为我的系统是按小时来更新文件,如下图
于是我在每次建立一个新文件后,只打开该文件一次,并且只在达到需要建立下一个文件的条件时才关闭该文件,至于存储过程中文件如何更新,则改成调用f_sync(&Fil);
也就是避免了最初的频繁调用open及close函数。后来经几天几夜的测试,之前乱七八糟文件出现的现象没有了,文件的写入也很正常。下图是我写的文件
至此,我的批量存储功能已经完成,文中如有不合理的地方,也请大家指正。