(46)STM32——FATFS文件系统实验

news/2024/6/3 17:24:40 标签: stm32, 单片机, arm

目录

学习目标

运行结果

文件系统

常用系统

FATFS

特点

结构图

移植步骤

disk_initialize

disk_status

 disk_read

 disk_write

disk_ioctl

get_fattime

代码

总结 


学习目标

        我们要来介绍的是FATFS文件系统,这是一个为嵌入式设计的文件系统,甚至8051系列也可以使用,好了,我们开始介绍吧!

运行结果

 

文件系统

        负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。即在磁盘上组织文件的方法。

常用系统

  • FAT/FATFS
  • NTFS:基于安全性的文件系统,是Windows NT所采用的独特的文件系统结构。
  • CDFS:CDFS是大部分的光盘的文件系统。
  • exFAT

FATFS

        FATFS文件系统FATFS是一个完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。完全用标准的C语言编写,所以具有良好的硬件平台独立性。可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。它支持FAT12、FAT16和FAT32,支持多个存储媒介:有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。并且FATFS是可裁剪的文件系统,所以可以适配一些内存小的MCU,只需要删掉一些功能即可。

特点

  • Windows 兼容的 FAT 文件系统(支持 FAT12/FAT16/FAT32)
  • 与平台无关,移植简单
  • 代码量少、效率高
  • 多种配置选项
    • 支持多卷(物理驱动器或分区,最多 10 个卷)
    • 多个 ANSI/OEM 代码页包括 DBCS
    • 支持长文件名、ANSI/OEM 或 Unicode
    • 支持 RTOS
    • 支持多种扇区大小
    • 只读、最小化的 API 和 I/O 缓冲区等
  • 免费、开源

结构图

  1. 底层接口,包括存储媒介读或写接口(disk I/O)和供给文件创建修改时间的实时时钟,需要我们根据平台和存储介质编写移植代码。
  2. 中间层FATFS模块,实现了FAT文件读或写协议。FATFS模块提供的是ff.c和ff.h。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。
  3. 最顶层是应用层,使用者无需理会FATFS的内部结构和复杂的FAT协议,只需要调用FATFS模块提供给用户的一系列应用接口函数,如f_open  f_read  f_write和f_close等,就可以像在PC上读/写文件那样简单。

        这个就是FATFS文件系统包的结构,diskio 是我们需要与硬件相关的,需要我们来修改。ff 是核心系统代码,不需要修改。然后还有 ffconf 需要我们修改相应的配置。

        FATFS 模块在移植的时候,我们一般只需要修改 2 个文件,即 ffconf.h 和 diskio.c。FATFS 模块的所有配置项都是存放在 ffconf.h 里面,我们可以通过配置里面的一些选项,来满足自己的需求。接下来简单介绍几个配置选项。

  1. _FS_TINY。我们使用 FATFS,所以把这个选项定义为 0 即可。如果使用Tiny FATFS,就定义为1。
  2. _FS_READONLY。这个用来配置是不是只读,我们需要读写都用,所以这里设置为 0 即可。
  3. _USE_STRFUNC。这个用来设置是否支持字符串类操作,比如 f_putc,f_puts 等,比较耗内存,我们需要用到,故设置这里为 1。
  4. _USE_MKFS。这个用来定时是否使能格式化,我们需要用到,所以设置这里为 1。
  5. _USE_FASTSEEK。这个用来使能快速定位,我们设置为 1,使能快速定位。
  6. _USE_LABEL。这个用来设置是否支持磁盘盘符(磁盘名字)读取与设置。我们设置 为 1,使能,就可以通过相关函数读取或者设置磁盘的名字了。
  7. _CODE_PAGE。这个用于设置语言类型,包括很多选项,我们这里设置为 936,即简体中文(GBK 码,需要 c936.c 文件支持,该文件在 option 文件夹)。
  8. _USE_LFN。该选项用于设置是否支持长文件名(还需要_CODE_PAGE 支持),取值范围为 0~3。0,表示不支持长文件名,1~3 是支持长文件名,但是存储地方不一样,我们选择使用 3,通过 ff_memalloc 函数来动态分配长文件名的存储区域。
  9. _VOLUMES。用于设置 FATFS 支持的逻辑设备数目,我们设置为 2,即支持 2 个设备。
  10. _MAX_SS。扇区缓冲的最大值,一般设置为 512。

