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

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

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

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

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

二、STM32之SD卡_SPI模式
1.硬件连接:
SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA7
2.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 1024
uint8_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 count
BYTE 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 physical drive 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"),如果不存在的话则创建
这个文件。

同意见Demo.TXT这个文件关联到FileSyatemSrc这个结构指针,以后操作文件就是听过
这个结构指针来完成,可以理解为文件指针。

*/
res = f_open( &FileSystemDst , "0:/Demo1.TXT", FA_CREATE_NEW | FA_WRITE);
/* 对f_open()函数的返回值进行检查 */
if( res == FR_OK )
{
printf("File Open SUCCESS! \n\t");
/*
将缓冲区的数据写到文件中,创建文件成功,调用f_write()将缓冲区的数组变量
TxFileBuffer 的容写到刚刚打开的Demo.TXT文件中,写完之后必须调用f_close()函数关闭
已经打开的文件,否则前面写入的数据无效,甚至可能导致其他错误
*/
res = f_write( &FileSystemDst , TxFileBuffer , sizeof(TxFileBuffer) , &bw);
if(res)
printf("File Write ERROR! \n\t");
else
printf("File Write SUCCESS! \n\t");
/* 关闭文件 */
f_close(&FileSystemDst);
}
else if(res == FR_EXIST)
{
printf("File is already exist \n");
}
else
printf("Don't know the error! \r\n");
/*-----------将刚刚新建的文件里面的容打印到串口----------------*/
/* 以只读的方式打开刚刚创建的文件 */
res = f_open( &FileSystemDst, "0:/Demo1.TXT", FA_OPEN_EXISTING | FA_READ);
if(res)
printf("File Open ERROR! \n\t");
else
printf("File Open SUCCESS! \n\t");
/* 打开文件 */
br = 1;
for(;;)
{
/* 清缓冲区 */
for(i = 0; i < ONE_BLOCK; i++)
FileRxBuffer[i] = 0;
/*
将文件里面的容读到缓冲区,调用函数f_read()将文件的容读到
缓冲区FileRxBuffer数组变量中,然后打印到串口
*/
res = f_read( &FileSystemDst, FileRxBuffer, sizeof(FileRxBuffer), &br);
if(res)
printf("File Read ERROR! \n\t");
else
printf("File Read SUCCESS! \n\t");
printf(" \r\n %s ",FileRxBuffer );
if(res || br == 0)
break; //错误或者到了文件尾
}
/*
关闭打开的文件
当被打开的文件操作完成之后都要调用f_close()将它关闭,
如同一块动态分配的存在用完之后都要调用free()来将它释放*/
f_close(&FileSystemDst);
while(1)
{ }
}
/**
* }
*/
/*********
********** (C) COPYRIGHT 2017 TIMEANDSPACE7*****END OF FILE****/
六、下载及实验现象
编译无误后下载,下载会很慢。

1.串口现象“首行的乱码是字符编码的问题,在这里不做解决”
2.SD卡
使用读卡器,读取SD卡:
百度云:
:https://pan.baidu./s/1hrSeFkw 密码:4hkc。

相关文档
最新文档