FATFS备忘
FATFS文件系统可以挂载SD卡也可以挂载FLASHeMMC等设备SD卡需要格式化为FAT32模式 块大小默认即可。
概述
FATFS文件系统可以挂载SD卡也可以挂载FLASHeMMC等设备
SD卡需要格式化为
FAT32模式 块大小默认即可

移植
SD卡
SD卡扇区大小是 512B
SD卡 SDIO模式 可以直接在
cubeMX里一键设置
先设置好SD卡的设置
这个是选择支持中文 其余是默认

这个是检测引脚可以留空
当SD卡插入拔出时会引起检测脚的变化

FLASH
FLASH接入FATFS需要自行修改接口,选用自定义模式
建议配合USB MSC功能使用
cubeMX配置
使用自定义模式,将扇区大小改为从512到4096都可

设置内容
全在cubeMX生成的
user_diskio.c中
先导入头文件和设置扇区大小

需要设置的APIs
全在
cubeMX生成的user_diskio.c中
初始化
| 描述 | 名称 | 功能 |
|---|---|---|
BYTE(uint8_t) |
pdrv |
磁盘编号 |
DSTATUS |
输出 | 错误码 |
DSTATUS USER_initialize (BYTE pdrv)
成功返回
RES_OK失败返回RES_ERROR根据自己初始化写入函数
例子
这里不需要初始化直接返回成功即可
DSTATUS USER_initialize(
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
/* USER CODE BEGIN INIT */
UNUSED(pdrv);
return RES_OK;
/* USER CODE END INIT */
}
获取磁盘状态
| 描述 | 名称 | 功能 |
|---|---|---|
BYTE(uint8_t) |
pdrv |
磁盘编号 |
DSTATUS |
输出 | 错误码 |
DSTATUS USER_status(BYTE pdrv)
成功返回
RES_OK失败返回RES_ERROR不使用返回即可
例子
DSTATUS USER_status(
BYTE pdrv /* Physical drive number to identify the drive */
)
{
/* USER CODE BEGIN STATUS */
UNUSED(pdrv);
return RES_OK;
/* USER CODE END STATUS */
}
读取扇区
| 描述 | 名称 | 功能 |
|---|---|---|
BYTE(uint8_t) |
pdrv |
磁盘编号 |
BYTE(uint8_t) |
buff |
缓冲区 |
DWORD |
sector |
扇区编号 |
UINT (uint32_t) |
count |
扇区数量 |
DSTATUS |
输出 | 错误码 |
DRESULT USER_read(BYTE pdrv,BYTE *buff,DWORD sector,UINT count)
示例
这个函数
W25Qxx_Read_Data输入的是FLASH的地址和byte数量,因此要乘上扇区大小
DRESULT USER_read(
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
/* USER CODE BEGIN READ */
W25Qxx_Read_Data(sector * USER_SECTOR_SIZE, buff, count * USER_SECTOR_SIZE);
return RES_OK;
/* USER CODE END READ */
}
写入扇区
| 描述 | 名称 | 功能 |
|---|---|---|
BYTE(uint8_t) |
pdrv |
磁盘编号 |
BYTE(uint8_t) |
buff |
缓冲区 |
DWORD |
sector |
扇区编号 |
UINT (uint32_t) |
count |
扇区数量 |
DSTATUS |
输出 | 错误码 |
DRESULT USER_write(BYTE pdrv,const BYTE *buff,DWORD sector,UINT count)
示例
这个函数
W25Qxx_Write输入的是FLASH的地址和byte数量,因此要乘上扇区大小
DRESULT USER_write(
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
/* USER CODE BEGIN WRITE */
/* USER CODE HERE */
W25Qxx_Write(sector * USER_SECTOR_SIZE, (uint8_t *)buff, count * USER_SECTOR_SIZE, 0);
return RES_OK;
/* USER CODE END WRITE */
}
控制操作
| 描述 | 名称 | 功能 |
|---|---|---|
BYTE(uint8_t) |
pdrv |
磁盘编号 |
BYTE(uint8_t) |
cmd |
命令 |
void * |
buff |
缓冲区 |
DSTATUS |
输出 | 错误码 |
DRESULT USER_ioctl(BYTE pdrv,BYTE cmd,void *buff)
必须要响应的命令
| 描述 | 功能 |
|---|---|
GET_SECTOR_COUNT |
扇区数量 |
GET_SECTOR_SIZE |
扇区大小 单位byte |
GET_BLOCK_SIZE |
区块大小 |
例子
使用W25Q128 16MB
扇区大小为4096=4KB
扇区数为 4096 这里写4095
区块直接写1 即可
DRESULT USER_ioctl(
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
/* USER CODE BEGIN IOCTL */
DRESULT res = RES_OK;
switch (cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case CTRL_TRIM:
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD *)buff = 4095;
break;
case GET_SECTOR_SIZE:
*(DWORD *)buff = USER_SECTOR_SIZE;
break;
case GET_BLOCK_SIZE:
*(DWORD *)buff = 1;
break;
}
return res;
/* USER CODE END IOCTL */
}
APIs
地址问题
根据初始化顺序,驱动器的根地址分别为
0:/1:/…比如这个例子里 SD卡的根地址是
0:/USER(可以设为FLASH等) 地址为1:/

