☰
单片机基础知识(六)FatFs文件系统
2026/10/16 2:12:04 网站建设 项目流程

文章目录

  • @[toc]
  • 官方文档介绍-FatFs
  • 前提知识准备
      • 一、核心编程语言:C语言(优先级★★★★★)
      • 二、嵌入式系统基础(优先级★★★★★)
      • 三、存储介质原理(优先级★★★★)
      • 四、文件系统基础概念(优先级★★★★)
      • 五、底层驱动开发能力(优先级★★★★)
      • 六、辅助调试与配置能力(优先级★★★)
      • 七、可选但加分的知识(优先级★★)
      • 学习路径建议
  • 一、**簇、FAT表、目录项详解**
    • **1. 簇 (Cluster) - 存储的基本单位**
      • **什么是簇?**
      • **比喻:仓库的储物柜**
      • **实际示例**
      • **簇的特点**
    • **2. FAT表 (File Allocation Table) - 簇的地图导航**
      • **什么是FAT表?**
      • **比喻:快递追踪系统**
      • **FAT表项的值**
      • **文件簇链示例**
      • **FAT表在磁盘上的位置**
    • **3. 目录项 (Directory Entry) - 文件的身份证**
      • **什么是目录项?**
      • **比喻:图书馆的图书卡片**
      • **目录项的详细结构(32字节)**
      • **属性字节 (DIR_Attr) 详解**
      • **目录项示例**
    • **三者的协同工作流程**
      • **场景:读取文件"DATA.BIN"**
      • **场景:创建新文件**
    • **FatFs中对应的操作**
    • **实际调试示例**
    • **常见问题**
      • **Q: 为什么我的4KB文件显示占用8KB?**
      • **Q: 删除文件后数据还在吗?**
      • **Q: 如何查看文件的真实簇链?**
  • 二、**FAT32 磁盘布局**
    • **关键结构详解**
      • **1. 引导扇区 (DBR - DOS Boot Record)**
      • **2. FAT 表 (File Allocation Table)**
      • **3. 目录项结构 (32字节)**
      • **4. 长文件名支持 (LFN)**
      • **5. 簇的寻址**
      • **6. 文件簇链示例**
    • **与 FatFs 的关联**
      • **FatFs 内部结构**
      • **常用 FatFs 函数与 FAT32 的关系**
    • **FAT32 限制**
    • **学习建议**
  • 三、实际应用
      • 📁 FatFs核心设计:模块化与可移植性
      • 🛠️ 如何使用FatFs:核心工作流程
      • 🔄 FatFs与其他嵌入式文件系统对比
      • 💡 关键概念与使用要点
      • 📚 学习与移植建议
  • FAT12 / FAT16 / FAT32 含义
    • 一句话理解
    • FAT12 / FAT16 / FAT32 的区别
    • 通俗类比
    • 嵌入式开发关键点
    • 举个场景

官方文档介绍-FatFs

前提知识准备

学习FatFs文件系统是嵌入式开发中高频的技能需求(FatFs是轻量级、可移植的FAT文件系统,广泛用于MCU/单片机场景),其前置知识需围绕嵌入式基础、存储原理、编程核心能力三大维度展开,以下是分层次的必备知识清单,附学习优先级和应用关联:

一、核心编程语言:C语言(优先级★★★★★)

FatFs源码完全由标准C编写,且嵌入式场景下的移植/使用高度依赖C语言核心特性,需掌握:

  1. 基础语法:变量、数据类型(尤其是uint8_t/uint16_t/uint32_t等嵌入式常用类型)、分支/循环、函数定义与调用;
  2. 核心特性:
    • 指针(一级/二级指针):FatFs大量使用指针操作缓冲区、文件目录项、FAT表;
    • 结构体/枚举/联合体:FatFs的核心对象(如FIL文件结构体、DIR目录结构体、FATFS卷结构体、FRESULT错误码枚举)均基于这些类型;
    • 宏定义/条件编译:FatFs的配置文件ffconf.h全靠宏控制功能(如FF_FS_READONLY、FF_FS_MINIMIZE),需理解宏的定义与展开;
    • 函数指针:FatFs底层驱动接口(如disk_ioctl)会用到函数指针实现通用适配;
  3. 内存操作:memcpy/memset/memcmp等内存操作函数(FatFs内部大量用于数据读写/校验),以及嵌入式场景下的静态/动态内存分配(避免堆溢出)。