移植步骤

  1. 数据类型:在 integer.h 里面去定义好数据的类型。这里需要了解你用的编译器的数 据类型,并根据编译器定义好数据类型。
  2. 配置:通过 ffconf.h 配置 FATFS 的相关功能,以满足你的需要。
  3. 函数编写:打开 diskio.c,进行底层驱动编写,一般需要编写 6 个接口函数。

        第一步,我们使用的是 MDK5.11a 编译器,器数据类型和 integer.h 里面定义的一致,所以此步,我们不需要做任何改动。

        第二步,关于 ffconf.h 里面的相关配置,我们在前面已经有介绍(之前介绍的 10 个配置),我们将对应配置修改为我们介绍时候的值即可,其他的配置用默认配置。

        第三步,因为 FATFS 模块完全与磁盘 I/O 层分开,因此需要下面的函数来实现底层物理磁盘的读写与获取当前时间。底层磁盘 I/O 模块并不是 FATFS 的一部分,并且必须由用户提供。这些函数一般有 6 个,在 diskio.c 里面。

disk_initialize

        主要用来初始化磁盘。 

disk_status

         返回磁盘状态。

 disk_read

         首先选择磁盘,然后需要读的数据大小,所以需要做好适配。

 disk_write

        同上。 

disk_ioctl

        除了读写之外的其他参数。 

get_fattime

        获取时间。 

代码

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"  
#include "sram.h"   
#include "malloc.h" 
#include "usmart.h"  
#include "sdio_sdcard.h"    
#include "malloc.h" 
#include "w25qxx.h"    
#include "ff.h"  
#include "exfuns.h"    
int main(void)
{        
	FIL fp;
	FRESULT result;
	UINT bww;
	char buf[100];
 	u32 total,free;
	u8 t=0;	
	u8 res=0;	

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);  //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	LED_Init();					//初始化LED 
	usmart_dev.init(84);		//初始化USMART
 	LCD_Init();					//LCD初始化  
 	KEY_Init();					//按键初始化 
	W25QXX_Init();				//初始化W25Q128
	my_mem_init(SRAMIN);		//初始化内部内存池 
	my_mem_init(SRAMCCM);		//初始化CCM内存池
	
 	POINT_COLOR=RED;//设置字体为红色 
	LCD_ShowString(30,90,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,110,200,16,16,"FATFS TEST");	  
	LCD_ShowString(30,130,200,16,16,"Use USMART for test");	   
 	while(SD_Init())//检测不到SD卡
	{
		LCD_ShowString(30,150,200,16,16,"SD Card Error!");
		delay_ms(500);					
		LCD_ShowString(30,150,200,16,16,"Please Check! ");
		delay_ms(500);
		LED0=!LED0;//DS0闪烁
	}
 	exfuns_init();							//为fatfs相关变量申请内存				 
  	f_mount(fs[0],"0:",1); 					//挂载SD卡 
 	res=f_mount(fs[1],"1:",1); 				//挂载FLASH.	
	if(res==0X0D)//FLASH磁盘,FAT文件系统错误,重新格式化FLASH
	{
		LCD_ShowString(30,150,200,16,16,"Flash Disk Formatting...");	//格式化FLASH
		res=f_mkfs("1:",1,4096);//格式化FLASH,1,盘符;1,不需要引导区,8个扇区为1个簇
		if(res==0)
		{
			f_setlabel((const TCHAR *)"1:ALIENTEK");	//设置Flash磁盘的名字为:ALIENTEK
			LCD_ShowString(30,150,200,16,16,"Flash Disk Format Finish");	//格式化完成
		}else LCD_ShowString(30,150,200,16,16,"Flash Disk Format Error ");	//格式化失败
		delay_ms(1000);
	}													    
	LCD_Fill(30,150,240,150+16,WHITE);		//清除显示			  
	while(exf_getfree("0",&total,&free))	//得到SD卡的总容量和剩余容量
	{
		LCD_ShowString(30,150,200,16,16,"SD Card Fatfs Error!");
		delay_ms(200);
		LCD_Fill(30,150,240,150+16,WHITE);	//清除显示			  
		delay_ms(200);
		LED0=!LED0;//DS0闪烁
	}													  			    
 	POINT_COLOR=BLUE;//设置字体为蓝色	   
	LCD_ShowString(30,150,200,16,16,"FATFS OK!");	 
	LCD_ShowString(30,170,200,16,16,"SD Total Size:     MB");	 
	LCD_ShowString(30,190,200,16,16,"SD  Free Size:     MB"); 	    
 	LCD_ShowNum(30+8*14,170,total>>10,5,16);				//显示SD卡总容量 MB
 	LCD_ShowNum(30+8*14,190,free>>10,5,16);					//显示SD卡剩余容量 MB			    
	
	result  = f_open (& fp, "0:1.txt", FA_CREATE_ALWAYS | FA_WRITE);
	
	f_write (&fp," test" , 50, & bww);
	
	f_close(&fp);
	
	result  = f_open (& fp, "0:1.txt", FA_READ);
	
	f_read (& fp, buf,100, & bww);
	
	f_close(&fp);
	
	LCD_ShowString(30,210,230,16,16,(u8 *)buf);
	while(1)
	{
		t++; 
		delay_ms(200);		 			   
		LED0=!LED0;
	} 
}