挂载
| 描述 | 名称 | 功能 |
|---|---|---|
FATFS* |
fs |
句柄 |
const TCHAR* |
path |
地址 |
BYTE |
opt |
是否立即加载(一般写1) |
FRESULT |
输出 | 错误码 |
FRESULT f_mount (FATFS* fs,const TCHAR* path,BYTE opt)
挂载例子
f_mount(&hFatfs, "0:/", 1);
打开文件
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
const TCHAR* |
path |
地址 |
BYTE |
mode |
模式 |
FRESULT |
输出 | 错误码 |
| 描述 | 功能 |
|---|---|
FA_READ |
只读 |
FA_WRITE |
只写 |
FA_OPEN_EXISTING |
如果文件存在,则打开;否则打开失败 |
FA_CREATE_NEW |
创建一个文件,如果文件存在,则创建失败 |
FA_CREATE_ALWAYS |
创建一个文件,如果文件存在,则覆盖原文件 |
FA_OPEN_ALWAYS |
如果文件存在,则打开,如果不存在则创建一个文件并打开 |
可以输入
FA_READ | FA_WRITE来使用读写
FRESULT f_open (FIL* fp,const TCHAR* path,BYTE mode)
打开后光标指向开头
关闭文件
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
FRESULT |
输出 | 错误码 |
FRESULT f_close (FIL* fp)
读文件
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
void* |
buff |
缓冲区 |
UINT |
btr |
操作数量 |
UINT* |
br |
已操作数量 |
FRESULT |
输出 | 错误码 |
FRESULT f_read (FIL* fp,void* buff,UINT btr,UINT* br)
会从光标处开始读取 指针自增
写文件
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
void* |
buff |
缓冲区 |
UINT |
btr |
操作数量 |
UINT* |
br |
已操作数量 |
FRESULT |
输出 | 错误码 |
FRESULT f_write (FIL* fp,const void* buff,UINT btw,UINT* bw)
会从光标处开始写入 指针自增
打印到文件
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
const TCHAR* |
fmt |
规则格式串 |
... |
... |
... |
int |
输出 | 写入数量 |
int f_printf (FIL* fp,const TCHAR* fmt,...)
会从光标处开始写入 指针自增
获取文件大小
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
FSIZE_t |
输出 | 大小 |
f_size(fp)
改变光标位置
| 描述 | 名称 | 功能 |
|---|---|---|
FIL* |
fp |
文件 |
FSIZE_t |
ofs |
从顶部开始的偏移 |
FRESULT |
输出 | 错误码 |
FRESULT f_lseek (FIL* fp,FSIZE_t ofs)
删除文件
| 描述 | 名称 | 功能 |
|---|---|---|
const TCHAR* |
path |
路径 |
FRESULT |
输出 | 错误码 |
FRESULT f_unlink (const TCHAR* path)
检查文件是否存在
| 描述 | 名称 | 功能 |
|---|---|---|
const TCHAR* |
path |
路径 |
FILINFO* |
fno |
信息 |
FRESULT |
输出 | 不存在FR_NO_FILE,存在FR_OK |
FRESULT f_stat (const TCHAR* path,FILINFO* fno)
更多推荐



所有评论(0)