在<a href="http://mcu.eetrend.com/content/2021/100556100.html">前面章节</a>中介绍了使用MM32F…,对SD卡识别和简单的数据读写验证,不过像这样直接操作SD卡存储单元,在实际应用中是不现实的。SD卡一般用来存放文件,所以都需要加载文件系统到里面。
FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。完全用标准C语言编写,所以具有良好的硬件平台独立性。可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。它支持FATl2、FATl6和FAT32格式,支持多个存储媒介,具有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。
本章节主要介绍移植FatFs文件系统到SD卡内。
<strong><font color="#004a85">FatFs的特点</font> </strong>
1)Windows兼容的FAT文件系统(支持FAT12/FAT16/FAT32)与平台无关,移植简单;
2)代码量少、效率高;
3)多种配置选项;
4)支持多卷(物理驱动器或分区,最多10个卷);
5)多个ANSI/OEM代码页包括DBCS;
6)支持长文件名、 ANSI/OEM 或Unicode;
7)支持RTOS;
8)支持多种扇区大小;
9)只读、最小化的API和I/O缓冲区等。
<strong><font color="#004a85">FatFs源码获取</font> </strong>
FatFs文件系统的源码可以从FatFs官网下载:
http://elm-chan.org/fsw/ff/00index_e.html
此地址不仅仅包含资料包下载,还包括文件系统一些知识,包括函数说明,函数调用实例等。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231168-1.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
官网有对FatFs做详细的介绍,感兴趣可以多了解一些。所有版本的FatFs源码的移植步骤都是类似的,我们选择选择其中一个版本下载即可。
<strong><font color="#004a85">FatFs文件结构</font> </strong>
解压之后可看到里面有 doc 和src 这两个文件。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231169-2.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
其中doc文件夹里面是一些使用帮助文档,src是FatFs文件系统的源码。
FatFs的源代码主要包含几个文件:
diskio.c、 diskio.h、 ff.c、 ff.h、 integer.h文件。
其中diskio.c 这个文件是文件系统底层和SD驱动的中间接口的实现代码,移植的时候需要改写在diskio.h中声明的那几个函数,代码在ff.c中被调用;diskio.h定义了FatFs用到的宏;ff.c是一般FatFs的代码文件;ff.h是一般FatFs包含的头文件;integer.h是内部基本类型的定义。
option文件夹下是一些可选的外部c文件,包含了多语言支持需要用到的文件和转换函数。
00readme.txt 说明了当前目录下 diskio.c 、 diskio.h、 ff.c、 ff.h、 integer.h 的功能。
<strong><font color="#004a85">FatFs移植步骤</font> </strong>
在工程目录下新建FatFs文件夹,并将src文件夹下的文件复制一份至该文件夹。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231170-3.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231171-4.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
使用KEIL打开工程文件并添加FatFs组件,并将src文件夹下的ff.c、 diskio.c 和 cc936.c 三个文件加入FatFs组件中。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231172-5.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
加入cc936.c文件可以支持简体中文,同时需要把 ffconf.h 中的 _CODE_PAGE 的宏改成 936。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231173-6.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
接着添加FatFs路径到工程选项。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231174-7.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
此时进行编译,会发现提示错误。
<strong><font color="#004a85">编写FatFs接口函数</font> </strong>
来看diskio.c文件,注释前面的几个头文件,这里要加入自己的头文件。下面的三个宏定义ATA、MMC、USB也可以改成想要的名称,可以改成SD并定义为0。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231175-8.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
然后将函数disk_status、disk_initialize、disk_read、disk_write里面执行的代码注释或者删除,这里需要添加自己的代码。由于上面改了宏定义,这里switch-case也要做一些修改。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231176-9.png&…; alt=“”SD卡的FatFs文件管理系统"></center>
更改如下:
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231177-10.png…; alt=“”SD卡的FatFs文件管理系统"></center>
对disk_initialize、disk_read、disk_write几个函数也这样更改。
再次编译,发现提示一个关于get_fattime的错误,get_fattime用来获取当前时间,如果不需要,在ffconf.h中的宏定义#define _FS_NORTC改为1关闭,如果需要这个功能,需要在diskio.c里面,实现get_fattime函数,加入如下代码即可。
<center><img src="http://mcu.eetrend.com/files/2021-12/wen_zhang_/100556274-231178-11.png…; alt=“”SD卡的FatFs文件管理系统"></center>
然后进行编译,这时错误就没有了。
至此我们已经完成FatFs文件管理系统的移植,不过功能还没有实现,需要在disk_status、disk_initialize、disk_read、disk_writ、disk_ioctl函数中加入执行代码:
<strong>设备状态获取</strong>
<pre style="overflow-x:auto; background-color:#e9e9e9;">DSTATUS disk_status (
BYTE pdrv /* Physical drive number to identify the drive */
)
{
DSTATUS stat;
stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
return stat;
}</pre>
<strong>设备初始化</strong>
<pre style="overflow-x:auto; background-color:#e9e9e9;">DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat = RES_OK;
if(disk.is_initialized[pdrv] == 0) {
disk.is_initialized[pdrv] = 1;
stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
}
return stat;
}</pre>
<strong>读取扇区</strong>
<pre style="overflow-x:auto; background-color:#e9e9e9;">DRESULT disk_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 */
)
{
DRESULT res;
res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
return res;
}</pre>
<strong>扇区写入</strong>
<pre style="overflow-x:auto; background-color:#e9e9e9;">DRESULT disk_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 */
)
{
DRESULT res;
res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
return res;
}</pre>
<strong>其他</strong>
<pre style="overflow-x:auto; background-color:#e9e9e9;">DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void* buff /* Buffer to send/receive control data */
)
{
DRESULT res;
res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
return res;
}</pre>
关联的代码不再进行详细描述,可在MindMotion官网下载MM32F3270 lib_Samples:
<a href="https://www.mindmotion.com.cn/products/mm32mcu/mm32f/mm32f_mainstream/m…;
工程路径如下:
~\MM32F3270_Lib_Samples_V0.90\Demo_app\PlayWave_Demo\SPI_I2S_SDIO_FatFs
可以看到详细的样例与功能操作。
来源:<a href="https://mp.weixin.qq.com/s/zaE68WzNNoTeP6ev8pjztg">灵动MM32MCU</a>
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。