总结 

        文件系统,目前感觉用不太到,而且都是偏向工程类的,其实不能像例程写的这么简单,但用来了解一下还是可以的。


http://www.niftyadmin.cn/n/418.html

相关文章

如何从gitee上拉项目?

​​​​​​​ 目录 ​​​​​​​​​​​​​​ 第一步:下载git软件 第二步:一直下一步,傻瓜式安装 第三部:使用 新建一个文件夹 2. 右击,打开命令窗口 3. 复制项目下载url 4.命令窗口输入这样一串命令 第…

Python编程运算符 ——算数运算符

作者简介:一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.运算符 1.在Python运算符中分为 2.算数运算符 3.比较重要的运算符 4…

【经典DP】Good String (不同好串的个数)

题目 描述 We consider a string to be a good string if and only if the string contains no palindromic substrings of length greater than 2 Now we want to know how many different good strings are there for all strings of exactly n length and character set s…

【C语言】三子棋小游戏

🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:初出茅庐C语言 ☀️ 学习格言:眼泪终究流不成海洋,人总要不断成长&am…

复旦-华盛顿大学EMBA 二十年20人丨徐欣:从外企转战民企的变身

复旦大学-华盛顿大学EMBA20周年校友系列访谈。      2008年堪称转折之年,中国举行北京奥运会向全世界展示“和而不同”的理念,入世7年让中国在贸易、金融领域与全球市场紧密相连,一大批最优秀的中国民营企业也加速踏上全球化之路。    …

Linux学习-07-Linux目录常用操作命令1

3.5 Linux cd命令:切换目录 cd (Change Directory) ,用来切换工作目录。Linux 命令按照来源方式,可分为两种,分别是 Shell 内置命令和外部命令。所谓 Shell 内置命令,就是 Shell 自带的命令,这些命令是没有…

redis的三种集群模式

redis集群模式有几种?三种 哪三种? 主从模式 哨兵模式 分布式模式 主从模式 最常见的模式,一主多从。主节点负责写,从节点负责读。 优点 提高了可用性,解决了单点故障的问题。 缺点 master宕机需要手动切换 多从…

使用 Qt 调用 Excel

Qt 3.1 及以上版本的一个新特性是为 Windows 操作系统提供了 ActiveX 支持。开发者如果关 心如何使用 Qt 操作 COM 组件,比如在 Excel 里插入新数据,这个新增功能就很重要了。 然而不幸的是,在 Internet 上没有太多这方面的主题可以借鉴。我在这里演示一个例子,可 能会对大…