在STM32中移植FATFS文件系统

合集下载

STM32+SDIO+FATFS文件系统直读SD卡

STM32+SDIO+FATFS文件系统直读SD卡

STM32+SDIO+FATFS文件系统直读SD卡STM32+SDIO+FATFS文件系统直读SD卡网上关于小型嵌入式的文件系统有好多~当然要数FATFS 很是出名一来小巧,二来免费。

当然了国产的振南的znFAT 一样开源好用而且极其的省资源~!非常适合51单片。

更重要的是国语的支持,呵呵!这次在STM32上为SD卡移植文件系统还是非常简单顺利的,这多亏了ST 官方提供的驱动,而我自己不用动手编写SD卡的命令省了很多时间而且官方做的驱动虽然效率一般但是极其严谨我很是佩服。

FATFS的官方网站是znFAT的官方网站是SD卡可以用SPI驱动也可以直接用SDIO 驱动STM32 256KB FLASH 以上的片子全部都有SDIO,我们当然要用高速快捷的SDIO 方式了!至于 SDIO 又有 1位 4位 8 位的之分我想不来8位SDIO 是怎么回事?SD卡上最多只能接4位嘛~网上有人说4位的SDIO 不好用多半是固件版本太老的缘故了。

呵呵这里还是要靠库~STM32真适合懒人用。

网上关于的FATFS 的文章很多不过都太老旧,很多东西已经不适用了。

我建议阁下到官方去下载最新的版本目前是最新是R0.08b,使用最新的版本好处是很多网上很多要改来改去的地方只要你使用了新版本那就是完全可以规避的。

另外STM32 的SDIO驱动也一定要用最新的,老版本问题很多不少人的失败就在这。

我这次用的是V3.3的库没有任何改动就可以了,现在最新的好像在3.4以上了。

好了说说移植ffconf.h是配置的头文件简单的修改宏就可以了,英文注释的很完全而且网上也有翻译我不多说了自己看主要在这里进行功能裁剪写写我的配置。

#define _FS_TINY 0 /* 0:Normal or 1:Tiny 完整的FATFS 精简版的是Tiny */#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only 能读能写*/#define _FS_MINIMIZE 1 /* 0 to 3 简单的裁剪f_mkdir, f_chmod..这些功能没法用的*//* The _FS_MINIMIZE option defines minimization level to remove some functions.// 0: Full function./ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename/ are removed./ 2: f_opendir and f_readdir are removed in addition to 1./ 3: f_lseek is removed in addition to 2. */#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable是否使用字符串文件接口 *//* To enable string functions, set _USE_STRFUNC to 1 or 2. */#define _USE_MKFS 0 /* 0:Disable or 1:Enable 制作文件系统我在PC上一般已经格式化好了*//* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */#define _USE_FORWARD 0 /* 0:Disable or 1:Enable 发文件流?*//* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable 搜索*//* To enable fast seek feature, set _USE_FASTSEEK to 1. */#define _CODE_PAGE 1 / /1 - ASCII only (Valid for non LFN cfg.)#define _USE_LFN 0 /* 0 to 3 */#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) 这些都是长文件名或是汉字文件支持很费资源所以不开启这些*/#define _FS_SHARE 0 /* 0:Disable or >=1:Enable 不使用相对路径*/#define _FS_SHARE 0 /* 0:Disable or >=1:Enable 文件共享多任务的操作系统会用到的*/#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable 这些是啥用?同步什么呢?默认就好了*/#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */integer.h主要定义了文件的类型若是最新的可以不用修改。

STM32F407移植FATFS文件系统(版本R0.09b)到SD卡(硬件SPI总线)

STM32F407移植FATFS文件系统(版本R0.09b)到SD卡(硬件SPI总线)

STM32F407移植FATFS⽂件系统(版本R0.09b)到SD卡(硬件SPI总线)⼀、序⾔经常在⽹上、群⾥看到很多⼈问关于STM32的FATFS⽂件系统移植的问题,刚好⾃⼰最近的⼯程项⽬需要使⽤SD卡,为了让⼤家少⾛弯路,我把我的学习过程和⽅法贡献给⼤家。

⼆、SD卡简介安全数字卡(简称SD卡),最初引进应⽤于⼿持式可携带电⼦产品,在⼀个⼩尺⼨产品上可靠的存储数据,如移动电话,数码相机等。

