一、环境介绍
主控MCU: STM32F103ZET6
STM32程序开发IDE: keil5
STM32程序风格: 采用寄存器方式开发,注释齐全,执行效率高,方便移植
硬件包含: 一块STM32F103ZET6系统板、一个SPI接口的SD卡卡槽模块、一张SD卡
工程完整源码下载地址: https://download.csdn.net/download/xiaolong1126626497/19687693
这篇文章主要演示FATFS文件系统如何移植到自己的工程,并完成文件的读写。
因为SD卡采用的是SPI模拟时序,所以,其他单片机一样可以照着移植,代码都可以复制粘贴的。
二、FATFS文件系统介绍
2.1 FATFS简介
FatFs 是一种完全免费开源的 FAT 文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C 语言编写,所以具有良好的硬件平台独立性,可以移植到 8051、 PIC、 AVR、 SH、 Z80、 H8、 ARM 等系列单片机上而只需做简单的修改。它支持 FATl2、 FATl6 和 FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对 8 位单片机和 16 位单片机做了优化。
2.2 特点
Windows兼容的FAT文件系统
不依赖于平台,易于移植
代码和工作区占用空间非常小
多种配置选项
多卷(物理驱动器和分区)
多ANSI/OEM代码页,包括DBCS
在ANSI/OEM或Unicode中长文件名的支持
RTOS的支持
多扇区大小的支持
只读,最少API,I/O缓冲区等等
2.3 移植性
fatfs模块是ANSI C(C89)编写的。 没有平台的依赖, 编译器只要符合ANSI C标准就可以编译。
fatf模块假设大小的字符/短/长8/16/32位和int是16或32位。 这些数据类型在integer.h文件中定义。这些数据类型在大多数的编译器中定义都符合要求。 如果现有的定义与编译器有任何冲突发生时,需要自己解决。
2.4 源码下载
下载地址:http://elm-chan.org/fsw/ff/00index_e.html

FATFS有两个版本,一个大版本,一个小版本。小版本主要用于8位机(内存小)使用。
下载图:

2.5 FATFS源码文件介绍
将下载的源码解压后可以得到两个文件夹: doc 和 src。 doc 里面主要是对 FATFS 的介绍(离线文档—英文和日文),而 src 里面才是我们需要的源码。
其中,与平台无关的是:
ffconf.h FATFS配置文件
ff.h 应用层头文件
ff.c 应用层源文件
diskio.h 硬件层头文件
interger.h 数据类型定义头文件
option 可选的外部功能(比如支持中文等)
与平台相关的代码:
diskio.c 底层接口文件(需要用户提供)
FATFS 模块在移植的时候,我们一般只需要修改 2 个文件,即 ffconf.h 和 diskio.c。
FATFS模块的所有配置项都是存放在 ffconf.h 里面,我们可以通过配置里面的一些选项,来满足自己的需求。
FATFS最顶层是应用层,使用者无需理会 FATFS 的内部结构和复杂的 FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如 f_open, f_read, f_write 和 f_close 等,就可以像在 PC 上读/写文件那样简单。
中间层 FATFS 模块, 实现了 FAT 文件读/写协议。 FATFS 模块提供的是 ff.c 和 ff.h。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。
需要我们编写移植代码的是 FATFS 模块提供的底层接口,它包括存储媒介读/写接口 ( disk、I/O) 和供给文件创建修改时间的实时时钟。
三、 移植FATFS文件系统
移植之前,首先得准备一个能正常编译的工程,并且工程里有SD卡的驱动代码,提供了读写扇区这些函数才能进行FATFS文件系统的正常移植。
关于如何编写SD卡驱动,SD卡的时序介绍、命令介绍等知识点下篇文章再讲解。这篇文章重点是FATFS文件系统的移植过程。
3.1 新建工程
FATFS文件系统源码下载下来,解压之后,移植修改的步骤如下:
打开KEIL工程,添加FATFS文件源码:

加入.h文件主要是方便配。cc936.c 用于支持中文。
3.2 修改diskio.c文件

注释掉现在不需要的用到的文件,因为我们现在用的是SD卡,与USB,ATA,MMC卡没关系。
并加入一个新的宏 :
#define SD 0
定义SD卡的物理驱动器号为0。
修改 disk_status函数,该函数主要是用来获取磁盘状态。现在未用到,可以直接函数体内代码删除。
修改截图:

