一、前言
FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 组件的编写遵循ANSI C(C89),完全分离于磁盘 I/O 层,因此不依赖于硬件平台。它可以嵌入到资源有限的微控制器中,如 8051, PIC, AVR, ARM, Z80, RX等等,不需要做任何修改。
二、硬件及软件准备
完整工程源码下载地址:
https://download.csdn.net/download/qq_44062900/18451571
1、硬件:STM32系列单片机
2、软件:Keil5、FatFS文件系统开源库、正点原子《实验24 SPI实验》(外部FLASH实验)代码
FatFS文件系统开源库下载:
http://elm-chan.org/fsw/ff/archives.html
正点原子实验代码下载:
https://download.csdn.net/download/qq_44062900/18451671
三、移植FatFS文件到工程文件夹下
1、解压下载好的文件,解压后如下图
"document"文件夹存放的是官方的API参考
"source"文件夹存放的是源文件
2、复制正点原子实验代码《实验24 SPI实验》,修改文件夹名为“STM32移植FATFS文件系统”,在该文件夹下创建“FATFS”文件夹
3、将FATFS中的“source”文件夹下的“ff.c”、“ff.h”、“ffconf.h”、“diskio.c”、“diskio.h”的5个文件复制到工程文件夹下的"FATFS"子文件夹中。“source”文件夹下的其他文件可以不用移植。
在这个5个文件中,我们只需要修改其中的“ffconf.h”配置文件和“diskio.c”底层存储设备驱动文件。
四、将移植文件添加到工程中
1、打开工程,在工程分组中创建一个“FATFS”分组,并将上述3个.c文件添加到工程,并设置头文件路径
2、编译工程,查看错误或警告信息,正常为13个错误和17个警告
3、修改编译错误
这个错误是默认FATFS是使能RTC功能的,这里可以将其关闭
在“ffconf.h”配置文件中将这个宏设为1即可
五、修改“diskio.c”文件
1、定义一个物理驱动器号,这里我使用外部FLASH,如有多个存储设备,在这定义即可,物理驱动器号从“0”开始
2、修改disk_status()函数,这个是获取驱动器状态的,大家可以根据返回状态自己编写,这里为了方便直接返回“RES_OK”
3、修改disk_initialize()函数,这里对硬件进行初始化,注意包含相应的头文件
4、修改disk_read()函数,这个函数的功能是从外部FLASH中读取数据
定义以下宏
5、修改disk_write()函数,这个函数的功能是向外部FLASH中写入数据
6、修改disk_ioctl()函数,这个函数是控制设备实现指定功能,用于辅助FATFS中其他API。
7、至此文件修改就已经完成了
六、配置“ffconf.h”文件
1、设置"FF_USE_STRFUNC" 宏为1,这个开启之后可以使用字符串辅助函数,例如f_gets()、f_putc()、f_puts() 、 f_printf() 等等
2、"FF_CODE_PAGE"为936,即为简体中文编码,设置不正确可能会导致打开文件失败
3、"FF_VOLUMES"这个宏是设置有几个卷,这里我的只有一个,填写范围为1~10
4、其他宏可根据需求选择开启
七、测试FATFS移植是否成功
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "w25qxx.h"
#include "ff.h"
#include "string.h"
FATFS fs;//文件系统对象
FIL fp;//文件对象
char *write_text="FATFS test success!";
unsigned int write_bytes=0;
char read_buff[512];
unsigned int read_bytes=0;
int main(void)
{
u8 key=0;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
KEY_Init(); //按键初始化
if(!f_mount(&fs,"0:",1))//挂载外部FLASH)
{
printf("mount success!n");
}
else printf("mount failure!n");
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES)
{
if(!f_open(&fp,"0:test.txt",FA_CREATE_ALWAYS | FA_WRITE))
{
printf("open file success!n");
}
else printf("open file failure!n");
if(!f_write(&fp,(char*)write_text,strlen(write_text),&write_bytes))
{
printf("write success,write_bytes=%dn",write_bytes);
}
else printf("write failure!n");
if(!f_close(&fp))
{
printf("close success!n");
}
else printf("close failure!n");
}
else if(key==KEY1_PRES)
{
if(!f_open(&fp,"0:test.txt",FA_READ))
{
printf("open file success!n");
}
else printf("open file failure!n");
if(!f_read(&fp,(char*)read_buff,sizeof(read_buff),&read_bytes))
{
printf("read success,write_bytes=%dn",read_bytes);
printf("test.txt content is :%sn",read_buff);
}
else printf("read failure!n");
if(!f_close(&fp))
{
printf("close success!n");
}
else printf("close failure!n");
}
}
}
2、实现效果