STM32学习笔记之fatfs文件系统接口函数使用

发布者:innovator8最新更新时间:2017-09-09 来源: eefocus关键字:STM32  fatfs  文件系统  接口函数 手机看文章 扫描二维码
随时随地手机看文章

FatFS文件系统包含了文件

ff.h         :文件系统实现头文件,定义有文件系统所需的数据结构

diskio.h  :底层驱动头文件,就一些状态宏的定义和底层驱动函数的申明

integer.h:仅实现数据类型重定义,增加系统的可移植性

ffconf.h :文件系统配置

ff.c  :文件系统实现。

diskio.c 底层驱动

 

FatFs 提供下面的函数API:

f_mount - 注册/注销一个工作区域(Work Area)

f_open - 打开/创建一个文件f_close - 关闭一个文件

f_read - 读文件f_write - 写文件

f_lseek - 移动文件读/写指针

f_truncate - 截断文件

f_sync - 冲洗缓冲数据 Flush Cached Data

f_opendir - 打开一个目录

f_readdir - 读取目录条目

f_getfree - 获取空闲簇 Get Free Clusters

f_stat - 获取文件状态

f_mkdir - 创建一个目录

f_unlink - 删除一个文件或目录

f_chmod - 改变属性(Attribute)

f_utime - 改变时间戳(Timestamp)

f_rename - 重命名/移动一个文件或文件夹

f_mkfs - 在驱动器上创建一个文件系统

f_forward - 直接转移文件数据到一个数据流 Forward file data to the stream directly

f_gets - 读一个字符串

f_putc - 写一个字符

f_puts - 写一个字符串

f_printf - 写一个格式化的字符磁盘I/O接口

f_tell - 获取当前读/写指针

f_eof - 测试一个文件是否到达文件末尾

f_size - 获取一个文件大小

f_error - 测试一个文件是否出错


因为FatFs模块完全与磁盘I/O层分开,因此需要下面的函数来实现底层物理磁盘的读写与获取当前时间。底层磁盘I/O模块并不是FatFs的一部分,并且必须由用户提供。

disk_initialize - Initialize disk drive 初始化磁盘驱动器

disk_status - Get disk status 获取磁盘状态

disk_read - Read sector(s) 读扇区

disk_write - Write sector(s) 写扇区

disk_ioctl - Control device dependent features 设备相关的控制特性

get_fattime - Get current time 获取当前时间