二、嵌入式系统基础(优先级★★★★★)

FatFs几乎只用于嵌入式场景,需掌握嵌入式开发的核心底层能力:

  1. MCU外设操作:
    • 通信总线:SPI/I2C/SDIO(对接SD卡、SPI Flash)、USB Host(对接U盘)——FatFs的存储介质依赖这些总线驱动;
    • GPIO/定时器:辅助存储介质的硬件初始化(如SD卡的片选引脚、Flash的复位引脚);
  2. 中断与并发:
    • 中断处理基础:文件读写时需避免中断打断关键操作(如SD卡扇区读写),需懂中断屏蔽/恢复;
    • RTOS基础(可选但高频):若在FreeRTOS/RT-Thread等系统中使用FatFs,需掌握互斥锁/信号量(防止多线程同时操作文件导致数据损坏);
  3. 内存管理:
    • 嵌入式内存布局(栈/堆/全局区):FatFs的缓冲区(如文件读写缓存)需合理分配内存;
    • 静态内存分配:嵌入式场景通常禁用malloc/free,需用静态数组替代动态内存(FatFs支持静态配置缓冲区);
  4. 字节序(大小端):FAT文件系统规定数据存储为小端序,MCU若为大端(如部分PowerPC),需掌握字节序转换(FatFs提供BYTE_SWAP宏适配,但需理解原理)。

三、存储介质原理(优先级★★★★)

FatFs需挂载具体的存储介质,必须理解介质的底层读写逻辑:

  1. 核心存储介质特性:
    介质类型关键知识点
    SD卡/MMC卡扇区概念(512字节/扇区,FatFs的最小操作单位)、SDIO/SPI协议、卡初始化流程、扇区读写指令;
    SPI Flash(如W25Q)页/扇区/块的区别(擦除单位是块,读写单位是页)、擦写寿命、SPI Flash的读写/擦除指令;
    U盘(USB Host)USB枚举流程、大容量存储设备(MSC)协议、U盘的扇区读写接口;
    eMMC/NAND Flash坏块管理、ECC校验(FatFs本身不处理坏块,需底层驱动适配);
  2. 通用概念:
    • 块设备(Block Device):FatFs仅支持块设备(按固定大小扇区读写),需区分“字符设备”(如串口)与块设备的差异;
    • 读写时序:存储介质的读写有严格时序要求(如SD卡的CMD指令响应),需理解底层驱动的“等待就绪”逻辑。

四、文件系统基础概念(优先级★★★★)

无需深入FAT协议细节,但需掌握通用文件系统的核心逻辑,理解FatFs的设计目标:

  1. FAT文件系统核心术语:
    • 卷(Volume):一个存储介质(如一张SD卡)对应一个FatFs卷(FATFS结构体);
    • 簇(Cluster):FAT文件系统的最小分配单位(由多个扇区组成),FatFs通过簇管理文件空间;
    • 文件分配表(FAT表):记录簇的使用状态(空闲/已分配/坏簇),是FatFs读写文件的核心依据;
    • 目录项(Directory Entry):存储文件/目录的元信息(名称、大小、起始簇、时间戳);
  2. FAT格式差异:FAT12/FAT16/FAT32的区别(FatFs支持全系列,需知道ffconf.h中FF_FS_FAT32的配置逻辑);
  3. 文件操作通用流程:打开→读写→关闭(FatFs的API完全遵循这一逻辑,如f_open/f_read/f_write/f_close)。

五、底层驱动开发能力(优先级★★★★)

FatFs的核心是“可移植”,其与硬件的解耦依赖底层驱动接口,需掌握:

  1. FatFs底层接口(diskio.c):需实现5个核心函数(FatFs的“硬件抽象层”),必须理解每个函数的作用:
    • disk_initialize:存储介质初始化(如SD卡初始化);
    • disk_status:获取介质状态(就绪/未就绪);
    • disk_read:从扇区读取数据(FatFs读文件的底层依赖);
    • disk_write:向扇区写入数据(FatFs写文件的底层依赖);
    • disk_ioctl:控制指令(如获取扇区数、擦除扇区、同步缓存);
  2. 驱动调试能力:能通过串口打印调试底层读写是否正常(如读取SD卡的MBR主引导记录、FAT表),定位“介质未就绪”“读写失败”等问题。

