文章目录
使用Cubemx 创建SD的文件系统工程
软件工具
1、 STM32CubeMX 6.2.1
2、 Keil MDK5.35
3、 CubeMX 引用固件库版本 STM32Cube_FW_F1_V1.8.4
创建 CubeMX 工程
SDIO 配置
SDIO 配置,如果通信出现 IO 层的错误,可以尝试增大分频系数来减小时钟
FATFS配置
选择 SD 卡
1、 长文件夹名存储位置 我们设置在栈空间 STACK(在生成工程是需要调整栈空间大小)
2、 文件夹名的长度
3、 FS_RPATH 该参数与部分函数使能有关 详细查看 ffconf.h 文件中的注释
创建工程
引用 Middlewares 的 FatFs 分析
Fatfs 概述
在 CUbeMX 中引用的文件系统版本为 0.11
官方 0.11 版本中的内容
文件名 | 文件内容 | 修改需求 |
---|---|---|
00readme.txt | 当前文件 | |
history.txt | 修订历史 | |
ffconf.h | FatFs 模块的配置文件 | |
ff.h | FatFs 和应用程序模块的通用包含文件 | |
ff.c | FatFs 模块 | |
diskio.h | FatFs 和磁盘 I/O 模块的通用包含文件 | |
diskio.c | 将现有磁盘 I/O 模块附加到 FatFs 的粘合函数示例 | |
integer.h | FatFs 的整数类型定义 | |
option | 可选的外部函数 | 支持简体中文的cc963.c文件 |
在 CubeMX 的引用中多的文件
文件名 | 文件内容 | 修改需求 |
---|---|---|
ff_gen_drv |
关键结构体与枚举数据
文件系统对象结构体(FATFS)
typedef struct {
union{
UINT d32[_MAX_SS/4]; /* 强制32位对齐 */
BYTE d8[_MAX_SS]; /*磁盘访问窗口的目录,FAT(和文件数据在微型cfg) */
}win;
BYTE fs_type; /* FAT子类型(0:不安装) */
BYTE drv; /* 物理驱动器号 */
BYTE csize; /* 每个集群(1,2,4,…128) */
BYTE n_fats; /* FAT拷贝数(1或2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* 文件系统挂载ID */
WORD n_rootdir; /* 根目录条目数(FAT12/16) */
#if _MAX_SS != _MIN_SS
WORD ssize; /* 每个扇区的字节数 (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* 同步对象的标识符 */
#endif
#if !_FS_READONLY
DWORD last_clust; /* 最后分配的集群 */
DWORD free_clust; /* 空闲集群数 */
#endif
#if _FS_RPATH
DWORD cdir; /* 当前目录启动集群(0:root) */
#endif
DWORD n_fatent; /* FAT条目数,=集群数+ 2 */
DWORD fsize; /* 每个FAT的扇区 */
DWORD volbase; /* 卷开始扇区 */
DWORD fatbase; /* FAT启动扇区 */
DWORD dirbase; /* 根目录启动扇区 (FAT32:Cluster#) */
DWORD database; /* 数据开始扇区 */
DWORD winsect; /* 当前扇区出现在 win[] */
} FATFS;
文件对象结构体(FIL)
typedef struct {
#if !_FS_TINY
union{
UINT d32[_MAX_SS/4]; /* 强制32位对齐 */
BYTE d8[_MAX_SS]; /* 文件数据读/写缓冲区 */
}buf;
#endif
FATFS* fs; /* 指向相关文件系统对象的指针(**不要更改顺序**) */
WORD id; /* 所有者文件系统的挂载ID(**不改变顺序**) */
BYTE flag; /* 状态标志 */
BYTE err; /* /*中止标志(错误代码) */
DWORD fptr; /* 文件读/写指针(在文件打开时置零) */
DWORD fsize; /* 文件大小 */
DWORD sclust; /* 文件启动集群(0:没有集群链,当fsize为0时总是0) */
DWORD clust; /* 当前的fpter集群(当fprt为0时无效) */
DWORD dsect; /* buf[]中出现扇区号(0:无效) */
#if !_FS_READONLY
DWORD dir_sect; /* 包含目录条目的扇区号 */
BYTE* dir_ptr; /* 指向win[] 中的目录项 */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /*指向集群链接映射表的指针(在文件打开时为空)*/
#endif
#if _FS_LOCK
UINT lockid; /*文件锁ID来源于1(文件信号表的索引Files[]) */
#endif
} FIL;
目录对象结构体(DIR)
typedef struct {
#if !_FS_TINY
union{
UINT d32[_MAX_SS/4]; /*强制32位对齐*/
BYTE d8[_MAX_SS]; /*文件数据读/写缓冲区*/
}buf;
#endif
FATFS* fs; /*指向文件系统对象所有者的指针(**不改变顺序**)*/
WORD id; /*所有者文件系统的挂载ID(**不改变顺序**)*/
WORD index; /*当前读写索引号*/
DWORD sclust; /*表启动集群(0:根目录)*/
DWORD clust; /*当前集群*/
DWORD sect; /*当前扇区*/
BYTE* dir; /*指向win的当前SFN表项[]*/
BYTE* fn; /*指向SFN的指针(in/out) {file[8],ext[3],status[1]} */
#if _FS_LOCK
UINT lockid; /*文件锁ID(文件信号表的索引Files[]) */
#endif
#if _USE_LFN
WCHAR* lfn; /*指向LFN工作缓冲区的指针*/
WORD lfn_idx; /*最后匹配的LFN索引号(0xFFFF:没有LFN) */
#endif
#if _USE_FIND
const TCHAR* pat; /*指向匹配模式的名称*/
#endif
} DIR;
文件信息结构体(FILINFO)
typedef struct {
DWORD fsize; /* 文件大小 */
WORD fdate; /* 最后修改日期 */
WORD ftime; /* 最后修改时间 */
BYTE fattrib; /* 属性 */
TCHAR fname[13]; /*短文件名(8.3格式)*/
#if _USE_LFN
TCHAR* lfname; /*指向LFN缓冲区的指针*/
UINT lfsize; /* LFN缓冲区的大小在TCHAR */
#endif
} FILINFO;
文件函数返回码(FRESULT)
typedef enum {
FR_OK = 0, /* (0) 成功 */
FR_DISK_ERR, /* (1) 低级磁盘I/O层发生硬错误 */
FR_INT_ERR, /* (2) 断言失败 */
FR_NOT_READY, /* (3) 物理驱动器无法工作 */
FR_NO_FILE, /* (4) 找不到文件 */
FR_NO_PATH, /* (5) 找不到路径 */
FR_INVALID_NAME, /* (6) 路径名格式无效 */
FR_DENIED, /* (7) 由于禁止访问或目录已满而拒绝访问 */
FR_EXIST, /* (8) 由于禁止访问而拒绝访问*/
FR_INVALID_OBJECT, /* (9) 文件/目录对象无效 */
FR_WRITE_PROTECTED, /* (10) 物理磁盘被写保护 */
FR_INVALID_DRIVE, /* (11) 逻辑驱动器号无效 */
FR_NOT_ENABLED, /* (12) 卷无工作区 */
FR_NO_FILESYSTEM, /* (13) 没有有效的FAT卷 */
FR_MKFS_ABORTED, /* (14) f_mkfs()由于任何参数错误而中止 */
FR_TIMEOUT, /* (15) 在指定的时间内无法获得访问卷的授权 */
FR_LOCKED, /* (16) 根据文件共享策略,操作被拒绝 */
FR_NOT_ENOUGH_CORE, /* (17) LFN工作缓冲区无法分配 */
FR_TOO_MANY_OPEN_FILES, /* (18) 打开的文件数> _FS_SHARE */
FR_INVALID_PARAMETER /* (19) 给出的参数是无效的 */
} FRESULT;
使用注意事项
如果对文件进行了任何更改之后未关闭文件或掉电前未关闭文件,会导致数据写入失败 在电脑上查看不存在写入数据
可以使用 f_write 函数与 f_sync 函数配合将数据刷新到文件对象中
// f_sync函数刷新写入文件的缓存信息。
FRESULT f_sync ( FIL* fp ); /* 输入参数:文件对象 */
版权声明:本文为qq_39567970原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。