结合我之前写的一篇博客SPI操作SD卡驱动,完成自定义的diskio.c文件如下:


  1. #include "nrf_gpio.h"  

  2. #include "nrf_drv_spi.h"  

  3. #include "nrf_drv_common.h"  

  4. #include "nrf_assert.h"  

  5. #include "app_util_platform.h"  

  6. #include "bsp.h"  

  7. #include "app_trace.h"  

  8. #include "string.h"  

  9. #include "drv_sd_api.h"  

  10. #include "diskio.h"  

  11. /* Status of Disk Functions */  

  12.   

  13.   

  14. DSTATUS disk_initialize (BYTE drv)  

  15. {  

  16.     uint8_t res=0;     

  17.     res = SD_Card_Initialize();     //正确返回 1:sd  2: SDHC  

  18.     if(res!=1)return  STA_NOINIT;  

  19.     else return 0;   

  20.   

  21. }  

  22.   

  23. DSTATUS disk_status (  

  24.     BYTE drv        /* Physical drive nmuber (0..) */  

  25. )  

  26. {            

  27.     return 0;  

  28. }  

  29.   

  30. DRESULT disk_read (  

  31.     BYTE drv,       /* Physical drive nmuber (0..) */  

  32.     BYTE *buff,     /* Data buffer to store read data */  

  33.     DWORD sector,   /* Sector address (LBA) */  

  34.     BYTE count      /* Number of sectors to read (1..255) */  

  35. )  

  36. {  

  37.     uint8_t res=0;   

  38.     if (!count)return RES_PARERR;  

  39.     if(count==1)            //1个sector的读操作        

  40.     {                                                  

  41.         res = SD_readSingleBlock(sector,buff);        

  42.     }                                                  

  43.     else                    //多个sector的读操作       

  44.     {                                                  

  45.       res= SD_ReadMultiBlock(sector, buff, count);  

  46.     }       

  47.     if(res==0x00)return RES_OK;    

  48.     else return RES_ERROR;       

  49. }  

  50.   

  51. #if _READONLY == 0  

  52. DRESULT disk_write (  

  53.     BYTE drv,           /* Physical drive nmuber (0..) */  

  54.     const BYTE *buff,   /* Data to be written */  

  55.     DWORD sector,       /* Sector address (LBA) */  

  56.     BYTE count          /* Number of sectors to write (1..255) */  

  57. )  

  58. {  

  59.     uint8_t res=0;  

  60.     if(count == 1)  

  61.     {  

  62.         res = SD_writeSingleBlock(sector, buff);  

  63.     }  

  64.     else  

  65.     {  

  66.         res = SD_WriteMultiBlock(sector, buff, count);  

  67.     }  

  68.     // 返回值转换  

  69.     if(res == 0)  

  70.     {  

  71.         return RES_OK;  

  72.     }  

  73.     else  

  74.     {  

  75.         return RES_ERROR;  

  76.     }  

  77. }  

  78. #endif /* _READONLY */  

  79.   

  80. DRESULT disk_ioctl (  

  81.     BYTE drv,       /* Physical drive nmuber (0..) */  

  82.     BYTE ctrl,      /* Control code */  

  83.     void *buff      /* Buffer to send/receive control data */  

  84. )  

  85. {     

  86.     DRESULT res;  

  87.   

  88.   

  89.     if (drv)  

  90.     {      

  91.         return RES_PARERR;  //仅支持单磁盘操作,否则返回参数错误  

  92.     }  

  93.       

  94.     //FATFS目前版本仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个命令  

  95.     switch(ctrl)  

  96.     {  

  97.     case CTRL_SYNC:  

  98.     /* 

  99.          SD_CS_ENABLE(); 

  100.       

  101.         if(SD_WaitReady()==0) 

  102.         { 

  103.             res = RES_OK; 

  104.         } 

  105.         else 

  106.         { 

  107.             res = RES_ERROR; 

  108.         } 

  109.         SD_CS_DISABLE(); 

  110.         */  

  111.         res=RES_OK;  

  112.         break;  

  113.           

  114.     case GET_BLOCK_SIZE:  

  115.         *(WORD*)buff = 512;  

  116.         res = RES_OK;  

  117.         break;  

  118.   

  119.     case GET_SECTOR_COUNT:  

  120.         *(DWORD*)buff = SD_GET_SD_SIZE();  

  121.         res = RES_OK;  

  122.         break;  

  123.     default:  

  124.         res = RES_PARERR;  

  125.         break;  

  126.     }  

  127.   

  128.     return res;  

  129. }  

  130.       

  131. DWORD get_fattime (void)  

  132. {  

  133.     DWORD date=0;  

  134.     return date;  

  135. }  




FatFS系统特性

打开文件数量:无限制,与可用内存有关。 卷(volume)数量:最多10个。 

文件大小:与FAT规范有关(最大4G-1字节)。 

卷大小:与FAT规范有关(在512字节/扇区上,最大2T字节) 

簇(Cluster)大小:与FAT规范有关(在512字节/扇区上,最大64K字节) 扇区(Sector)大小:与FAT规范有关(最大4K字节)

创建文件并读写的使用例程

1)f_mount(0, &fatFS);                                       

2)f_mkfs(0,1,512);                 //创建文件系统

FRESULT f_mkfs (
 BYTE  Drive,            
 BYTE  PartitioningRule, 
 WORD  AllocSize         );

 

分区规则:当给定0时,首先在驱动器上的第一个扇区创建一个分区表,然后文件系统被创建在分区上。这被称为FDISK格式化,用于硬盘和存储卡。当给定1时,文件系统从第一个扇区开始创建,而没有分区表。这被称为超级软盘(SFD)格式化,用于软盘和可移动磁盘。


3)f_getfree("0:", &fre_clust, &fs2)   //获得磁盘存储空间大小 

4)f_open(&file1, "/srcfile.txt",  FA_OPEN_ALWAYS | FA_READ | FA_WRITE);  //打开文件

FIL     file1;   

5)f_puts(cDataBuf, &file1);    //将cDataBuf[]数据写入 文件srcfile.txt

6)f_sync (&file1);   //刷新文件

7)f_lseek(&file1, 0);   //从文件 偏移字节0出开始读文件

8)f_read(&file1, buffer, 10,&r);     //读出10个字节到 buffer[]中

9)f_close(&file1);   //操作完成  关闭文件

常见的实际用法:

1)

 b = f_open(&infile,"SD.txt",FA_CREATE_NEW);    //创建新文件
 f_close(&infile);    //关闭文件

2) 