六、辅助调试与配置能力(优先级★★★)

  1. FatFs配置文件(ffconf.h):理解核心配置项的含义,按需裁剪功能(减少ROM/RAM占用):
    • FF_FS_READONLY:是否只读(仅读场景可开启,节省代码);
    • FF_FS_MINIMIZE:功能裁剪级别(0-3,级别越高功能越少);
    • FF_USE_STRFUNC:是否启用字符串操作(如f_puts/f_gets);
    • FF_VOLUMES:支持的卷数量(如同时挂载SD卡+SPI Flash需设为2);
  2. 错误码解析:FatFs的返回值(FRESULT枚举,如FR_DISK_ERR、FR_NOT_READY、FR_NO_FILE)是调试的核心,需熟记常见错误码的含义;
  3. 编译与链接:嵌入式编译器(Keil/STM32CubeIDE/GCC)的基本使用,能将FatFs源码加入工程,解决链接时的“未定义函数”(通常是底层驱动未实现)。

七、可选但加分的知识(优先级★★)

  1. FAT协议细节:如MBR分区表结构、FAT表的映射规则、长文件名(LFN)的存储方式(FatFs支持长文件名,需理解其编码逻辑);
  2. 低功耗/异常处理:文件读写中断后的恢复逻辑(如掉电前同步文件缓存);
  3. 跨平台移植经验:理解FatFs的“硬件无关层”与“硬件相关层”分离设计,能快速适配不同MCU(如STM32、ESP32、51单片机)。

学习路径建议

  1. 先巩固C语言指针/结构体 + 嵌入式外设驱动(如SD卡SPI驱动);
  2. 理解FAT文件系统的核心概念(扇区/簇/FAT表);
  3. 从ffconf.h最简配置入手(只读、单卷、禁用长文件名),先实现“读取SD卡中某文件”的基础功能;
  4. 逐步开启写功能、长文件名、多卷,结合RTOS实现多线程安全的文件操作。

核心逻辑:FatFs的学习本质是“C语言+嵌入式驱动+文件系统概念”的融合,重点不是背API,而是理解“FatFs如何通过通用接口适配不同存储介质,如何基于FAT协议管理文件”。

一、簇、FAT表、目录项详解

1. 簇 (Cluster) - 存储的基本单位

什么是簇?

比喻:仓库的储物柜

仓库(硬盘) → 储物柜区(簇区) 每个储物柜(簇)有固定大小(如4KB) 即使只存1字节文件,也要占用整个储物柜

实际示例

// 假设簇大小 = 4KB(8个扇区)文件"log.txt"大小=1.2KB 但实际占用空间=4KB(一个整簇) 文件"photo.jpg"大小=15KB 实际占用空间=16KB(4个簇,15/4向上取整)

簇的特点

2. FAT表 (File Allocation Table) - 簇的地图导航

什么是FAT表?

比喻:快递追踪系统

文件 = 一批要配送的货物 每个簇 = 一个配送站点 FAT表 = 配送路线图,告诉你: "当前站点的下一站是哪里?" "货物是否已送达?"

FAT表项的值

0x00000000空闲簇,可以分配0x00000002有效簇号,指向下一簇0x0FFFFFF7坏簇,不可用0x0FFFFFF8-0x0FFFFFFF文件结束标记

文件簇链示例

文件"report.doc"占用簇:5 → 8 → 12 → EOF FAT表内容: 索引 | 值 | 含义 -----|----------|---------------- 5 | 0x00000008 → 去簇8 8 | 0x0000000C → 去簇12 12 | 0x0FFFFFFF → 文件结束 其他 | 0x00000000 → 空闲

FAT表在磁盘上的位置

扇区0-31: 引导区 扇区32-543: FAT1(主表) 扇区544-1055: FAT2(备份表) 扇区1056+: 数据区(簇从这里开始)

3. 目录项 (Directory Entry) - 文件的身份证

什么是目录项?

比喻:图书馆的图书卡片

目录项 = 图书索引卡片 包含:书名(文件名)、位置(簇号)、大小、借阅时间等

目录项的详细结构(32字节)

// 实际内存布局(小端序)字节0-10:DIR_Name[11]// "FILENAMEEXT"(8.3格式)字节11:DIR_Attr// 属性字节字节12-21:保留/时间信息 字节22-23:DIR_FstClusHI// 起始簇高16位字节24-25:DIR_WrtTime// 最后写入时间字节26-27:DIR_WrtDate// 最后写入日期字节28-29:DIR_FstClusLO// 起始簇低16位字节30-33:DIR_FileSize// 文件大小(字节)