1、SD卡简介请参考如下博⽂2、SD卡种类请参考如下博⽂3、SD卡简介和种类请参考如下博⽂4、MMC、SD、TF、SDIO、SDMMC简介三、SD卡总线协议简介SD卡⽀持2种总线协议,即SDIO总线协议和SPI总线协议。

SDIO总线协议速度快,SPI总线相对SDIO总线速度要慢很多,但是⽬前市⾯上很多单⽚机不⽀持SDIO总线协议,只有中⾼端单⽚机(例如:STM32F407)才⽀持SDIO总线协议。

1、SDIO总线协议利⽤该总线协议,可以使⽤最多四条数据线实现主机与SD卡之间的数据传输,所以速度相对⽽⾔可以达到最⾼,但是需要主机具有SDIO控制器,才可以使⽤该协议。

2、SPI总线协议如果主机不⽀持SDIO协议,那么可以使⽤SPI协议对SD卡进⾏操作。

虽然速度⽐SDIO慢,但是硬件上更加简单,只需要四根线便可以实现与SD卡进⾏通讯。

3、SDIO协议与SPI协议的⽐较SDIO协议与SPI协议相较⽽⾔,SDIO协议读写SD卡的速度更快,再加上其⽀持4线模式,即利⽤4条数据线,同时发送4Bits数据,数据的传输效率就更⾼了,但是由于使⽤的引脚较多,所以也导致了控制相对⽐较困难。

⽽SPI外设只具有两条数据线MISO和MOSI,分别⽤作数据的输⼊和输出,由于引脚较少,所以控制相对较容易。

但是,数据的传输效率相对⽽⾔就⽐较低了。

但是,两中协议的共同之处在于:均是通过命令实现对SD卡的控制,仍然是结合状态机实现编程。

4、SD卡如何⼯作在SPI模式下当SD卡上电之后,只有第⼀次发送的CMD0命令才可以选择SD卡⼯作在SPI模式下。

stm32sdiofatfs文件系统源码分析

stm32sdiofatfs文件系统源码分析

、概述1、目的在移植之前,先将源代码大概的阅读一遍,主要是了解文件系统的结构、各个函数的功能和接口、与移植相关的代码等等。

2、准备工作在官方网站下载了0.07c 版本的源代码,利用记事本进行阅读。

二、源代码的结构1、源代码组成源代码压缩包解压后,共两个文件夹,doc是说明,src里就是代码。

src文件夹里共五个文件和一个文件夹。

文件夹是option,还有OOreadme.txt、diskio.c、diskio.h、ff.c、ff.h、integer.h。

对比网上的文章,版本已经不同了,已经没有所谓的tff.c 和tff.h 了,估计现在都采用条件编译解决这个问题了,当然文件更少,可能编译选项可能越复杂。

2、00readme.txt 的说明Low level disk I/O module is not included in this archive because the FatFsmodule is only a generic file system layer and not depend on any specificstorage device. You have to provide a low level disk I/O module that writtento control your storage device .主要是说不包含底层10代码,这是个通用文件系统可以在各种介质上使用。

我们移植时针对具体存储设备提供底层代码。

接下来做了版权声明-可以自由使用和传播。

然后对版本的变迁做了说明。

3、源代码阅读次序先读integer.h,了解所用的数据类型,然后是ff.h, 了解文件系统所用的数据结构和各种函数声明,然后是diskio.h,了解与介质相关的数据结构和操作函数。

再把ff.c和diskio.c两个文件所实现的函数大致扫描一遍。

最后根据用户应用层程序调用函数的次序仔细阅读相关代码。

为STM32移植FATFS读取SD卡上FAT121632文件系统

为STM32移植FATFS读取SD卡上FAT121632文件系统

给stm32移植fatfs文件系统,今天终于取得阶段性胜利。

只需要提供这样几个函数即可[plain]view plaincopyprint?1.DSTATUS disk_initialize (BYTE);2.DSTATUS disk_status (BYTE);3.DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);4.DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); // 如果实现只读的文件系统就不需要了。

5.DRESULT disk_ioctl (BYTE, BYTE, void*);移植成功后,可以用如下方式读取SD卡了,实在太方便了,和PC机上编程差不了多少。

