STM32笔记(六)SD卡的读写和FatFS文件系统
STM32读写SD卡
3.20SD卡实验很多单片机系统都需要大容量存储设备,以存储数据。
目前常用的有U盘,FLASH芯片,SD卡等。
他们各有优点,综合比较,最适合单片机系统的莫过于SD卡了,它不仅容量可以做到很大(32Gb以上),而且支持SPI接口,方便移动,有几种体积的尺寸可供选择(标准的SD 卡尺寸,以及TF卡尺寸),能满足不同应用的要求。
只需要4个IO口,就可以外扩一个最大达32GB以上的外部存储器,容量选择尺度很大,更换也很方便,而且方便移动,编程也比较简单,是单片机大容量外部存储器的首选。
ALIENTKE MiniSTM3开发板就带有SD卡接口,利用STM32自带的SPI接口,最大通信速度可达18Mbps,每秒可传输数据2M字节以上,对于一般应用足够了。
本节将向大家介绍,如何在ALIENTEK MiniSTM32开发板上读取SD卡。
本节分为如下几个部分:3.20.1 SD卡简介3.20.2 硬件设计3.20.3 软件设计3.20.4 下载与测试3.20.1 SD卡简介SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。
SD卡一般支持2种操作模式:1,SD卡模式;2,SPI模式;主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。
SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。
SD卡的引脚排序如下图所示:图3.20.1.1 SD卡引脚排序图SD卡引脚功能描述如下表所示:表3.20.1.1 SD卡引脚功能表SD卡只能使用3.3V的IO电平,所以,MCU一定要能够支持3.3V的IO端口输出。
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主要定义了文件的类型若是最新的可以不用修改。
STM32使用FatFs
STM32使⽤FatFs1、定义⼀些变量在我们代码开始的部分,先定义⼀些变量供我们使⽤。
这⾥选择⼏个来解析⼀下。
第⼀个FIL file;这个变量是⽂件的结构体变量,记录了我们打开的⽂件的信息。
使⽤f_open等函数的时候都要⽤到。
第⼆个Words变量是⼀个字符串指针,我⽤这个指针来存储读取的字符信息。
这⾥我们就使⽤了malloc函数来分配内存,我们通过修改启动代码提供了更多的堆内存所以这⾥就可以分配⼀些给我们使⽤。
第三个是Path这个字符串,这⾥保存的是⽂件所在的路径。
关于⽂件路径的写法,请参考FatFs的官⽅⽂档。
FIL file; uint8_t Status = 0; char* Words = malloc(256); char* String = "\nWrite some words to this file by STM32F407 MCU.\n"; UINT Number = 0; char Path[16] = "/File/test.txt";2、使⽤f_open关于f_open函数的具体⽤法和详细说明,参见FatFs官⽅⽂档。
这⾥可以看看我在下⽅贴出的代码作为参考来使⽤。
3、使⽤f_read关于f_read没有特别的说明,详细的⽤法去看看FatFs官⽅⽂档⽹站。
这⾥只想说⼀下第三个和第四个参数。
这⾥的第三个参数是给定的要读取的字节数,⽽第四个参数是最后读取了的字节数的存储指针。
这⾥要说明的是,不⼀定你要读取128个字节就⼀定会读取这么多,如果遇到了⽂件尾符号就会停⽌读取。
停⽌读取的时候就会把读取的字节数写⼊到第四个参数指定的存储空间⾥。
所以我们可以通过返回的读取字节数来发送到串⼝,不需要⾃⼰数读取了多少个字节。
if(!f_open(&file, Path, FA_READ | FA_OPEN_EXISTING | FA_WRITE)) { f_read(&file, Words, 256,&Number); HAL_UART_Transmit(&huart1, (uint8_t *)Words, Number, 500); }4、使⽤f_lseek我在调⽤f_write函数之前,调⽤了⼀下f_lseek函数来移动⽂件指针。
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文件系统,今天终于取得阶段性胜利。
只需要提供这样几个函数即可[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之FATFS文件系统(SPI方式)笔记
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"),如果不存在的话则创建这个文件。
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"),如果不存在的话则创建这个文件。
【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(六)-FatFs使用的思路介绍
f_open打开/创建⽂件f_close关闭⽂件f_read读取⽂件f_write写⼊⽂件f_lseek移动读/写指针,扩展⼤⼩f_truncate 截断⽂件f_sync 刷新缓存数据f_forward 转移⽂件数据到⼀个数据流f_expand 为⽂件分配⼀个连续的块f_gets 读取⼀个字符串(string )f_putc写⼊⼀个字符(character )f_puts写⼊⼀个字符串(string )f_printf写⼊⼀个格式化字符串f_tell获取当前读/写指针f_eof⽂件结束测试f_size获取长度f_error测试错误f_opendir 打开⼀个⽬录f_closedir 关闭⼀个已打开的⽬录f_readdir 读取⽬录f_findfirst 打开⼀个⽬录并读取匹配的第⼀个项⽬f_findnext 查找下⼀个匹配的项⽬【STM32】使⽤SDIO 进⾏SD 卡读写,包含⽂件管理FatFs (六)-FatFs 使⽤的思路介绍本篇要来介绍⽂件管理FatFs官⽅的⽹站是:这是⼀个⽇本⼈写的,除了⽂件管理以外,还有其他的,例如解码JPEG 、红外遥控等在官⽹链接内,最下⽅有个Return ,点击后就可以看到相关的开源库以下开始正题(本⽂⾥提到的媒介,其实就是设备了,我不想改图了...)打开官⽅⽹站,页⾯简单明了,就分为4个区块(以下图⽚为FatFs 官⽹上截取的图⽚)第⼀区块、介绍及特性(Features ):FatFs 是⽂件管理系统,可⽤于SD 卡、硬盘(ATA )、RTC 时钟,FTL 和etc 不清楚是什么,另外,也可以⽤于Flash 或是EEPROM第⼆区块、应⽤接⼝(Application Interface ):FatFs 提供了接⼝,使得我们的应⽤可以和它交互。
官⽹左侧为⼀些接⼝的介绍,分四个部分第⼀部分:File Access (⽂件存取)第⼆部分:Directory Access (⽬录访问)f_stat 检查⽂件或⼦⽬录是否存在f_unlink 删除⽂件或⼦⽬录f_rename 重命名/移动⽂件或⼦⽬录f_chmod 更改⽂件或⼦⽬录的属性f_utime更改⽂件或⼦⽬录的时间戳f_mkdir创建⼦⽬录f_chdir 更改当前⽬录f_chdive 更改当前驱动f_getcwd 检索当前⽬录和驱动f_mount注册/注销⼀个⼯作区(挂起与否)f_mkfs在逻辑驱动上创建⼀个FAT 卷f_fdisk 在物理驱动上创建分区f_getfree 获取卷上的可⽤空间f_getlabel 获取卷标f_setlabel 设置卷标f_setcp设置活动代码页disk_status获取设备状态disk_initialize 初始化设备disk_read读取数据disk_write写⼊数据disk_ioctl控制设备相关功能get_fattime 获取当前时间第三部分:File and Dirextor Management (⽂件和⽬录管理)第四部分:Volume Management and System Configuration (卷管理和系统配置)第三区块、媒介访问接⼝(Media Access Interface ):你想管理的存储设备,必须要和FatFs 链接。
STM32下SD卡的读取
STM32下SD卡的读取⼀、SD卡模块介绍1.1 什么是SD卡SD存储卡是⼀种基于半导体快闪记忆器的新⼀代记忆设备,由于它体积⼩、数据传输速度快、可热插拔等优良的特性,被⼴泛地于便携式装置上使⽤,例如数码相机、平板电脑和多媒体播放器等。
控制器对 SD 卡进⾏读写通信操作⼀般有两种通信接⼝可选,⼀种是 SPI 接⼝,另外⼀种是 SDIO 接⼝。
1.2 SD卡的物理结构⼀张SD卡包括有存储单元、存储单元接⼝、电源检测、卡及接⼝控制器和接⼝驱动器5 个部分。
存储单元是存储数据部件,存储单元通过存储单元接⼝与卡控制单元进⾏数据传输;电源检测单元保证SD卡⼯作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接⼝复位;卡及接⼝控制单元控制SD卡的运⾏状态,它包括有8个寄存器;接⼝驱动器控制 SD 卡引脚的输⼊输出。
⼆、项⽬代码已挂载在Github上烧录程序成功后:主要函数代码分析: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_SPI1_Init();MX_FATFS_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1); //enable uart printf(" mian \r\n");Get_SDCard_Capacity(); //得到使⽤内存并选择格式化/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){WritetoSD(WriteBuffer,sizeof(WriteBuffer));HAL_Delay(500);WriteBuffer[0] = WriteBuffer[0] +0;WriteBuffer[1] = WriteBuffer[1] +1;write_cnt ++;while(write_cnt > 10){printf(" while \r\n");HAL_Delay(500);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}void WritetoSD(BYTE write_buff[],uint8_t bufSize){FATFS fs;FIL file;uint8_t res=0;UINT Bw;res = SD_init(); //SD卡初始化if(res == 1){printf("SD卡初始化失败! \r\n");}else{printf("SD卡初始化成功! \r\n");}res=f_mount(&fs,"0:",1); //挂载// if(test_sd == 0) //⽤于测试格式化if(res == FR_NO_FILESYSTEM) //没有⽂件系统,格式化{// test_sd =1; //⽤于测试格式化printf("没有⽂件系统! \r\n");res = f_mkfs("", 0, 0); //格式化sd卡if(res == FR_OK){printf("格式化成功! \r\n");res = f_mount(NULL,"0:",1); //格式化后先取消挂载res = f_mount(&fs,"0:",1); //重新挂载if(res == FR_OK){printf("SD卡已经成功挂载,可以进进⾏⽂件写⼊测试!\r\n");}}else{printf("格式化失败! \r\n");}}else if(res == FR_OK){printf("挂载成功! \r\n");}else{printf("挂载失败! \r\n");}res = f_open(&file,SD_FileName,FA_OPEN_ALWAYS |FA_WRITE);if((res & FR_DENIED) == FR_DENIED){printf("卡存储已满,写⼊失败!\r\n");}f_lseek(&file, f_size(&file));//确保写词写⼊不会覆盖之前的数据if(res == FR_OK){printf("打开成功/创建⽂件成功! \r\n");res = f_write(&file,write_buff,bufSize,&Bw); //写数据到SD卡if(res == FR_OK){printf("⽂件写⼊成功! \r\n");}else{printf("⽂件写⼊失败! \r\n");}}else{printf("打开⽂件失败!\r\n");}f_close(&file); //关闭⽂件f_mount(NULL,"0:",1); //取消挂载}程序⾸先进⾏相关初始化,完成后输出mian,之后进⾏SD卡格式化,成功后进⼊循环,进⼊SD卡读写函数,先后进⾏SD卡的初始化,挂载,创⽂件,写⼊,写⼊超过10次,输出while三、相关引脚的配置CS -> PB0SCK -> PA5MISO -> PA6MOSI -> PA7四、实验结果SD卡中⽣成⼀个新的hello.txt⽂件内容如下更改写⼊内容写⼊结果如下:五、⼼得体会在初始化过程中确保SD格式化成FAT⽂件模式,确保单⽚机的供电和SD卡模块的供电最好是5V,不然可能带不动SD卡驱动导致实验失败。
在STM32中移植FATFS文件系统
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 controldata */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卡的程序填充在这个框架里面。
[STM32]stm32sdiofatfs文件系统源码剖析[精品]
[STM32]stm32+sdio+fatfs文件系统源码分析一、概述1、目的在移植之前,先将源代码大概的阅读一遍,主要是了解文件系统的结构、各个函数的功能和接口、与移植相关的代码等等。
2、准备工作在官方网站下载了0.07c版本的源代码,利用记事本进行阅读。
二、源代码的结构1、源代码组成源代码压缩包解压后,共两个文件夹,doc是说明,src里就是代码。
src文件夹里共五个文件和一个文件夹。
文件夹是option,还有00readme.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. Y ou have to provide a low level disk I/O module that writtento control your storage device.主要是说不包含底层IO代码,这是个通用文件系统可以在各种介质上使用。
我们移植时针对具体存储设备提供底层代码。
接下来做了版权声明-可以自由使用和传播。
然后对版本的变迁做了说明。
3、源代码阅读次序先读integer.h,了解所用的数据类型,然后是ff.h,了解文件系统所用的数据结构和各种函数声明,然后是diskio.h,了解与介质相关的数据结构和操作函数。
再把ff.c和diskio.c两个文件所实现的函数大致扫描一遍。
FAT文件系统的SD卡单片机读写方法详解
FAT32文件系统的存储机制及其在单片机上的实现 FAT32文件系统您一定不会陌生,最多看到它是在windows操作系统里,但在一些嵌入式产品(如手机、MP3、MP4等)中,也能看到它的身影。
从某种意义上来讲,FAT32文件系统是非常成功的,使我们可以脱离底层储存设备驱动,更为方便高效地组织数据。
给单片机系统中的大容量存储器(如SD卡、CF卡、硬盘等)配以FAT32文件系统,将是非常有意义的(如创建的数据文件可以在windows等操作系统中直接读取等)。
FAT32本身是比较复杂的,对其进行讲解的最好方法就是实际演练。
笔者手里持有一张刚以FAT32格式化的SD卡,我们就围绕它来讲解FAT32的实现机理。
FAT32分为几个区域,这里将用实例的方法对它们的结构与在文件存储中的功能进行详细的剖析。
1、实例说明此实例首先在一张空的SD卡(已被格式化为FAT32格式)上创建一个文本文件,并在其中输入20个字符。
再将它插入到单片机系统中,实现对这个文件的读取,将文件内容输出在调试终端上。
2、实现过程1)格式化与创建文件Windows上的磁盘格式化与文件创建就不用多说了。
如下图:2)DBR(DOS BOOT RECORD 操作系统引导记录区)DBR是我们进军FAT32的首道防线。
其实DBR中的BPB部分才是这一区域的核心部分(第12~90字节为BPB),只有深入详实的理解了BPB的意义,才能够更好的实现和操控FAT32。
关于DBR在FAT32中的地位就不多说了,以下面实际的DBR内 图所示:上面的数据看起来杂乱不堪,无从下手,其实对我们有用的数据只不过90个字节(如图中彩色线标记的字节)。
仅仅是这90个字节就可以告诉我们关于磁盘的很多信息,比如每扇区字节数、每簇扇区数、磁道扇区数等等。
对于这些信息的读取,只要遵循DBR中的字段定义即可。
(比如图中紫色字段的两个字节表示这张磁盘的每一个扇区有512个字节,具体的计算方法见下文)字段定义如下表(BPB后面的422个字节对我们的意义不大,表中省略):字段名称长度含义偏移量jmpBoot 3 跳转指令 03OEMName 8 这是一个字符串,标识了格式化该分区的操作系统的名称和版本号BytesPerSec 2 每扇区字节数11SecPerClus 1 每簇扇区数13RsvdSecCnt 2 保留扇区数目 14 NumFATs 1 此卷中FAT表数 16RootEntCnt 2 FAT32为0 17TotSec16 2 FAT32为0 19Media 1 存储介质 21FATSz16 2 FAT32为0 22SecPerTrk 2 磁道扇区数 24NumHeads 2 磁头数 26 HiddSec 4 FAT区前隐扇区数 28TotSec32 4 该卷总扇区数 32FATSz32 4 FAT表扇区数 36ExtFlags 2 FAT32特有 40FSVer 2 FAT32特有 42RootClus 4 根目录簇号 44FSInfo 2 文件系统信息48BkBootSec 2 通常为6 50Reserved 12 扩展用 52 DrvNum 1 - 64 Reserved1 1 - 65 BootSig 1 - 66 V olID 4 - 67 FilSysType 11 - 71 FilSysType1 8 - 82 DBR的实现代码:struct FAT32_DBR{unsigned char BS_jmpBoot[3]; //跳转指令offset: 0unsigned char BS_OEMName[8]; // offset: 3unsigned char BPB_BytesPerSec[2];//每扇区字节数offset:11unsigned char BPB_SecPerClus[1]; //每簇扇区数offset:13unsigned char BPB_RsvdSecCnt[2]; //保留扇区数目offset:14unsigned char BPB_NumFATs[1]; //此卷中FAT表数offset:16unsigned char BPB_RootEntCnt[2]; //FAT32为0 offset:17unsigned char BPB_TotSec16[2]; //FAT32为0 offset:19unsigned char BPB_Media[1]; //存储介质offset:21unsigned char BPB_FATSz16[2]; //FAT32为0 offset:22unsigned char BPB_SecPerTrk[2]; //磁道扇区数offset:24unsigned char BPB_NumHeads[2]; //磁头数offset:26unsigned char BPB_HiddSec[4]; //FAT区前隐扇区数 offset:28unsigned char BPB_TotSec32[4]; //该卷总扇区数offset:32unsigned char BPB_FATSz32[4]; //一个FAT表扇区数 offset:36unsigned char BPB_ExtFlags[2]; //FAT32特有offset:40unsigned char BPB_FSVer[2]; //FAT32特有offset:42unsigned char BPB_RootClus[4]; //根目录簇号offset:44unsigned char FSInfo[2]; //保留扇区FSINFO扇区数offset:48unsigned char BPB_BkBootSec[2]; //通常为6 offset:50unsigned char BPB_Reserved[12]; //扩展用offset:52unsigned char BS_DrvNum[1]; // offset:64unsigned char BS_Reserved1[1]; // offset:65unsigned char BS_BootSig[1]; // offset:66unsigned char BS_VolID[4]; // offset:67unsigned char BS_FilSysType[11]; // offset:71unsigned char BS_FilSysType1[8]; //"FAT32 " offset:82};在程序中我们采用以上的结构体指针对扇区数据指针进行转化,就可以直接读取数据中的某一字段,如要读取BPB_BytesPerSec,可以这样来作:((struct FAT32_DBR *)pSector)-> BPB_BytesPerSec用如上语句就可以得到这一字段的首地址。
stm32fatfs文件系统分析和代码解析
stm32fatfs⽂件系统分析和代码解析⼀⽂件系统:⽂件系统是操作系统⽤于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的⽂件的⽅法和数据结构;即在存储设备上组织⽂件的⽅法。
操作系统中负责管理和存储⽂件信息的软件机构称为⽂件管理系统,简称⽂件系统。
⽂件系统由三部分组成:⽂件系统的接⼝,对对象操纵和管理的软件集合,对象及属性。
从系统⾓度来看,⽂件系统是对⽂件存储设备的空间进⾏组织和分配,负责⽂件存储并对存⼊的⽂件进⾏保护和检索的系统。
具体地说,它负责为⽤户建⽴⽂件,存⼊、读出、修改、转储⽂件,控制⽂件的存取,当⽤户不再使⽤时撤销⽂件等。
⼆ fatfs逻辑FatFs是⽤于⼩型嵌⼊式系统的通⽤FAT / exFAT⽂件系统模块。
FatFs模块是依据ANSI C(C89)标准编写的,并且与磁盘I / O层完全分开。
因此,它的运⾏独⽴于平台。
可以将其合并到资源有限的⼩型微控制器中,例如8051,PIC,AVR,ARM,Z80,RX等。
fatfs写的特别简洁,⾮常适合⼊门者学习和熟悉⽂件系统。
借着stm32的开发机会,笔者对fatfs做了⼀个⼤致的梳理。
stm32中的fatfs⽂件系统分层⼀般分成两层,⼀层是底层的逻辑,这部分主要是通过配置内存卡的寄存器来实现数据的读写。
另外⼀层是应⽤逻辑,这部分负责把函数封装成可以调⽤的⽂件。
让⽤户能清晰的操作⽂件。
三⽂件系统的底层逻辑DSTATUS SD_disk_initialize(BYTE drv)这个主要是初始化的内存设备,很多存储卡的设备都是标准的,不过,也不排除有些设备的兼容性问题是否可以。
这个初始化的时候,⼀定要对准⼿册,看⼀下内存卡命令接⼝信息。
从sd卡中读取信息:DRESULT SD_disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count)往sd卡中写信息,DRESULT SD_disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)对齐和复位存储设备DRESULT SD_disk_ioctl(BYTE drv, BYTE ctrl, void *buff)四⽂件系统的应⽤逻辑⽂件系统的应⽤逻辑⾮常简单,就是让⽤户可以⾃由简单的操作⽂件。
FAT文件系统的SD卡单片机读写方法详解
FAT文件系统的SD卡单片机读写方法详解FAT(File Allocation Table)文件系统是一种常用的文件系统,被广泛应用于存储设备如SD卡上。
在单片机中使用SD卡进行读写操作时,需要使用FAT文件系统进行文件的管理和操作。
下面将详细介绍FAT文件系统的SD卡单片机读写方法。
1.SD卡初始化:在进行SD卡读写操作之前,首先需要初始化SD卡。
初始化SD卡的步骤如下:1.1硬件上电及等待稳定。
将SD卡模块供电,并等待SD卡电压稳定,通常需要几十毫秒的时间。
1.2发送复位命令。
向SD卡发送复位命令,命令的格式如下:CMD0:0x400x000x000x000x000x95发送这个命令后,SD卡会返回R1响应,其中bit 0为0表示复位成功。
1.3发送检测版本命令。
向SD卡发送检测版本命令,命令的格式如下:CMD8:0x480x000x000x010xAA0x87发送这个命令后,SD卡会返回R7响应,其中bit 0为0表示命令执行成功。
1.4判断SD卡类型。
根据R7响应中的数据,判断SD卡的类型,如果是SDHC卡或SDXC卡,需要进行额外的操作。
1.5发送初始化命令。
向SD卡发送初始化命令,命令的格式如下:CMD55:0x770x000x000x000x000xFFACMD41:0x690x400x000x000x000xFF循环发送这两个命令,直到SD卡返回R1响应的bit 0为0,表示初始化完成。
1.6发送读取OCR命令。
向SD卡发送读取OCR命令,命令的格式如下:CMD58:0x7A0x000x000x000x000xFF发送这个命令后,SD卡会返回R3响应,其中包含卡的OCR寄存器的内容。
2.FAT文件系统格式化:在SD卡上创建FAT文件系统之前,需要对SD卡进行格式化操作。
格式化操作会将SD卡分为引导扇区、FAT表、根目录区和数据区。
2.1创建引导扇区。
在SD卡的第一个扇区创建引导扇区,引导扇区包含引导记录和磁盘参数表。
FAT文件系统的SD卡单片机读写方法详解
FAT文件系统的SD卡单片机读写方法详解FAT(File Allocation Table)文件系统是一种用于存储和组织文件的文件系统。
SD卡是一种常见的存储设备,广泛应用于单片机系统中。
在单片机中,访问和读写SD卡上的文件需要特定的方法和步骤。
本篇文章将详细介绍FAT文件系统的SD卡在单片机中的读写方法。
1.硬件接口配置:在单片机系统中使用SD卡之前,需要进行硬件接口的配置。
SD卡使用SPI(Serial Peripheral Interface)进行数据传输,因此需要连接SD卡的CLK(时钟)、MISO(主从串行数据输入)、MOSI(主从串行数据输出)和CS(片选)引脚。
在单片机上使能SPI模块,并设置相关寄存器进行SPI传输的配置。
2.初始化SD卡:在开始使用SD卡之前,需要进行初始化操作。
初始化主要包括向SD 卡发送初始化命令和等待SD卡的响应。
初始化命令主要包括发送复位命令(CMD0)和发送初始化命令(CMD1)。
发送命令后,需要等待SD卡发回响应信号,即SD卡的操作完成,才能进行下一步的操作。
3.读取文件目录:在FAT文件系统中,文件目录存储了文件的相关信息,如文件名、文件大小、起始簇号等。
读取文件目录需要进行多次读取操作,以读取目录项的内容。
首先需要读取FAT表,获取根目录的起始簇号。
然后根据起始簇号,读取对应的目录项内容。
目录项的读取可以通过读取SD卡上的扇区数据进行,需要注意目录项的位置和格式。
4.读取文件数据:在FAT文件系统中,文件数据以簇(Cluster)为单位进行存储。
每个簇的大小一般为512字节。
首先需要根据文件目录项中的起始簇号,定位到对应的簇,并读取簇的数据内容。
读取文件数据就是按照簇的顺序进行读取,直到读取到文件结束符为止。
通过读取SD卡上的扇区数据,并根据FAT表中的簇号进行簇的链式读取。
5.写入文件数据:写入文件数据和读取文件数据类似,也是按照簇的顺序进行写入。
STM32单片机对NAND Flash的读写以及在ASF中的使用
STM32单片机对NAND Flash的读写以及在ASF中的使用
这次大概介绍了一下NAND Flash,以及在ASF中使用它的方法。
一、接线
这个开发板搭载了一个256 MB,8位的NAND Flash(MT29F2G08ABAEA)。
引脚接线如下:
偷个懒,直接上引脚复用的图。
其中PC14表明该NAND FLASH需要作为SMC的外设0使用。
通过使用NANDOE和NANDWE引脚说明需要使用芯片的NAND Flash控制逻辑。
另外,PC18复用为输入引脚,用以查询芯片的状态。
二、NAND Flash
组织结构与寻址
NAND Flash的容量较大。
整片Flash分为若干个块(Block),每个Block分为若干个页(Page)。
在每个页中,除了数据区域,也包含若干“多余”的区域,用来进行ECC等操作。
在进行擦除操作是,基本单位是“块”;而编程的基本单位是“页”。
另外,NAND Flash的物理特性决定了其在编程时,每个bit只能从1变成0。
所以在写入前,必须先对该块进行擦除(擦除时把所有位置为1)。
该Flash的结构如下(忽略plane):
在寻址时,是通过行地址和列地址指定储存单元的。
其中行地址表示页的编号,列地址表示指定在目标地址在该页的位置。
读写时序
因为没有地址线,所以读写较为复杂。
读写时,需要先发送相应操作命令,然后发送地址,才能进行数据传输。
一个简单的“页读取”操作时序图如下:。
STM32读写SD卡要点
3.20SD卡实验很多单片机系统都需要大容量存储设备,以存储数据。
目前常用的有U盘,FLASH芯片,SD卡等。
他们各有优点,综合比较,最适合单片机系统的莫过于SD卡了,它不仅容量可以做到很大(32Gb以上),而且支持SPI接口,方便移动,有几种体积的尺寸可供选择(标准的SD 卡尺寸,以及TF卡尺寸),能满足不同应用的要求。
只需要4个IO口,就可以外扩一个最大达32GB以上的外部存储器,容量选择尺度很大,更换也很方便,而且方便移动,编程也比较简单,是单片机大容量外部存储器的首选。
ALIENTKE MiniSTM3开发板就带有SD卡接口,利用STM32自带的SPI接口,最大通信速度可达18Mbps,每秒可传输数据2M字节以上,对于一般应用足够了。
本节将向大家介绍,如何在ALIENTEK MiniSTM32开发板上读取SD卡。
本节分为如下几个部分:3.20.1 SD卡简介3.20.2 硬件设计3.20.3 软件设计3.20.4 下载与测试3.20.1 SD卡简介SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。
SD卡一般支持2种操作模式:1,SD卡模式;2,SPI模式;主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。
SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。
SD卡的引脚排序如下图所示:图3.20.1.1 SD卡引脚排序图SD卡引脚功能描述如下表所示:表3.20.1.1 SD卡引脚功能表SD卡只能使用3.3V的IO电平,所以,MCU一定要能够支持3.3V的IO端口输出。
stm32Fatfs读写SD卡
stm32Fatfs读写SD卡读写SD是嵌入式系统中一个比较基础的功能,在很多应用中都可以用得上SD卡。
折腾了几天,总算移植成功了最新版Fatfs(Fatfs R0.09),成功读写SD卡下文件。
FatFs ()是一个通用的文件系统模块,用于在小型嵌入式系统中实现FAT文件系统。
FatFs 的编写遵循ANSI C,因此不依赖于硬件平台。
它可以嵌入到便宜的微控制器中,如8051, PIC, AVR, SH, Z80, H8, ARM 等等,不需要做任何修改。
1. SD卡/TF卡硬件接口SD卡有两种操作接口,SDIO和SPI。
使用SDIO口的速度比较快,SPI的速度比较慢。
SD卡引脚描述如下: SD 卡SPI接法如下:我使用的是正点原子的开发板,所以采用的是SPI接口的模式。
TF卡SDIO 模式和SPI模式引脚定义:可以发现Micro SD卡只有8个引脚是因为比SD卡少了一个Vss。
使用TF转SD的卡套套在Micro SD卡上,这样一来大小就和SD卡一样大,这时候卡套上的9个引脚就和SD卡一样了,你可以完全当做SD卡来操作。
2. SD卡底层驱动SD卡的操作比较复杂,需要多看看一些文档。
这里附上SD底层驱动代码,代码说明详见注释Sd卡SPi操作底层代码: sdcard.c sdcard.h3. Fatfs 移植FatFs 软件包中相关文件:ffconf.h FatFs 模块配置文件ff.h FatFs 和应用模块公用的包含文件ff.c FatFs 模块diskio.h FatFs and disk I/O 模块公用的包含文件integer.h 数据类型定义option 可选的外部功能diskio.c FatFs 与disk I/O 模块接口层文件(不属于 FatFs 需要由用户提供)FatFs 配置,文件系统的配置项都在 ffconf.h 文件之中:(1) _FS_TINY :这个选项在R0.07 版本之中开始出现,在之前的版本都是以独立的文件出现,现在通过一个宏来修改使用起来更方便;(2) _FS_MINIMIZE、_FS_READONLY、_USE_STRFUNC、_USE_MKFS、_USE_FORWARD 这些宏是用来对文件系统进行裁剪(3) _CODE_PAGE :本选项用于设置语言码的类型(4) _USE_LFN :取值为0~3,主要用于长文件名的支持及缓冲区的动态分配:0:不支持长文件名;1:支持长文件名存储的静态分配,一般是存储在BSS 段;2:支持长文件名存储的动态分配,存储在栈上;3:支持长文件名存储的动态分配,存储在堆上。
stm32-SD卡FatFS文件系统
STM32平台SD卡的FatFS文件系统开发系统平台:STM32系列的STM32F103ZESPI方式与SD卡通信SD上移植FatFS系统1 FatFS文件系统1.1 FatFS简介FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。
FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。
因此,它独立(不依赖)于硬件架构,可以被嵌入到低成本的微控制器中,如A VR, 8051, PIC, ARM, Z80, 68K 等等,而不需要做任何修改。
特点:∙Windows兼容的FAT文件系统∙不依赖于平台,易于移植∙代码和工作区占用空间非常小∙多种配置选项∙多卷(物理驱动器和分区)∙多ANSI/OEM代码页,包括DBCS∙在ANSI/OEM或Unicode中长文件名的支持∙RTOS的支持∙多扇区大小的支持∙只读,最少API,I/O缓冲区等等1.2 FatFS文件系统移植FatFS文件系统移植需要的几个关键文件如下。
●ff.c(不动)文件系统的实现代码,里面主要是FatFS文件系统源码,移植的时候不需要修改;●diskio.h(不动)声明diskio.c文件中需要的一些接口函数和命令格式;●diskio.c(自写)这个文件是文件系统底层和SD驱动的中间接口的实现代码,移植的时候需要改写在diskio.h中声明的那几个函数,代码在ff.c中被调用;●integer.h(微改)这是FatFS用到的数据类型定义,按移植的平台修改;●ff.h(不动)是FatFS的文件系统的函数(在ff.c中)声明,以及一些选项的配置,具体选项及详细说明在文件中都有;●ffconf.h(按需要)这个是在FatFS的0.08a版本中有看到,0.06版本中还没有,是关于FatFS系统模块的一些配置;综上,需要修改的就是diskio.c文件,主要是6个函数,描述如下。
DSTATUS disk_initialize (BYTE pdrv /* Physical drive nmuber (0..) */) 初始化函数,调用编写的SD卡初始化函数,成功返回0,失败返回其它。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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卡CID
u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD
u32 SD_GetCapacity(void); //取SD卡容量
u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sector
u8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sector
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sector
u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count); //写多个sector
这是diskio.c中的一段代码,在disk初始化中,我们调用了SPI_SD_driver.c中的SD卡初始化函数。
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
u8 state;
if(drv)
{
return STA_NOINIT; //仅支持磁盘0的操作
}
state = SD_Init();
if(state == STA_NODISK)
{
return STA_NODISK;
}
else if(state != 0)
{
return STA_NOINIT; //其他错误:初始化失败
}
else
{
return0; //初始化成功
}
}
总之FATFS文件系统具有很高的可移植性,经测试,在STM32的18MSPI时钟下,读文件的速度在每秒300K以上,写文件也有100多K的速度,应该说基本满足了嵌入式工程应用中,对磁盘读写的速度要求。
如果进一步优化SD卡读写代码,速度应该还会有一定提高,同时还要注意的是FLASH自身读写速度没有ram那么快,通过更换SD卡发现读写速度和卡本身有直接的关系,所以应该尽量选择速度较快的卡。