概述
FATFS
文件系统可以挂载SD卡也可以挂载FLASH
eMMC
等设备
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)