属性字节 (DIR_Attr) 详解

位0 (0x01): 只读 → 不能修改 位1 (0x02): 隐藏 → dir命令不显示 位2 (0x04): 系统文件 → 操作系统使用 位3 (0x08): 卷标 → 磁盘标签 位4 (0x10): 子目录 → 这是一个目录 位5 (0x20): 存档 → 已备份/可修改 位6-7: 保留 长文件名条目:属性=0x0F(特殊标记)

目录项示例

文件: "README.TXT" (6KB) 属性: 存档(0x20) 起始簇: 0x0005 (簇5) 大小: 6144字节 十六进制表示: 52 45 41 44 4D 45 20 20 54 58 54 20 00 00 00 00 00 00 00 00 00 00 88 6D 75 54 00 00 05 00 00 00 00 00 18 00 00 00

三者的协同工作流程

场景:读取文件"DATA.BIN"

1. 查找目录项(在目录文件中搜索) - 找到"DATA.BIN"的目录项 - 从中提取:起始簇号=5,文件大小=10240字节 2. 使用FAT表遍历簇链 - 读取簇5 → FAT[5]=8 - 读取簇8 → FAT[8]=12 - 读取簇12 → FAT[12]=0x0FFFFFFF(结束) 3. 读取实际数据 - 簇5物理地址 = 数据区起始 + (5-2)*每簇扇区数 - 读取簇5、8、12的内容

场景:创建新文件

1. 在目录中找空闲目录项(第一个字节=0xE5或0x00) 2. 在FAT表中找空闲簇(FAT项=0x00000000) 3. 填充目录项:文件名、属性、起始簇号、大小等 4. 在FAT表中标记该簇为"已使用"

FatFs中对应的操作

// 打开文件(内部操作)f_open(&fil,"test.txt",FA_READ);// 1. FatFs查找当前目录,找到"test.txt"的目录项// 2. 读取目录项,获取起始簇号和大小// 3. 初始化文件对象的当前位置信息// 读取文件f_read(&fil,buffer,1024,&br);// 1. 根据当前位置计算在哪个簇// 2. 读取该簇的数据// 3. 如果读到簇末尾,查FAT表找下一簇// 4. 更新文件位置指针// 写入文件f_write(&fil,data,512,&bw);// 1. 如果当前簇已满,分配新簇// 2. 更新FAT表,建立簇链// 3. 更新目录项中的文件大小

实际调试示例

假设你想查看文件"CONFIG.CFG"的存储情况:

// 1. 找到目录项(假设在根目录)根目录起始簇=BPB_RootClus(假设=2)读取簇2,搜索"CONFIG CFG"// 2. 解析目录项起始簇号=(DIR_FstClusHI<<16)|DIR_FstClusLO=5文件大小=1500字节// 3. 跟踪FAT链FAT[5]=8// 还有数据FAT[8]=0x0FFFFFFF// 文件结束// 4. 结论:文件占用簇5和簇8簇5:0-4095字节(实际只用前1500字节) 簇8:未使用(因为1500<4096,只用一个簇就够了)// 这里似乎矛盾,说明FAT链有问题或文件大小变了

常见问题

Q: 为什么我的4KB文件显示占用8KB?

A: 可能因为簇大小=8KB,或者文件系统有额外的元数据。

Q: 删除文件后数据还在吗?

A: 还在!删除只是:

  1. 目录项第一个字节改为0xE5(标记删除)
  2. FAT表中相应簇标记为空闲
  3. 实际数据直到被覆盖前都保留

Q: 如何查看文件的真实簇链?

A: 可以使用WinHex等工具,或自己写代码解析FAT。

二、FAT32 磁盘布局

┌─────────────────────────────────────────────────────────────────┐ │ FAT32 磁盘结构 │ ├──────────────┬──────────────┬──────────────┬────────────────────┤ │ 保留区域 │ FAT1 │ FAT2 │ 数据区域 │ │ (包含MBR/DBR) │ (文件分配表)│ (备份FAT) │ (簇区域) │ ├──────────────┼──────────────┼──────────────┼────────────────────┤ │ 扇区0 │ FAT表区域 │ FAT表备份 │ 簇2, 簇3, ... │ │ (引导扇区) │ │ │ (文件/目录数据) │ └──────────────┴──────────────┴──────────────┴────────────────────┘