代码示例:
#include "diskio.h" /* fatf底层API */
#include "sd.h" /* SD卡驱动头文件 */
/* 定义每个驱动器的物理驱动器号*/
#define SD 0
/*-----------------------------------------------------------------------*/
/* 获取设备(磁盘)状态 */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* 物理驱动识别 */
)
{
return 0; //该函数现在无需用到,直接返回0
}
修改disk_initialize函数,添加SD卡的初始化,其他不用到的代码直接删掉,该函数成功返回0,失败返回1。
修改截图:

代码示例:
/*-----------------------------------------------------------------------*/
/* 初始化磁盘驱动 */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* 物理驱动识别 */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case SD : //选择SD卡
stat=SD_Init(); //初始化SD卡-用户自己提供
}
if(stat)return STA_NOINIT; //磁盘未初始化
return 0; //初始化成功
}
修改disk_read函数,加入SD卡读任意扇区的函数(需要用户自己提供),其他不用到的选项可以删掉。

修改代码如下:
/*-----------------------------------------------------------------------*/
/* 读扇区 */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* 物理驱动编号 - 范围0-9*/
BYTE *buff, /* 数据缓冲区存储读取数据 */
DWORD sector, /* 扇区地址*/
UINT count /* 需要读取的扇区数*/
)
{
DRESULT res;
int result;
switch (pdrv) {
case SD:
res=SD_Read_Data((u8*)buff,sector,count); //读SD扇区函数--用户提供
return res; //在此处可以判错误
}
return RES_PARERR; //无效参数
}
修改disk_write 函数,添加写扇区函数:

代码:
/*-----------------------------------------------------------------------*/
/* 写扇区 */
/*-----------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
BYTE pdrv, /* 物理驱动号*/
const BYTE *buff, /* 要写入数据的首地址 */
DWORD sector, /* 扇区地址 */
UINT count /* 扇区数量*/
)
{
DRESULT res;
int result;
switch (pdrv) {
case SD:
res=SD_Write_Data((u8*)buff,sector,count); //写入扇区
return res;
}
return RES_PARERR; //无效参数
}
#endif
修改disk_ioctl 函数,填充ioctl命令功能。这些功能是标准的命令,在diskio.h有定义。
代码如下:

