在STM32中移植FATFS文件系统
STM32+SDIO+FATFS文件系统直读SD卡
![STM32+SDIO+FATFS文件系统直读SD卡](https://img.taocdn.com/s3/m/d915855ca517866fb84ae45c3b3567ec102ddc33.png)
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总线)](https://img.taocdn.com/s3/m/02337354b207e87101f69e3143323968011cf475.png)
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文件系统源码分析](https://img.taocdn.com/s3/m/6bced66bb14e852458fb57d9.png)
、概述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文件系统](https://img.taocdn.com/s3/m/a8b615cc08a1284ac8504368.png)
给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文件系统](https://img.taocdn.com/s3/m/3c332263ddccda38376baf16.png)
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文件系统成功!!!](https://img.taocdn.com/s3/m/3a7c9d03a31614791711cc7931b765ce05087a02.png)
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文件系统移植](https://img.taocdn.com/s3/m/af03cdd3f705cc17552709fb.png)
基于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方式)笔记](https://img.taocdn.com/s3/m/639cb288ff00bed5b9f31ddc.png)
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"),如果不存在的话则创建这个文件。
FatFs在32位微控制器STM32上的移植
![FatFs在32位微控制器STM32上的移植](https://img.taocdn.com/s3/m/818d4f1b76c66137ee061997.png)
0引言 目前微控制器的片上Flash越来越大,一般都有数十 到数百l(B的容量,可以满足多数情况下的应用,但在某 些应用中片上的Flash就不足,比如数据采集、文件存贮。 可见大容量数据的存贮是微控制器应用系统的瓶颈。为了 突破容量的限制,可以采取外扩存贮器,如u盘、移动硬 盘、SD卡等,并移植文件系统便于对文件进行管理。
AnnIication
FatFs m。duIe
Low leve disk I/0 (SD,ATA.USB,NAND)
l RTC
凸一国
2.2 SD卡初始化及读写
图6为SD卡的初始化过程,在SD卡刚刚上电的时候 至少要延时等待74个时钟周期,然后发送复位命令。
要注意的是,STM32连接SD卡的GPIO引脚频率至少 要配置为10MHz以上SD卡才能正常工作,SD卡初始化阶 段SPI的时钟频率必须小于400k,一旦初始化完成可以设 置为高速模式,SPI模式数据传输为高位在前。
2.3移植过程
圈6.SD卡的初始化
移植的第1步是定义数据类型,修改integer.h,使其 中定义的数据类型与相应的Mcu十fl匹配。
第二步是配置ff.h,首先可以看到#define
WORD ACCESS 0这一句,O表示微控制可以按位访问,l
表示微控制按字节访问,STM32是按字节访问的,所以
将其修改为1,另外还要修改#define FS TINY 0这句,如
究生,主要从事光电检测与控制技术方向的研究。 手机:13545196858 E-mail:zhangtao.hawk@gmail.tom
(上接29页) 作者简介:
方敏,女(汉族),(1984.1~),中国地质大学(武汉)机 电学院在读硕士,专业:信息与通信工程。研究方 向:信息与通信工程。
FATFS移植、调试过程(在STM32上使用W25Q64)
![FATFS移植、调试过程(在STM32上使用W25Q64)](https://img.taocdn.com/s3/m/fae25800c381e53a580216fc700abb68a982ad80.png)
FATFS移植、调试过程(在STM32上使用W25Q64)花了几天的时间好不容易自己移植好了FATFS,以前一般都是用别个现成的东西,真的自己移植还是有一点点的操蛋。
移植FATFS其实不难,当然这是对于一个成功移植好的人来说。
FATFS移植资料网上有一大堆,但是在移植成功之前还是搞得我一头雾水.1、准备工作硬件:STM32F4+W25Q64软件:FATFS 0.1版本,好像现在最高的就是0.1版的吧,没去细查。
FATFS官方源码下载好之后只有几个文件。
添加两个C文件进去就好了,添加文件这种事比较基础,没什么好说的。
只要我这截图上有的文件都加上去了,基本上就可以了。
这里面需要我们修改的是diskio.c,其它文件不用动,当然有时候动动也没事,我用别人的东西总喜欢看看里面是什么。
在diskio.c里面,一共有6个接口函数,我按照重要性从最不重要的开始讲参考正点原子的代码,我在开头宏定义了扇区大小等内容。
[cpp] view plain copyprint?1.#define FLASH_SECTOR_SIZE 5122.#define FLASH_BLOCK_SIZE 83.uint32_t FLASH_SECTOR_COUNT = 2048*6;这三个内容在diskio.c都会用到。
这里解释一下这三个东西,我之前查这个搞了半天没理解[cpp] view plain copyprint?1.FLASH_SECTOR_SIZE 是指一个扇区块的大小 512个字节[cpp] view plain copyprint?1.<pre name="code" class="cpp">FLASH_BLOCK_SIZE 一个扇区分成了8块,也就是4K的大小,为什么是八块,百度后发现是因为与FAT类型有关,具体解释在正点原子<h1 class="ph" style="word-wrap: break-word; margin: 0px; padding: 15px 0px 10px; font-size: 20px; font-family: 'Microsoft YaHei', 'Hiragino Sans GB', STHeiti, Tahoma, Si mHei, sans-serif; font-weight: 100; color: rgb(68, 68, 68);">-第四十五章 FATFS实验里面有说明</h1></pre><p></p>2.<pre></pre>3.<pre name="code" class="cpp">FLASH_SECTOR_COUNT 这一段的内容是指有多少个扇区块,有什么用呢,在格式化W25Q64的时候,这个就可以认为是我的W25Q64的容量</pre>因为在W25Q64里面是没有MBR/DBR这些大小的,所以需要使用FATFS格式化成一个存储设备4.<p></p>5.<p>要使用格式化就需要使用diskio.c里面的disk_ioctl函数</p>6.<p>这是第一个函数。
基于STM32的FATS文件系统移植全教程
![基于STM32的FATS文件系统移植全教程](https://img.taocdn.com/s3/m/26e142a2f705cc1755270988.png)
基于STM32的FATS文件系统移植全教程一、移植目的1、结合命令界面的改结~结结文件系结命令界面的结合使用。
与2、在命令界面中结结以下文件系结操作命令,flist-列出前目结下的文件~当fmkdir-在前目结下结建目结~当fchgdir-改结前目结~当fread-结取文件容~内fwrite-新建文件入。
并写二、移植件条1、可以结结的串口命令界面。
参数2、FatFS007e版本。
三、结命令界面所结结功能的描述1、超结结端结置。
首先打结串口结端~结置波特率115200~8位据~无奇偶校结~无流控~结端结结数仿真ANSIW~asicc结结置结以结行符结尾;以前结置的~原因已结忘了,~反正结结结置了能结正常工作。
结结板结位后~结端结示,**********nthq2004 结的结结命令接口写!*********Sh>然后可以在结里结入命令结行。
比如结在支持的命令包括,"help","cls","ledon","ledoff","time","temp","i2cwr","i2crd","sdrd","s dwr"~共10个命令。
比如结入help me命令~结结示命令界面前支持的所有命令~结示会当并当参数前所有结入的命令。
所以命令结行结程的分析以help me结例~help是命令~me是。
参数2、串口结端命令结入结程在串口结端结入一字符结~其工作工程结,个void USART1_IRQHandler(void){ //结函在文件数stm32f10x_it.c中OS_CPU_SR cpu_sr;OS_ENTER_CRITICAL();OSIntNesting++; //中嵌套结断数OS_EXIT_CRITICAL();if ( USART_GetITStatus ( USART1, USART_IT_RXNE )!= RESET ){ Uart_ReceiveChar(); //串口接收字符 }OSIntExit(); //结里可以结任结切结结中触断}串口接收到字符引起结端、然后结用函数Uart_ReceiveChar()结取字符并放入串口消息结列~void Uart_ReceiveChar (void) { //结函在文件数uart.c中u32 RecChar;RecChar = (u32)(USART1->DR & 0xFF);OSQPost ( UartMsgOSQ, ( void* )RecChar ); //字符指结化放入消息结列将~结里接用了周慈航授结中的方法。
fatfs移植调试过程(在stm32上使用w25q64)
![fatfs移植调试过程(在stm32上使用w25q64)](https://img.taocdn.com/s3/m/1695b055c850ad02de804156.png)
FATFS移植、调试过程(在STM32上使用W25Q64)花了几天的时间好不容易自己移植好了FATFS,以前一般都是用别个现成的东西,真的自己移植还是有一点点的操蛋。
移植FATFS其实不难,当然这是对于一个成功移植好的人来说。
FATFS移植资料网上有一大堆,但是在移植成功之前还是搞得我一头雾水.1、准备工作硬件:STM32F4+W25Q64软件:FATFS 0.1版本,好像现在最高的就是0.1版的吧,没去细查。
FATFS官方源码下载好之后只有几个文件。
添加两个C文件进去就好了,添加文件这种事比较基础,没什么好说的。
只要我这截图上有的文件都加上去了,基本上就可以了。
这里面需要我们修改的是diskio.c,其它文件不用动,当然有时候动动也没事,我用别人的东西总喜欢看看里面是什么。
在diskio.c里面,一共有6个接口函数,我按照重要性从最不重要的开始讲参考正点原子的代码,我在开头宏定义了扇区大小等内容。
[cpp] view plain copy print?#defineFLASH_SECTOR_SIZE 512 #defineFLASH_BLOCK_SIZE 8 uint32_tFLASH_SECTOR_COUNT = 2048*6; 这三个内容在diskio.c都会用到。
这里解释一下这三个东西,我之前查这个搞了半天没理解[cpp] view plain copy print?FLASH_SECTOR_SIZE 是指一个扇区块的大小512个字节[cpp] view plain copy print?<pre name="code"class="cpp">FLASH_BLOCK_SIZE 一个扇区分成了8块,也就是4K的大小,为什么是八块,百度后发现是因为与FAT类型有关,具体解释在正点原子<h1 class="ph" style="word-wrap: break-word; margin: 0px; padding: 15px0px 10px; font-size: 20px; font-family: 'Microsoft YaHei','Hiragino Sans GB', STHeiti, Tahoma, SimHei, sans-serif; font-weight: 100; color: rgb(68, 68, 68);">-第四十五章FATFS实验里面有说明</h1></pre><p></p><pre></pre> <pre name="code"class="cpp">FLASH_SECTOR_COUNT 这一段的内容是指有多少个扇区块,有什么用呢,在格式化W25Q64的时候,这个就可以认为是我的W25Q64的容量</pre>因为在W25Q64里面是没有MBR/DBR这些大小的,所以需要使用FATFS格式化成一个存储设备<p></p><p>要使用格式化就需要使用diskio.c里面的disk_ioctl 函数</p> <p>这是第一个函数。
STM32下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,并进行擦写均衡分析
![STM32下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,并进行擦写均衡分析](https://img.taocdn.com/s3/m/77a26293b9d528ea80c77904.png)
STM32 下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,探写均衡分析作者:观海QQ:5316221、摘要在STM32 单片机上,成功移植 FatFs 0.12b,使用的 Nand Flash 芯片为K9F2G08 。
特点:系统配合 FatFs 实现了坏块管理,硬件ECC,软件 ECC 纠错2、代码分析2.1、擦写均衡分析在create_chain 函数中实现,每次分配都由当前scl 指向的free cluster 开始,逐块检查,是否有可用cluster 存在。
如果没有则取下一块,直到回到起始点,说明已经没有free cluster 了。
因为每次都紧邻scl 取free cluster, 那么每次的起始scl 值在哪里,就决定了擦写位置。
通过查看代码,很可惜,发现scl 每次都重新从1 开始查找free cluster。
所以,默认条件下,FatFs 不支持擦写均衡。
如果能把每次分配的cluster号记录下来,下次接着向后分配,则可实现擦写均衡。
未来有时间再来实现吧。
也许你现在就能实现哦,另忘了实现了分享一份给我。
2.2、坏块管理分析通过2.1对create_chain 函数的分析,我们知道get_fat是完成真实的free cluster的分配。
而每次get_fat 函数都会调用move_window 函数实际的读入一次该sector。
所以,我们只需要在读取函数中,对坏块进行检查,返回出错,则分配的cluster 自动移到下一个。
从而完成跳过坏块存储数据。
具体实现如下:如果FSMC_NAND_ReadSmallPage 检测到坏块,则NAND_disk_read 返回RES_ERROR。
2.3、STM32的硬件ECC在FSMC_NAND_Init 函数中打开STM32的硬件ECC配置。
如下红色字。
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes;FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;这里使用的是FSMC_ECCPageSize_256Bytes,而K9F2G08 的最小page 为2048, 所以,我们在驱动中,会再把2048 的page 页再分为8个256的小页面分别进行ECC 运算。
stm32sdiofatfs文件系统源码分析
![stm32sdiofatfs文件系统源码分析](https://img.taocdn.com/s3/m/6bced66bb14e852458fb57d9.png)
、概述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两个文件所实现的函数大致扫描一遍。
最后根据用户应用层程序调用函数的次序仔细阅读相关代码。
fatfs使用例程
![fatfs使用例程](https://img.taocdn.com/s3/m/5629cd6f3069a45177232f60ddccda38376be1ea.png)
fatfs使用例程FatFs是一个嵌入式文件系统库,用于处理在嵌入式应用中使用的存储设备(例如SD卡、SPI存储芯片等)上的文件操作。
它由Elm Chan开发并开源,具有轻量级、可移植性强等特点,适用于各种嵌入式系统。
在使用FatFs之前,我们需要做几个准备工作。
首先,我们需要在我们的开发环境中添加FatFs库文件,并在我们的项目中引入相关的头文件。
其次,我们需要连接一个存储设备到我们的嵌入式系统,例如SD卡或SPI存储芯片。
接下来,我们将通过一个简单的示例来说明如何使用FatFs库。
我们将使用一个基于STM32F4的开发板和一个连接到内置SD卡插槽的SD卡来进行示范。
首先,在STM32CubeIDE中创建一个新的STM32工程,选择合适的开发板和芯片型号,然后通过CubeMX配置SD卡接口。
确保SD卡接口的时钟和引脚配置正确,并使能相关的中断。
然后,我们需要将FatFs库文件添加到我们的项目中。
将FatFs的源代码文件和对应的头文件复制到我们的工程目录下,并在STM32CubeIDE中添加这些文件。
在我们的工程中创建一个新的C文件,命名为"fatfs_example.c",然后在其中编写我们的FatFs使用示例代码。
```c#include "fatfs.h"#include "stdio.h"FATFS fs; /*文件系统对象*/FIL fil; /*文件对象*/FRESULT res; /* FatFs函数返回值*/UINT br, bw; /*读写的字节数*/int main(void){/*挂载文件系统*/if(f_mount(&fs, "0:", 1) != FR_OK){/*挂载失败*/printf("Mount failed.\n");while(1);}/*打开文件*/if(f_open(&fil, "test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE) != FR_OK){/*文件打开失败*/printf("Open failed.\n");while(1);}/*写入数据*/if(f_write(&fil, "Hello,World!", 12, &bw) != FR_OK) {/*写入失败*/printf("Write failed.\n");while(1);}/*关闭文件*/if(f_close(&fil) != FR_OK){/*关闭失败*/printf("Close failed.\n");while(1);}/*卸载文件系统*/if(f_mount(NULL, "0:", 1) != FR_OK){/*卸载失败*/printf("Unmount failed.\n");while(1);}while(1);}```在这个示例中,我们首先挂载了文件系统,然后打开了一个名为"test.txt"的文件,如果文件不存在,则会创建一个新的文件。
STM32_例程TB_FatFs移植实验
![STM32_例程TB_FatFs移植实验](https://img.taocdn.com/s3/m/9bffbb3acfc789eb162dc80a.png)
实验目的∙了解FatFs文件系统的原理∙掌握FatFs文件系统的移植方法∙实现SD卡中文件的读写及其它操作[编辑] FatFsFatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。
FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。
因此,它独立(不依赖)于硬件架构。
它可以被嵌入到低成本的微控制器中,如AVR, 8051, PIC, ARM, Z80, 68K 等等,而不需要做任何修改。
[编辑] 特点∙Windows兼容的FAT文件系统∙不依赖于平台,易于移植∙代码和工作区占用空间非常小∙多种配置选项:多卷(物理驱动器和分区)多ANSI/OEM代码页,包括DBCS在ANSI/OEM或Unicode中长文件名的支持RTOS的支持多扇区大小的支持只读,最少API,I/O缓冲区等等[编辑] 应用程序接口FatFs 模块为应用程序提供了下列函数,这些函数描述了FatFs能对FAT卷执行哪些操作。
[编辑] f_mount在FatFs模块上注册/注销一个工作区(文件系统对象)FRESULT f_mount (BYTE Drive, /* 逻辑驱动器号 */FATFS* FileSystemObject /* 工作区指针 */);参数Drive注册/注销工作区的逻辑驱动器号(0-9)。
FileSystemObject工作区(文件系统对象)指针。
返回值FR_OK (0)函数成功。
FR_INVALID_DRIVE驱动器号无效描述f_mount函数在FatFs模块上注册/注销一个工作区。
在使用任何其他文件函数之前,必须使用该函数为每个卷注册一个工作区。
要注销一个工作区,只要指定FileSystemObject为NULL即可,然后该工作区可以被丢弃。
该函数只初始化给定的工作区,以及将该工作区的地址注册到内部表中,不访问磁盘I/O层。
卷装入过程是在f_mount函数后或存储介质改变后的第一次文件访问时完成的。
18-STM32CubeMX系列教程18文件系统FATFS
![18-STM32CubeMX系列教程18文件系统FATFS](https://img.taocdn.com/s3/m/6ef3121ee87101f69e3195d5.png)
在main.c文件前面添加错误处理函数声明。
5/7
/* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ static void Error_Handler(void); /* USER CODE END PFP */
在FATFS配置中选择简体中文字GBK编码支持 中文,使能长文件名,缓存存储在堆 (STACK)中。
1/7
点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名 动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误 中断(HardFault),死循环)。
编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的 SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。
下载简介一下FATFS的几个操作函数。 1.f_mount 在FatFs模块上注册、注销一个工作区(文件系统对象)。
在main函数中添加应用程序。程序中首先注 册一个文件系统对象,然后新 建STM32cube.txt文件,将数据写文件中再读 出来,判断文件系统是否工作正常。
4/7
/* USER CODE BEGIN 2 */ printf("\r\n ****** FatFs Example ******\r\n\r\n"); /*##-1- Register the file system object to the FatFs module ##############*/ retSD = f_mount(&fs, "", 0); if(retSD) { printf(" mount error : %d \r\n",retSD); Error_Handler(); } else printf(" mount sucess!!! \r\n"); /*##-2- Create and Open new text file objects with write access ######*/ retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); if(retSD) printf(" open file error : %d\r\n",retSD); else printf(" open file sucess!!! \r\n"); /*##-3- Write data to the text files ###############################*/ retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten); if(retSD) printf(" write file error : %d\r\n",retSD); else { printf(" write file sucess!!! \r\n"); printf(" write Data : %s\r\n",wtext); } /*##-4- Close the open text files ################################*/ retSD = f_close(&fil); if(retSD) printf(" close error : %d\r\n",retSD); else printf(" close sucess!!! \r\n"); /*##-5- Open the text files object with read access ##############*/ retSD = f_open(&fil, filename, FA_READ); if(retSD) printf(" open file error : %d\r\n",retSD); else printf(" open file sucess!!! \r\n"); /*##-6- Read data from the text files ##########################*/ retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread); if(retSD) printf(" read error!!! %d\r\n",retSD); else { printf(" read sucess!!! \r\n"); printf(" read Data : %s\r\n",rtext); } /*##-7- Close the open text files ############################*/ retSD = f_close(&fil); if(retSD) printf(" close error!!! %d\r\n",retSD); else printf(" close sucess!!! \r\n"); /*##-8- Compare read data with the expected data ############*/ if(bytesread == byteswritten) { printf(" FatFs is working well!!!\r\n"); } /* USER CODE END 2 */
STM32之FATFS文件系统(SPI方式)笔记
![STM32之FATFS文件系统(SPI方式)笔记](https://img.taocdn.com/s3/m/b47cbdc1e2bd960591c67778.png)
STM32之FATFS文件系统(SPI方式)笔记BY:T7Date:20171202At:YSU_B307开发环境:uVision: V5.12.0.0STM32F103V8T6库版本: STM32F10x_StdPeriph_Lib_V3.5.0FATSF : ff13a工程版本:FATFS_V1日期:20171130硬件连接: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 FileSyatemSrc,FileSystemDst;//文件系统结构体,包含文件指针等成员UINT br,bw;//Fil R/W countBYTE FileRxBuffer[ONE_BLOCK];//FILE COPY BUFFER//BYTE TxFileBuffer[] = "This is the FATFS System!\r\n";BYTE TxFileBuffer[] = "中文文件系统实验!\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 file/directory 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_FILESYSTEM:没有有效的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 file sharing 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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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获取卡的类型,不同类型的卡其初始化方式有所不同。