[csharp]view plaincopyprint?1.unsigned int i;2. BYTE buffer[512]; // file copy buffer3. FATFS fs; // Work area (file system object) for logical drive4. FIL fsrc; // file objects5. FRESULT res; // FatFs function common result code6. UINT br; // File R/W count7. USART1_Puts("Now, I'll read file 'i2c/uart.lst'.\n");8.9.// Register a work area for logical drive 010. f_mount(0, &fs);11.12.// Open source file13. res = f_open(&fsrc, "i2c/uart.lst", FA_OPEN_EXISTING | FA_READ);14.if (res)15. {16. USART1_Puts("Can't open i2c/uart.lst for read. :-(\n");17.goto exit;18. }19.20.for (;;) {21. res = f_read(&fsrc, buffer, sizeof(buffer), &br);22.if (res || br == 0) break; // error or eof23.for( i = 0; i < br; ++i )24. USART1_Putc(buffer[i]);25. }26.27. f_close(&fsrc);28.xit:29.// Unregister a work area before discard it30. f_mount(0, NULL);。

STM32笔记(六)SD卡的读写和FatFS文件系统

STM32笔记(六)SD卡的读写和FatFS文件系统

STM32笔记(六)SD卡的读写和FatFS文件系统因为要用,学习了一下SPI操作SD卡,同时移植了一个免费开源的FAT文件系统:FatFS。

感觉挺好,在单片机上实现了读写文件的操作,接下来就可以解释我的G代码咯!我的SD卡底层操作参考了网上几种常见的代码,但又对其结构做了一定的优化,至少看起来用起来比较方便。

既可以作为文件系统的diskio使用,也可以直接使用底层函数,把SD卡作为一块flash读写。

FatFs文件系统体积蛮小,6-7K足矣,对于128Kflash的STM32来说很合适,代价不大。

同时可移植性很高,最少只需要4个函数修改既可以实现文件系统的移植。

相关文件系统的介绍请看这里。

这里给一套比较完整的参考资料,包括fatfs文件系统的原版资料、几个重要的手册和网上下载的代码。

/bbs/bbs_content.jsp?bbs_sn=3210864&bbs_page_no=1&bbs_id=3020 下面是我的代码:其中底层的SPI总线对SD卡的操作在SPI_SD_driver.c/h中,而FATFS的移植文件diskio.c中对磁盘的操作函数中将调用底层的操作函数。

下面是一些底层操作函数:u8 SPI_ReadWriteByte(u8 TxData); //SPI总线读写一个字节u8 SD_WaitReady(void); //等待SD卡就绪u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令,不断线u8 SD_Init(void); //SD卡初始化u8 SD_ReceiveData(u8 *data, u16 len, u8 release); //SD卡读数据u8 SD_GetCID(u8 *cid_data); //读SD卡CIDu8 SD_GetCSD(u8 *csd_data); //读SD卡CSDu32 SD_GetCapacity(void); //取SD卡容量u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sectoru8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sectoru8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sectoru8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count); //写多个sector这是diskio.c中的一段代码,在disk初始化中,我们调用了SPI_SD_driver.c中的SD卡初始化函数。

STM32F429利用CUBEMX移植FATFS文件系统成功!!!

STM32F429利用CUBEMX移植FATFS文件系统成功!!!

STM32F429利⽤CUBEMX移植FATFS⽂件系统成功⽂件系统对于⼀个专业的嵌⼊式系统⽽⾔必不可少,博主这两天利⽤STM32F429成功移植了FATFS,特来分享⼀下学习⼼得,避免新⼈采坑。

我是在SD卡上实现的,因此你需要利⽤SDIO接⼝扩展⼀个SD卡,具体实现如下:进⼊Configuration界⾯,基本参数的不⽤配置,但是需要开启中断和DMA,配置如下:点击OK,关闭Configuration窗⼝。

在MiddleWares下拉列表中打开FATFS,选中SD卡。

进⼊FATFS的Configuration界⾯,配置如下:解释⼀下改动的两个参数,⼀个选择读取中⽂类型的⽂件,另⼀个是使能长字节名称命名(如果不选择,只有8字节,超过8字节会出现Hardware Fault),⽂件系统的磁盘选择3个(⽅便挂载其他内存)最后,再设置选择中,把stack的空间⼤⼩设置为0X1000⼤⼩。

以上,便完成可在CUBEMX中配置FATFS⽂件系统,点击⽣成⼯程⽂件。