关键结构详解

1. 引导扇区 (DBR - DOS Boot Record)

位于第 0 扇区,包含文件系统参数:

typedefstruct{uint8_tBS_jmpBoot[3];// 跳转指令uint8_tBS_OEMName[8];// OEM名称uint16_tBPB_BytsPerSec;// 每扇区字节数 (通常512)uint8_tBPB_SecPerClus;// 每簇扇区数uint16_tBPB_RsvdSecCnt;// 保留扇区数 (FAT32通常为32)uint8_tBPB_NumFATs;// FAT表数量 (通常2)uint32_tBPB_FATSz32;// 每个FAT表大小(扇区数)uint32_tBPB_RootClus;// 根目录起始簇号// ... 还有其他字段}FAT32_BPB;

2. FAT 表 (File Allocation Table)

3. 目录项结构 (32字节)

typedefstruct{uint8_tDIR_Name[11];// 8.3文件名 (大写)uint8_tDIR_Attr;// 文件属性uint8_tDIR_NTRes;// NT保留uint8_tDIR_CrtTimeTenth;// 创建时间(10ms)uint16_tDIR_CrtTime;// 创建时间uint16_tDIR_CrtDate;// 创建日期uint16_tDIR_LstAccDate;// 最后访问日期uint16_tDIR_FstClusHI;// 起始簇号高16位uint16_tDIR_WrtTime;// 最后修改时间uint16_tDIR_WrtDate;// 最后修改日期uint16_tDIR_FstClusLO;// 起始簇号低16位uint32_tDIR_FileSize;// 文件大小(字节)}DIR_ENTRY;

文件属性位 (DIR_Attr):

4. 长文件名支持 (LFN)

FAT32 通过特殊目录项存储长文件名:

5. 簇的寻址

6. 文件簇链示例

假设文件占用簇 5、8、10:

FAT表内容: 索引 值(16进制) 含义 ... 5 0x00000008 → 下一簇是8 8 0x0000000A → 下一簇是10 10 0x0FFFFFFF → 文件结束

与 FatFs 的关联

在 FatFs 中,这些概念对应为:

FatFs 内部结构

// FatFs 的 FAT32 结构体typedefstruct{FATFS*fs;// 文件系统对象DWORD sclust;// 起始簇号DWORD clust;// 当前簇号DWORD sect;// 当前扇区UINT index;// 扇区内偏移}FIL;

常用 FatFs 函数与 FAT32 的关系

  1. f_mount()- 读取引导扇区,初始化文件系统信息
  2. f_open()- 查找目录项,获取起始簇号
  3. f_read()/f_write()- 通过 FAT 表遍历簇链
  4. f_lseek()- 计算簇内偏移,可能触发簇链跳转
  5. f_truncate()- 修改 FAT 表释放簇

FAT32 限制

学习建议

  1. 先从 FatFs API 开始:不要一开始就深入二进制格式
  2. 理解关键概念:簇、FAT表、目录项
  3. 使用调试工具:如 WinHex 查看实际磁盘结构
  4. 动手实验:创建小文件,观察 FAT 表和目录项变化

三、实际应用

FatFs(File Allocation Table File System)是一个专为嵌入式系统设计的、兼容FAT格式的开源文件系统模块。它不依赖操作系统,能让你在W25Q128这类存储芯片上实现类似电脑U盘的文件管理。

📁 FatFs核心设计:模块化与可移植性

FatFs采用清晰的分层架构,便于移植到不同硬件:

架构层级组件名称核心职责你需要做什么
应用层用户程序调用FatFs API(如f_open, f_write)编写业务逻辑代码
中间层FatFs核心 (ff.c, ff.h)实现FAT文件系统逻辑(目录、文件读写)通常无需修改
物理层磁盘I/O层 (diskio.c, diskio.h)提供底层存储介质的读写、控制接口重点移植部分,需对接W25Q128驱动

这种设计的精髓在于:你只需实现底层diskio.c中的几个函数(如disk_read,disk_write)来驱动W25Q128,上层的文件操作(创建、读写文件)FatFs都已为你准备好。

🛠️ 如何使用FatFs:核心工作流程

典型的FatFs操作遵循以下流程,这是一个在SD卡或W25Q128上创建并写入文件的简化示例:

// 0. 初始化你的硬件(SPI、GPIO等)spi_init();// 1. 注册工作区(挂载)FATFS fs;// 文件系统对象FRESULT fr=f_mount(&fs,"0:",1);// "0:"对应diskio.c中的驱动器编号// 2. 创建并打开文件FIL fil;fr=f_open(&fil,"0:/log.txt",FA_CREATE_ALWAYS|FA_WRITE);// 3. 写入数据UINT bw;chardata[]="Hello, W25Q128 with FatFs!\n";fr=f_write(&fil,data,sizeof(data)-1,&bw);// 4. 关闭文件并卸载f_close(&fil);f_unmount("0:");

🔄 FatFs与其他嵌入式文件系统对比

了解FatFs的定位有助于你做出选择:

特性对比FatFsLittleFSSPIFFS
主要特点FAT标准兼容,通用性强专为掉电安全和磨损均衡优化专为SPI NOR Flash设计,极度轻量
优点与PC兼容性好,文档丰富,功能全面防掉电损坏,动态磨损均衡内存占用极小,设计简洁
缺点掉电保护较弱,需自行处理均衡代码比FatFs稍复杂非标准格式,社区支持相对少
适用场景需要与PC交换数据、功能要求全面的应用频繁断电或需高可靠性的IoT设备资源极度紧张的小容量SPI Flash

💡 关键概念与使用要点

  1. FAT卷与驱动器号
    FatFs通过“驱动器号”(如0:,1:)来标识不同的物理设备。在你的diskio.c中,需要将这些编号映射到具体的W25Q128芯片实例。

  2. 可裁剪性
    FatFs通过ffconf.h配置文件提供大量选项。你可以根据需求关闭不用的功能(如长文件名、多分区),以节省宝贵的ROM和RAM空间。

  3. 重要:确保底层驱动稳定
    一切文件操作都建立在disk_read/disk_write稳定可靠的基础上。对于W25Q128,你需要特别注意:

📚 学习与移植建议

  1. 官方资源:访问FatFs官网,阅读00readme.txt和doc目录下的文档,这是最权威的信息源。
  2. 移植起点:以官方提供的“diskio.c模板”为起点进行修改,重点关注disk_status、disk_initialize、disk_read、disk_write、disk_ioctl这五个函数。
  3. 调试:先确保底层W25Q128的读写擦除操作绝对可靠,再挂载FatFs。使用f_mkfs创建文件系统是很好的第一步测试。

总结来说,FatFs是连接你的嵌入式应用与W25Q128这类存储芯片的强大桥梁。理解其分层架构和移植关键点,你就能在设备上高效管理文件。

FAT12 / FAT16 / FAT32 含义

一句话理解

FatFs 是嵌入式单片机用的开源C语言文件系统库;这句话意思:只要你的SD卡 / SPI Flash / U盘 格式化成 FAT12、FAT16、FAT32,FatFs 就能识别、读写里面的文件,和Windows电脑互相兼容。

FatFs 本身不是硬件驱动!
它只负责文件逻辑(打开、读写、创建文件、目录);底层读扇区、写扇区需要你自己写底层disk驱动。

FAT12 / FAT16 / FAT32 的区别

名字里的数字 =文件分配表FAT里,簇编号占用多少bit,决定能管理多大存储:

  1. FAT12(12bit)
    • 老式软盘,容量很小,最大约32MB;现在极少用。
  2. FAT16(16bit)
    • 老U盘、小存储卡;分区上限约2GB;单个文件最大2GB。
  3. FAT32(32bit)
    • 最常用!普通SD卡、U盘默认格式;分区最大2TB,单个文件上限4GB(这是FAT32经典限制)。

通俗类比

文件系统 = 仓库的账本:

嵌入式开发关键点

  1. FatFs 自动识别卡是FAT12/FAT16/FAT32,你代码不用手动指定格式;
  2. FatFs新版还可选开启 exFAT(支持大于4GB单文件);
  3. 可以用FatFs的f_mkfs()函数,直接在单片机里把存储介质格式化成FAT12/FAT16/FAT32,不用电脑格式化;
  4. 代码只需要实现底层disk_read、disk_write这两个读写扇区函数,上层f_open、f_write等API直接调用。

举个场景

STM32+SD卡,移植FatFs:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询