/*-----------------------------------------------------------------------*/
/* 其他函数 */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL
DRESULT disk_ioctl (
BYTE pdrv, /* 物理驱动号 */
BYTE cmd, /* 控制码 */
void *buff /* 发送/接收数据缓冲区地址 */
)
{
DRESULT res;
int result;
switch (pdrv) {
case SD:
switch(cmd)
{
case CTRL_SYNC: //等待写过程
SD_CS(0); //选中SD卡
if(SD_Wait_Ready())result = RES_ERROR;/*等待卡准备好*/
else res = RES_OK; //成功
SD_CS(1); //释放SD卡
break;
case GET_SECTOR_SIZE://获取扇区大小
*(DWORD*)buff = 512;
res = RES_OK; //成功
break;
case GET_BLOCK_SIZE: //获取块大小
*(WORD*)buff = 8; //块大小(扇区为单位),一块等于8个扇区
res = RES_OK;
break;
上一篇:基于STM32完成FATFS文件系统移植与运用
下一篇:基于STM32设计的小说阅读器(翻页、字体切换、颜色切换、语音播报)
推荐阅读
史海拾趣
随着通信行业的快速发展,康普公司意识到光纤光缆在有线电视行业的重要性。因此,在1977年,康普公司合并了Valtec公司,一个独立的光纤技术领导者。这次合并不仅增强了康普在光纤技术方面的实力,也为其日后的全球化布局打下了坚实的基础。随后,康普通过一系列的战略合作和收购,逐渐在全球范围内建立了供应链和生产基地,为全球客户提供高效、可靠的通讯网络解决方案。
尽管睿赫公司在电子行业中取得了显著的成就,但公司也面临着诸多挑战。随着技术的不断进步和市场的不断变化,公司需要不断创新和进步,才能保持领先地位。
面对未来,睿赫公司将继续秉承“创新、卓越、诚信、共赢”的企业精神,不断加强技术研发和人才培养,推动公司的持续发展和壮大。同时,公司还将积极关注市场动态和客户需求,不断推出符合市场需求的新产品,为客户提供更加优质的服务和解决方案。
随着国内市场的逐渐饱和,eLED.com Corp开始将目光投向国际市场。公司积极参与各类国际展会,向全球客户展示其优质的产品和技术。同时,eLED.com Corp还与国际知名企业开展合作,共同研发新技术,推动LED行业的发展。通过与国际巨头的合作,eLED.com Corp不仅提升了自身的技术水平,还拓展了国际市场,实现了品牌的全球化布局。
随着5G技术的快速发展,电子行业迎来了新的变革。AntennaHome公司面临着来自行业内外的巨大挑战。为了应对这一变革,公司加大了对5G天线技术的研发力度,同时积极调整产品结构和市场策略。经过一段时间的努力,公司成功推出了多款适应5G时代需求的新型天线产品,为公司的持续发展奠定了坚实的基础。
作为一家专注于电气元件和连接器制造的公司,Amphenol Nexus Technologies始终致力于技术创新和产品升级。公司投入大量资源用于研发,不断推出具有创新性和高性能的新产品。例如,在高速连接器领域,Amphenol Nexus Technologies成功研发出了112G高速背板连接器,这一产品满足了人工智能等前沿技术对高速传输的需求,为公司带来了新的增长点。
Amphenol Nexus Technologies深知,在电子行业中,合作与共赢是实现持续发展的重要途径。因此,公司积极与产业链上下游的合作伙伴建立紧密的合作关系,共同推动行业的发展。通过与供应商、客户以及同行业企业的合作,Amphenol Nexus Technologies不断提升自身的竞争力,实现了业务的快速增长和市场的持续扩张。
以上便是关于Amphenol Nexus公司在电子行业发展的五个故事。这些故事展示了公司在不同历史阶段的发展轨迹、领导层的智慧和决策、技术创新的努力以及合作共赢的理念。正是这些因素的共同作用,使得Amphenol Nexus Technologies能够在激烈的市场竞争中脱颖而出,成为电子连接器行业的佼佼者。
|
问ad9833能产生方波吗?看了它的控制寄存器功能表,好像不能直接产生方波啊,而且框图里面也没有比较器嘛,但看关于它的主要特点,都说可以直接产生正弦、三角、方波三种波形 恳请赐教… 查看全部问答∨ |
|
|
搞到了一个份能在EVC下运行的 pocketpc GIS的程序 程序都能运行 只是 随程序提供了一个map文件夹 里面放了一些 .dbf .shp和.shx的文件,应该是一些地图图片信息和相关的地理数据信息。程序运行时 需要加载上述的图片,我是在模拟器中运 ...… 查看全部问答∨ |
|
|
tlc555频率测量时,如果选取C=180PF,要求输出为20KHZ左右,匹配R1,R2时该注意什么,为什么我选取R1=18K,R2=110K,按照如下公式计算: 上升时间 (T1) = 0.693 * (R1+R2) * C 下降时间(T2) = 0.693 * R2 * C 頻率 = 1.44 / ( (R1+R2+R2) * C) ...… 查看全部问答∨ |
请问各位大侠,在WinCE中调用windows media player 时,能不能隐藏它自带的下面的一排按钮. 我在WinCE+VS2005调用Windows media player,定制它的界面,请问可以实现吗? … 查看全部问答∨ |
|
我调试wince的时候使用ActiveSync进行连接 有时候调试到一般,连接突然中断,但是电脑右下脚的小图标仍然是绿色,这个时候我一拔出USB电缆,电脑就会死机 这个问题困扰了我很久 希望有人能帮我解决,谢谢!… 查看全部问答∨ |
H3C公司2003年11月成立,最初由华为和3COM合资组建,2006年11月由3COM公司全资收购。 目前公司正在全力投入高端路由器产品的开发,急需大量软件开发、测试人员。 地点:杭州 职责: 1、负责H3C高端路由器产品软件开发工作,完成相关的设计文档、 ...… 查看全部问答∨ |
|
各位好!我现在用一台PC没有与其他PC连网,只使用它来开发,用ACTIVESYNC与WINCE设备相连,在模拟器中可以与SQLSERVER相连,可是部署到设备上时,提示找不到SQLSERVER,请问谁遇到过,帮忙解决一下,多谢!… 查看全部问答∨ |
- 有奖直播|是德科技感恩月—遇见KeysightCare - 贵重仪器安全避坑指南
- 【EE团】ST最新STM32F429i高性能开发板重磅登场
- ADI有奖直播:基准电压源产品技术及应用选择 7月25日上午10:00-11:30 不容错过~
- 直播已结束【解锁 TI Sitara AM2x MCU 在电机驱动中的新可能】
- 英特尔 SoC FPGA 开发者论坛 (ISDF) 预约报名享好礼!
- Intel最新物联网解决方案,抢先阅读,下载有惊喜
- 答题有礼|一起学习 Mentor PCB 手册
- 有奖直播:TI毫米波雷达在汽车车内的应用
- 罗姆有奖直播|可应用于LiDAR的激光二极管及周边电源推荐
- 绝地求生,集齐4样必然吃鸡!览TI汽车技术方案 赢小礼品









XC6406PP60DL






京公网安备 11010802033920号