可以看到,在⼯程⽬录下,⽣成了这样⼀些⽂件:具体什么内容先不管,我们需要在main中添加⼀些代码测试我们的⽂件管理系统。

⾸先添加如下所⽰的全局变量:/* USER CODE BEGIN PV *//* Private variables ---------------------------------------------------------*/uint32_t byteswritten; /* File write counts */uint32_t bytesread; /* File read counts */uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */uint8_t rtext[100]; /* File read buffers */char filename[] = "STM32cube.txt";/* USER CODE END PV */在初始化之后,while(1)之前添加如下代码int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_TIM6_Init();MX_FMC_Init();MX_USART1_UART_Init();MX_TIM7_Init();MX_USART3_UART_Init();MX_DMA2D_Init();MX_LTDC_Init();MX_SPI5_Init();MX_SDIO_SD_Init();MX_FATFS_Init();/* Initialize interrupts */MX_NVIC_Init();/* USER CODE BEGIN 2 */delay_init(180);LED_Init();KEY_Init();SDRAM_Init();LCD_Init();ESP8266_Init(); //WIFI ͨѶģ¿éW25QXX_Init(); //Íⲿ SPI FLASH --- 32MBFTL_Init(); //Íⲿ NAND FLASH --- 512MBmy_mem_init(SRAMIN); //½«SRAMÖÐ60KBÄÚ´æÓÃÓÚÄÚ´æ¹ÜÀíϵͳ my_mem_init(SRAMEX); //½«SDRAMÖÐ15MBÄÚ´æÓÃÓÚÄÚ´æ¹ÜÀíϵͳ ITEnable();PeriphInit();GUI_Init();Show_SDcard_Info();LCD_ShowString(400,400,400,24,24,"****** FatFs Example ******");retSD = f_mount(&SDFatFS, "0:", 0);if(retSD){LCD_ShowString(400,440,400,24,24,"****** mount error ******");LCD_ShowNum(800,440,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,440,400,24,24,"****** mount success ******");retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE);if(retSD){LCD_ShowString(400,480,400,24,24,"****** open file error ******");LCD_ShowNum(800,480,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,480,400,24,24,"****** open file success ******");retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten);if(retSD){LCD_ShowString(400,520,400,24,24,"****** write file error ******");LCD_ShowNum(800,520,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,520,400,24,24,"****** write file success ******");retSD = f_close(&SDFile);if(retSD){LCD_ShowString(400,560,400,24,24,"****** close file error ******");LCD_ShowNum(800,560,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,560,400,24,24,"****** close file success ******");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}OK,编译通过,下载程序,运⾏结果如下所⽰:之后你便可以在SD卡中找到你创建的⽂件STM32cube.txt。

基于STM32的FATFS文件系统移植

基于STM32的FATFS文件系统移植

基于STM32的FATFS文件系统移植经过将近1个月的时间,终于完成了STM32是FATFS文件系统移植,说来是够艰辛的,SDIO章节是我学习cortex m3以来消耗时间最多的章节。

这里说一些个人对于SDIO的看法,其实SDIO属于意法半导体公司在cortex m3内核之外(在芯片之内)添加的功能外设,完全属于意法的杰作了。

关于SD卡的读写,分为SPI模式和SD模式(专用模式),这两种模式都必须遵循SD2.0协议。

SPI模式控制方法相对较为简单,操作简洁,但失去了速度;SD模式控制方法相对较为复杂一点,操作繁琐,但具有高速的特点。

FATFS文件系统是一种兼容性比较高的文件管理系统,兼容FAT32、FAT16。

关于文件系统的细节,如果认真研究的话,应该会觉得作者的伟大,惊叹代码的绝妙。

我们要想移植FATFS,首先要做的是编写基于SDIO模式的SD卡底层驱动,这部份完整的驱动代码较多,大概有2000多行,但我们首先需要克服心理作用,再长的代码只要理解之后,都很简单。

意法在参考手册中介绍SDIO时,上下文比较乱,其中还夹杂讲解了一些SD2.0协议,使得初学者云里雾里。

因为SDIO是属于一种完全的外设接口,所以在讲解的过程中必须与实际的外设SD卡联系起来。