b = f_open(&infile,"SD.txt", FA_WRITE);   //以写方式打开文件
 f_puts((char *)buff2,&infile);  //文件内写入字符串
 f_puts((char *)buff2,&infile);  //文件内写入字符串
 f_puts((char *)buff2,&infile); //文件内写入字符串
 f_close(&infile);  //关闭文件

3) 

b = f_open(&infile,"SD.txt",FA_WRITE);   //以写方式打开文件
 b = infile.fsize;       //获得文件大小
 f_lseek(&infile,b);  //移动文件指针
 f_puts(buff3,&infile);  //从文件内数据的最后写入字符串
 f_close(&infile);    //关闭文件

4) 

b = f_open(&infile,"SD.txt",FA_READ);  //以读方式打开文件
 f_read(&infile,buff1,50,&rc);  //从文件内读50字节赋给 buff1数组
 f_close(&infile);   //关闭文件

// f_unlink("SD.txt");   //删除文件


创建目录例程

1) f_chdir("0:");   //切换到根目录

2)f_mkdir("folder");   //创建目录 folder

3)f_open(&file1, "folder/oldname2.txt", FA_CREATE_ALWAYS | FA_WRITE);  //打开folder目录下的文件

4)f_close(&file1);    //关闭文件



 FATFS *fs, fatfs;

 fs = &fatfs;
 f_mount(0, fs);

 b = f_open(&infile,"SD.txt",FA_CREATE_NEW);    //创建新文件
 f_close(&infile);    //关闭文件

 b = f_open(&infile,"SD.txt", FA_WRITE);   //以写方式打开文件
 f_puts((char *)buff2,&infile);  //文件内写入字符串
 f_puts((char *)buff2,&infile);  //文件内写入字符串
 f_puts((char *)buff2,&infile); //文件内写入字符串
 f_close(&infile);  //关闭文件

 b = f_open(&infile,"SD.txt",FA_WRITE);   //以写方式打开文件
 b = infile.fsize;       //获得文件大小
 f_lseek(&infile,b);  //移动文件指针
 f_puts(buff3,&infile);  //从文件内数据的最后写入字符串
 f_close(&infile);    //关闭文件

 b = f_open(&infile,"SD.txt",FA_READ);  //以读方式打开文件
 f_read(&infile,buff1,50,&rc);  //从文件内读50字节赋给 buff1数组
 f_close(&infile);   //关闭文件

// f_unlink("SD.txt");   //删除文件


关键字:STM32  fatfs  文件系统  接口函数 引用地址:STM32学习笔记之fatfs文件系统接口函数使用

上一篇:STM32学习笔记之低功耗模式的机制
下一篇:STM32学习笔记之对PWM频率和占空比都可调测试

推荐阅读最新更新时间:2024-03-16 15:36