STM32的SDIO接口兼容性很高,可以兼容SD1.0卡、2.0卡、MMC 卡、多媒体卡等,与多媒体卡4.2支持三种不同的数据总线模式:1位、4位和8位,在8位的模式下速度可以达到48MHZ,但在SD2.0协议中只支持两种总数总线模式:1位和4位,在SDIO中存在两种状态机:命令状态机(CPSM)和数据状态机(DPSM),两者的使能信号独立,用于控制外部双向驱动器,命令是通过CMD命令线单线串行发送的,而数据是由于DATx数据线传输(1位或4位),每当CPSM发送一条命令给卡时,如工作正常的话,卡都会有与CPSM中设置响应格式相对应的响应内容(短响应与长响应),两者的细节在下面讲到。

STM32之FATFS文件系统(SPI方式)笔记

STM32之FATFS文件系统(SPI方式)笔记

STM32之FATFS文件系统(SPI方式)笔记BY:T7Date:20171202At:YSU_B307开发环境:uVision: V5.12.0.0STM32F103V8T6库版本: STM32F10x_StdPeriph_Lib_V3.5.0FATSF : ff13a工程版本:FATFS_V1日期:硬件连接:SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA7工程功能:建立在SPI_SD的基础上,完成文件系统的初步接触。

一、FATFS文件系统1.使用开源的FAT文件系统模块,其源代码的获取从官网:目前最新版本是:ff13a2.解压后得到两个文件:其中,documents相当于STM32的固件库使用手册,介绍FATFS系统的函数使用方法,source 中则是需要用到的源代码。

因为FATFS使用SD卡,所以FATFS的基础是SD卡的正常读写,这里采用SPI模式。

二、STM32之SD卡_SPI模式1.硬件连接:SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA72.SPI模式下STM32读写SD卡的工程结构在确定STM32使用SPI模式读写SD卡没有问题后,进入FATSF文件系统的实验,另源代码在文档最后。

三、FATSF文件系统移植1.配置工程环境1)STM32读写SD卡-SPI模式成功2)将解压后的ff13a整个文件夹赋值到工程目录下,如图:3)返回到MDK界面下,添加ff13a项目组,并把ff13a\source\目录下ff.c,diskio.c,ffunicode.c,ffsystem.c添加到项目组中,如下图:4)在Target Options的C++编译器选项中添加文件包含路径,如下图四、为FATSF文件系统添加底层驱动(一)在diskio.c中添加函数代码1.DSTATUS disk_status (BYTE pdrv); 添加完成后如下图2.DSTATUS disk_initialize (BYTE pdrv); 添加完成后如下图3.DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);4.DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);5.DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);6.DWORD get_fattime (void);注意:在diskio.c中DEV_MMC的宏定义要为0,如下图(二)打开Ffconf.h函数1.改变FF_CODE_PAGE的值如下2.改变FF_USE_LFN的值如下五、Main主函数Main.c函数如下代码:#include "main.h"#define ONE_BLOCK 512#define TWO_BLOCK 1024uint8_t sd_RxBuf[TWO_BLOCK];//SD卡数据j接收缓存区uint8_t sd_TxBuf[TWO_BLOCK] = {0};//SD卡数据j接收缓存区FRESULT res;//读写文件的返回值FIL ;//文件系统结构体,包含文件指针等成员UINT br,bw;//Fil R/W countBYTE [ONE_BLOCK];// BUFFER//BYTE Tx[] = "This is the FATFS System!\r\n";BYTE Tx[] = "中文文件系统实验!\r\n";static const char * FR_Table[]={"FR_OK:成功", /* (0) Succeeded */"FR_DISK_ERR:底层硬件错误", /* (1) A hard error occurred in the low level disk I/O layer */"FR_INT_ERR:断言失败", /* (2) Assertion failed */"FR_NOT_READY:物理驱动没有工作", /* (3) The physicaldrive cannot work */"FR_NO_FILE:文件不存在", /* (4) Could not find the file */"FR_NO_PATH:路径不存在", /* (5) Could not find the path */"FR_INVALID_NAME:无效文件名", /* (6) The path name format is invalid */"FR_DENIED:由于禁止访问或者目录已满访问被拒绝", /* (7) Access denied due to prohibited access or directory full */"FR_EXIST:由于访问被禁止访问被拒绝", /* (8) Access denied due to prohibited access */"FR_INVALID_OBJECT:文件或者目录对象无效", /* (9) The object is invalid */"FR_WRITE_PROTECTED:物理驱动被写保护", /* (10) The physical drive is write protected */"FR_INVALID_DRIVE:逻辑驱动号无效", /* (11) The logical drive number is invalid */"FR_NOT_ENABLED:卷中无工作区", /* (12) The volume has no work area */"FR_NO_:没有有效的FAT卷", /* (13) There is no valid FAT volume */"FR_MKFS_ABORTED:由于参数错误f_mkfs()被终止", /* (14) The f_mkfs() aborted due to any parameter error */"FR_TIMEOUT:在规定的时间内无法获得访问卷的许可", /* (15) Could not get a grant to access the volume within defined period */"FR_LOCKED:由于文件共享策略操作被拒绝", /* (16) The operation is rejected according to the policy */"FR_NOT_ENOUGH_CORE:无法分配长文件名工作区", /* (17) LFN working buffer could not be allocated */"FR_TOO_MANY_OPEN_FILES:当前打开的文件数大于_FS_SHARE", /* (18) Number of open files > _FS_SHARE */"FR_INVALID_PARAMETER:参数无效" /* (19) Given parameter is invalid */};int main(void){int i = 0;FATFS fs;//记录文件系统盘符信息的结构体LED_Init();USARTx_Init();/* 调用f_mount()创建一个工作区,另一个功能是调用了底层的disk_initialize()函数,进行SDIO借口的初始化*/res = f_mount(&fs, "0:", 1 );if (res != FR_OK){printf("挂载文件系统失败(%s)\r\n", FR_Table[res]);}else{printf("挂载文件系统成功(%s)\r\n", FR_Table[res]);}/* 调用f_open()函数在刚刚开辟的工作区的盘符0下打开一个名为Demo.TXT的文件,以创建新文件或写入的方式打开(参数"FA_CREATE_NEW | FA_WRITE"),如果不存在的话则创建这个文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32的FATFS文件系统移植笔记一、序言经常在网上、群里看到很多人问关于STM32的FATFS文件系统移植的问题,刚好自己最近也在调试这个程序,为了让大家少走弯路,我把我的调试过程和方法也贡献给大家。

二、FATFS简介FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。

它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。

它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。

三、移植准备1、FATFS源代码的获取,可以到官网下载:/fsw/ff/00index_e.html最新版本是R0.09版本,我们就移植这个版本的。

2、解压文件会得到两个文件夹,一个是doc文件夹,这里是FATFS的一些使用文档和说明,以后在文件编程的时候可以查看该文档。

另一个是src文件夹,里面就是我们所要的源文件。

3、建立一个STM32的工程,为方便调试,我们应重载printf()底层函数实现串口打印输出。

可以参考已经建立好的printf()打印输出工程:.viewtool./bbs/foru ...d=77&extra=page%3D1四、开始移植1、在已经建立好的工程目录User文件夹下新建两个文件夹,FATFS_V0.09和SPI_SD_Card,FATFS_V0.09用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驱动文件。

2、如图1将ff.c添加到工程文件夹中,并新建diskio.c文件,在diskio.c文件中实现五个函数:1.DSTATUS disk_initialize (BYTE);//SD卡的初始化2. DSTATUS disk_status (BYTE);//获取SD卡的状态,这里可以不用管3. DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//从SD卡读取数据4. DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//将数据写入SD卡,若该文件系统为只读文件系统则不用实现该函数5. DRESULT disk_ioctl (BYTE, BYTE, void*);//获取SD卡文件系统相关信息6.复制代码<IGNORE_JS_OP>图13、初步实现以上五个函数FATFS初始化函数:1.DSTATUS disk_initialize (2.BYTE drv /* Physical drive nmuber (0..) */3. )4. {5.switch (drv)6.{7. case 0 :8. return RES_OK;9. case 1 :10. return RES_OK;11. case 2 :12. return RES_OK;13. case 3 :14. return RES_OK;15. default:16. return STA_NOINIT;17.}18. }复制代码1.DSTATUS disk_status (2.BYTE drv /* Physical drive nmuber (0..) */3. )4. {5.switch (drv)6.{7. case 0 :8. return RES_OK;9. case 1 :10. return RES_OK;11. case 2 :12. return RES_OK;13. default:14. return STA_NOINIT;15.}16. }复制代码FATFS底层读数据函数:1.DRESULT disk_read (2.BYTE drv, /* Physical drive nmuber (0..) */3.BYTE *buff, /* Data buffer to store read data */4.DWORD sector, /* Sector address (LBA) */5.BYTE count /* Number of sectors to read (1..255) */6. )7. {8.if( !count )9.{10. return RES_PARERR; /* count不能等于0,否则返回参数错误*/11.}12.switch (drv)13.{14. case 0:15.if(count==1) /* 1个sector的读操作*/16.{17.return RES_OK;18.}19.else /* 多个sector的读操作*/20.{21.return RES_OK;22.}23. case 1:24.if(count==1) /* 1个sector的读操作*/25.{26.return RES_OK;27.}28.else /* 多个sector的读操作*/29.{30.return RES_OK;31.}32.33. default:34. return RES_ERROR;35.}36. }复制代码FATFS底层写数据函数:1.DRESULT disk_write (2.BYTE drv, /* Physical drive nmuber (0..) */3.const BYTE *buff, /* Data to be written */4.DWORD sector, /* Sector address (LBA) */5.BYTE count /* Number of sectors to write (1..255) */6. )7. {8.if( !count )9.{10. return RES_PARERR; /* count不能等于0,否则返回参数错误*/11.}12.switch (drv)13.{14. case 0:15.if(count==1) /* 1个sector的写操作*/16.{17.return RES_OK;18.}19.else /* 多个sector的写操作*/20.{21.return RES_OK;22.}23. case 1:24.if(count==1) /* 1个sector的写操作*/25.{26.return RES_OK;27.}28.else /* 多个sector的写操作*/29.{30.return RES_OK;31.}32.33. default:return RES_ERROR;34.}35. }复制代码FATFS磁盘控制函数:1.DRESULT disk_ioctl (2.BYTE drv, /* Physical drive nmuber (0..) */3.BYTE ctrl, /* Control code */4.void *buff /* Buffer to send/receive control data */5. )6. {7.if (drv==0)8.{9. switch (ctrl)10. {11. case CTRL_SYNC :12.return RES_OK;13. case GET_SECTOR_COUNT :14. return RES_OK;15. case GET_BLOCK_SIZE :16. return RES_OK;17. case CTRL_POWER :18.break;19. case CTRL_LOCK :20.break;21. case CTRL_EJECT :22.break;23. /* MMC/SDC command */24. case MMC_GET_TYPE :25.break;26. case MMC_GET_CSD :27.break;28. case MMC_GET_CID :29.break;30. case MMC_GET_OCR :31.break;32. case MMC_GET_SDSTAT :33.break;34. }35. }else if(drv==1){36. switch (ctrl)37. {38. case CTRL_SYNC :39.return RES_OK;40. case GET_SECTOR_COUNT :41. return RES_OK;42. case GET_SECTOR_SIZE :43.return RES_OK;44. case GET_BLOCK_SIZE :45. return RES_OK;46. case CTRL_POWER :47.break;48. case CTRL_LOCK :49.break;50. case CTRL_EJECT :51.break;52. /* MMC/SDC command */53. case MMC_GET_TYPE :54.break;55. case MMC_GET_CSD :56.break;57. case MMC_GET_CID :58.break;59. case MMC_GET_OCR :60.break;61. case MMC_GET_SDSTAT :62.break;63. }64.}65.else{66. return RES_PARERR;67.}68.return RES_PARERR;69. }复制代码以上函数都只是实现一个框架,并没有做实际的事情,下一步就需要把操作SD卡的程序填充在这个框架里面。

4、实现disk_initialize()函数该函数在挂载文件系统的时候会被调用,主要是实现读写SD卡前对SD卡进行初始化,根据SD卡的传输协议,我们按照如下步骤初始化SD卡:a、判断SD卡是否插入,可以通过检查SD卡卡座的CD脚电平进行判断,一般插入卡后该引脚会变成低电平。

b、稍微延时一段时间后发送至少74个时钟给SD卡。

c、发送CMD0命令给SD卡,直到SD卡返回0x01为止,这里可以循环多次发送。

程序如下:1. /* Start send CMD0 till return 0x01 means in IDLE state */2.for(retry=0; retry<0xFFF; retry++)3.{4. r1 = MSD0_send_command(CMD0, 0, 0x95);5. if(r1 == 0x01)6. {7. retry = 0;8. break;9. }10.}复制代码d、发送CMD8获取卡的类型,不同类型的卡其初始化方式有所不同。

相关文档
最新文档