STM32 ADC的规则通道和注入通道的区别
STM32的每个ADC模块通过内部的模拟多路开关,可以切换到不同的输入通道并进行转换。STM32特别地加入了多种成组转换的模式,可以由程序设置好之后,对多个模拟通道自动地进行逐个地采样转换。 有2种划分转换组的方式:规则通道组和注入通道组。通常规则通道组中可以安排最多16个通道,而注入通道组可以安排最多4个通道。 在执行规则通道组扫描转换时,如有例外处理则可启用注入通道组的转换。 一个不太恰当的比喻是:规则通道组的转换好比是程序的正常执行,而注入通道组的转换则好比是程序正常执行之外的一个中断处理程序。 再举一个不一定使用的例子: 假如你在家里的院子内放了5个温度探头,室内放了3个温度探头;你需要时刻监视室外温
[单片机]
STM32输出PWM时,PWM1和PWM2的区别
首先,本人虽然初学STM32但极力反对一种误人子弟的观点:“对于STM32这样级别的MCU,有库函数就不用去看寄存器怎么操作的了!” 好了,言归正传,最近总看到很多朋友对于PWM这个实验有很多的疑惑,看到原子也在极力的回复也挺累的(体谅一下幸苦的原子大神,(*^__^*) ),所以我打算写这么一篇文字来阐述一下我个人对STM32的PWM的理解。 首先来说,你要使用PWM模式你得先选择用那个定时器来输出PWM吧!除了TIM6、TIM7这两个普通的定时器无法输出PWM外,其余的定时器都可以输出PWM,每个通用定时器可以输出4路PWM,高级定时器TIM1、TIM8每个可输出7路PWM,这里为了方便起见,我们选择与实验相同的TIM3的
[单片机]
STM32_TIM定时-中断
今天讲解STM32F103定时器定时-中断功能,在昨天定时器延时的软件工程上添加TIM3定时的功能,自己也可以试着将昨天的工程添加修改得到。 今天的软件工程下载地址(360云盘): https://yunpan.cn/cPnJ9KYcXbPsP 访问密码 acd8 工程现象:间隔(定时器定时)500ms LED变化一次, 并且串口打印 STM32F103ZE有8个定时器(TIM1 – TIM8), 改工程以TIM3定时为例。 STM32F10x的资料可以在我360云盘下载: https://yunpan.cn/crBUdUGdYKam2 访问密码 ca90 关于TIM延时,我把重要的几点在下面分别讲述,工程中
[单片机]
STM32_TIM定时-中断
STM32——DMA
DMA 是为CPU分担数据转移的工作。因为DMA的存在CPU才被解放出来,它可以在 DMA 转移数据的过程中同时进行数据运算、响应中断,大大提高效率。 1、DMA工作分析 数据传输的过程中,不需要内核的全程参与,所以内核可以同时进行数据运算。DMA 方式是点到点的数据转移,而不使用 DMA 方式还要以内核来作为中转站,显然 DMA 传输方式的效率更高。 要使用 DMA,需要确定一系列的控制参数,如外设数据的地址、内存地址、传输方向等,在开启 DMA 传输前还要先发出 DMA 请求。 2、 初始化DMA typedef struct { uint32_t DMA_PeripheralBaseAdd
[单片机]
<font color='red'>STM32</font>——DMA
stm32软件系统从裸机升级为ucos
如题,公司的项目,stm32原来是裸奔的,驱动之类都是直接写的,这一个星期,将驱动和上层的应用升级为ucos的版本。 由于ucos系统很简单(5000行),而且别人都做好了现成的stm32移植,我只是简单的做上面的驱动和应用,我主要关注点是怎么利用ucos系统接口完成应用。 之所以升级到ucos版本,是因为原来的iic和SPI驱动由于要死等,导致应用层的任务被阻塞,而导致伺服周期不准,虽然用上了外部定时器中断来触发伺服任务,但是还是有不准的情况,所以对iic和SPI驱动改造,不再是死等,而是等的时候放弃CPU(OSTimeDly(1)),这样,即使在运行过程中,也可以很方便的读写eeprom。 心得体会: 1)复杂多任务的情况下面
[单片机]
为什么可以在STM32上面跑神经网络
摘要:为什么可以在STM32上面跑神经网络?简而言之就是使用STM32CubeMX中的X-Cube-AI扩展包将当前比较热门的AI框架进行C代码的转化,以支持在嵌入式设备上使用,目前使用X-Cube-AI需要在STM32CubeMX版本5.0以上,支持转化的模型有Keras、TFlite、ONNX、Lasagne、Caffe、ConvNetJS。Cube-AI把模型转化为一堆数组,而后将这些数组内容解析成模型,和Tensorflow里的模型转数组后使用原理是一样的。 一、环境安装和配置 STM32CubeMX MDK/IAR/STM32CubeIDE F4/H7/MP157开发板 二、AI神经网络模型搭建 这里使用官方提供
[单片机]
为什么可以在<font color='red'>STM32</font>上面跑神经网络
STM32入门学习之GPIO(STM32F030F4P6基于CooCox IDE)(寄存器操作版
依然,直接上代码 #include stm32f0xx.h #include stm32_lib/inc/stm32f0xx_rcc.h #include stm32_lib/inc/stm32f0xx_gpio.h int main(void) { //IOPAEN=1,使能GPIOA的时钟 RCC- AHBENR |= RCC_AHBENR_GPIOAEN; //设置IO口工作模式,GPIOA_MODER4=0x01,通用IO口 GPIOA- MODER |= GPIO_MODER_MODER4_0; GPIOA- MODER &= ~GPIO_MODER_MODER4_1; /
[单片机]
<font color='red'>STM32</font>入门学习之GPIO(STM32F030F4P6基于CooCox IDE)(寄存器操作版
STM32的SYSTICK_Init()配置
void SYSTICK_Init(void) { /* SysTick end of count event each 1ms with input clock equal to 4.5MHz (HCLK/8, default) SysTick_SetReload(4500); /* Enable SysTick interrupt SysTick_ITConfig(ENABLE); /* Enable the SysTick Counter SysTick_CounterCmd(SysTick_Counter_Enable); } 系统时钟定时器的周期与驱动的时钟频率和Reload值相关。
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved