你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CubeMX配置文件系统FATFS

[复制链接]
科技人生 发布时间:2017-12-26 17:53
[转载]STM32CubeMX配置文件系统FATFS
* B# a' S" j! v$ c% Fhttp://www.waveshare.net/study/article-657-1.html
; ~  w1 Q6 P8 L3 [; t(出处:微雪课堂)3 z( F3 F/ o! u2 N0 _
FATFS简介
) e& @. \2 u2 }2 P2 {6 m* I- H! \) r  O- M. X
    FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。它可以被嵌入到低成本的微控制器中,如AVR, 8051, PIC, ARM等等。兼容Windows文件系统。. ~6 {6 [/ c; e; N$ o1 i
关于FATFS文件系统的API函数介绍,底层移植接口和例程等可以查到FATFS官网。
  @  e3 n/ O8 H4 L" D. k
; a) M2 M/ ~6 k% m2 wFATFS官网:http://elm-chan.org/fsw/ff/00index_e.html
& {. k$ I5 ^0 y9 J, L; {/ }
" @6 k& s' w9 k$ b
* w3 o9 T0 p# T; c3 t- z6 J
        结合STM32cubeMX软件移植FATFS文件系统非常简单。本章程序在上一章SDMMC工程的基础上修改,复制串口SDMMC的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。在中间件中选择SD卡,在SD上建立文件系统。
  a( C, A' t  }
: Z8 M" d0 F6 W# v8 k 001.png
' k$ Q/ Z8 s3 T8 H8 y, N7 G    在FATFS配置中选择简体中文字GBK编码支持中文,使能长文件名,缓存存储在堆(STACK)中。8 x7 G+ E3 O, d
002.png
( W6 x  S. c( u  ]    点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。
% {6 y/ J' j1 V; _3 w 003.png
1 E; q/ q, Q; E' C2 D/ t( ^    生成报告以及代码,编译程序。在fatfs.c文件中可以看到FATFS初始化函数。在bsp_drver_sd.c文件中可以看到SD卡的板级操作函数,包括SD初始化,读写擦除块操作函数。在sd_diskio.c文件中可以看到FATFS文件系统移植的底层操作函数。
8 I% \* @: |% L% V$ n 004.png ; k5 k  y+ \) `% k8 q5 P$ P$ P. s
    删除上一章SDMMC的应用程序。在main.c文件前添加变量。fs为文件系统工作区,fil为文件对象结构的指针。rtext/wtext分别为读写缓存,bytesread/byteswritten分别存储读写的字节数。filename存储文件名(FATFS文件系统配置时使能了长文件名,最长255字节,若不支持长文件名,则文件名最多8个字节)。
( o2 l/ k1 A, _" b( q2 }/ H, {
  1. /* USER CODE BEGIN PV */4 _" [# e0 i2 J4 P) I7 ~, z
  2. /* Private variables ---------------------------------------------------------*/0 ~  Q, P7 y3 s
  3. FATFS fs;                 // Work area (file system object) for logical drive3 J# |7 _# \& r+ b
  4. FIL fil;                  // file objects
    " h2 k) o/ R  O
  5.   
    ) A: W0 i0 N& @& k
  6. uint32_t byteswritten;                /* File write counts */
    % ^2 k; Z7 B+ S
  7. uint32_t bytesread;                   /* File read counts */
    $ q& n4 B' B. p
  8. uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */% ?2 y  V# W, E# I; P9 Z
  9. uint8_t rtext[100];                     /* File read buffers */' v4 y3 m* O3 z7 ?$ Y; |
  10. char filename[] = "STM32cube.txt";* p2 P. E! t! G8 K7 V1 _; v
  11. /* USER CODE END PV */
    / E8 n4 W0 ^1 v9 D  V6 w$ i
复制代码
在main函数中添加应用程序。程序中首先注册一个文件系统对象,然后新建STM32cube.txt文件,将数据写文件中再读出来,判断文件系统是否工作正常。
: m# L1 r4 k% k9 F( E9 q% @! B
  1. /* USER CODE BEGIN 2 */
    " B$ d, }4 b: A5 ~: g$ l
  2.     printf("\r\n ****** FatFs Example ******\r\n\r\n");# r& U  K3 X+ H$ k" Y  ]; O2 \8 ~
  3. ; A1 X. q  v' T" I0 L
  4.     /*##-1- Register the file system object to the FatFs module ##############*/2 V( S6 J/ I9 U
  5.     retSD = f_mount(&fs, "", 0);
    9 m+ @2 S9 U# C4 E
  6.     if(retSD)- @6 j9 f: a: i; z5 A
  7.     {
    . t$ d6 s+ d; z! z' O: I4 Y& f6 i
  8.         printf(" mount error : %d \r\n",retSD);
    2 K) h/ y9 d5 ~9 N
  9.         Error_Handler();; l7 T" ?6 t8 n' D% F; ~+ v
  10.     }+ c" U, Z+ }/ k' K5 F' z
  11.     else
    ( v2 e/ B2 I5 ^9 y! u
  12.         printf(" mount sucess!!! \r\n");
    ! y* h% G: D( w
  13.      
    & y  B& h- A3 J0 h+ y: P* p
  14.     /*##-2- Create and Open new text file objects with write access ######*/7 P: }8 A* g3 ~1 B# L$ u* S5 e$ O
  15.     retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE);; y. G; t& o' O. u! q1 O
  16.     if(retSD)
    6 w- p6 u" h( I2 \& v
  17.         printf(" open file error : %d\r\n",retSD);
    $ t7 w& d: G; f! p
  18.     else
    8 L/ e' |/ f: c. D2 g# B
  19.         printf(" open file sucess!!! \r\n");
    6 ]$ p+ n* ], s5 z: T5 l; |9 f
  20.      
    ! C" k8 m, }8 p" X8 P. i
  21.     /*##-3- Write data to the text files ###############################*/* _5 k% k$ [0 f8 D$ o
  22.     retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten);6 p& m8 Y% r6 b$ y# v! Y
  23.     if(retSD)
    . Y  x( \0 W" n0 b- S# V
  24.         printf(" write file error : %d\r\n",retSD);1 a; f. \: u# j3 @, _) F4 U
  25.     else6 c! E4 P4 ~1 z4 Y
  26.     {
    7 e2 V9 }4 j, A" h$ \; ~/ a
  27.         printf(" write file sucess!!! \r\n");
    ' T6 [- x( v% N
  28.         printf(" write Data : %s\r\n",wtext);, k' ]  z- X7 r
  29.     }
    7 L1 ^4 B/ i, |/ v! a
  30.      
    - I" ^* D: Z1 g: `4 d% A
  31.     /*##-4- Close the open text files ################################*/
    4 F% Y& J: f7 R! }
  32.     retSD = f_close(&fil);6 A$ N% r2 h/ w; K! G, T- C0 L; J
  33.     if(retSD)0 r, V+ z1 ?  F- o, Y5 }2 \6 P  p2 N
  34.         printf(" close error : %d\r\n",retSD);
    0 d% _" s4 _; N
  35.     else
      J  C. p+ a2 v1 S
  36.         printf(" close sucess!!! \r\n");
    * l+ W3 j5 t+ }3 d3 }! c
  37.      
    $ z4 G9 t- o) ~" J$ l( j  r+ V
  38.     /*##-5- Open the text files object with read access ##############*/% @# T2 L0 \$ X2 U
  39.     retSD = f_open(&fil, filename, FA_READ);9 ~  V: W5 {2 m) a& f
  40.     if(retSD)$ D& h0 |/ V  y! C4 g; f
  41.         printf(" open file error : %d\r\n",retSD);
    # \" A& d; J5 c* G
  42.     else! V4 Z, a( E( @5 Q1 L" Y2 t
  43.         printf(" open file sucess!!! \r\n");
    0 n7 V* j% E( G2 M! G
  44.      
    $ S1 @6 ?& b# K0 K: q% X6 |
  45.     /*##-6- Read data from the text files ##########################*/
      W+ i3 [( M" h( ]& _
  46.     retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread);
    6 p" F3 I% c* t  O
  47.     if(retSD)" X  D1 T5 f3 }
  48.         printf(" read error!!! %d\r\n",retSD);
    + q) I; G# f; D) V- `: I& H$ V
  49.     else4 J9 `. w/ n7 S, s$ d
  50.     {
    7 F0 F- O6 Y; q9 P6 I
  51.         printf(" read sucess!!! \r\n");
    $ L& N( s3 y, E. P) t
  52.         printf(" read Data : %s\r\n",rtext);
    , G, S. f, v( e, r" z
  53.     }8 m/ X. v0 x/ f
  54.      
    , A% s+ Y2 a- K1 R) W8 U) M3 \3 x
  55.     /*##-7- Close the open text files ############################*/
    + [4 l$ G7 C- k& N
  56.     retSD = f_close(&fil);
    & n# O- n  t' }0 m  e# Q# i
  57.     if(retSD)  & |, ~$ H0 U3 T4 `* ^
  58.         printf(" close error!!! %d\r\n",retSD);- _" s% F$ M% I% P" V& m: z; {3 O
  59.     else
    + t- M; }! n, c  w  G; Y
  60.         printf(" close sucess!!! \r\n");
    # y9 a) @. b" F
  61.      5 h. c+ X3 H2 M, _/ t3 y
  62.     /*##-8- Compare read data with the expected data ############*/
    + m/ d% k3 b$ g4 q0 {" ?
  63.     if(bytesread == byteswritten)
    2 ?$ I* L* N# N: J2 K
  64.     {
    3 W3 x! u/ S- V% e
  65.         printf(" FatFs is working well!!!\r\n");% p1 {- Q/ W+ {6 g; u# V
  66.     }
    0 b7 {! \2 ~% E
  67.   /* USER CODE END 2 */
复制代码
在main.c文件后面添加错误处理函数。

$ J* k5 o/ i2 n+ R
  1. /* USER CODE BEGIN 4 */
    * g+ e2 D5 n# I, C. E* u6 D
  2. static void Error_Handler(void)
    - z: I, I' F5 e* E3 k( c9 A2 T. n& Q
  3. {! ~! T) a! C1 w+ X
  4.   printf("something wrong ....\r\n");
    & T6 h: I+ m/ f6 N$ @
  5.     /* User may add here some code to deal with this error */
    ! |% y' i# c3 ^1 {
  6.   while(1)
    ( o, m/ |0 o* m6 r
  7.   {; ], x+ X2 M7 ?+ p. P% @: P
  8.   }3 W* d) \/ [& d* Y- j, `' W/ R8 ?
  9. }
    / ]7 O) k$ j7 i9 D
  10. /* USER CODE END 4 */
复制代码
在main.c文件前面添加错误处理函数声明。

; }4 i  d" A' {, z- U
  1. /* USER CODE BEGIN PFP */* Z2 g; S8 P" n9 {
  2. /* Private function prototypes -----------------------------------------------*/
    % I+ C, ^! y* y/ J& z
  3. static void Error_Handler(void);8 i# S$ J: F+ S# ?( J
  4. /* USER CODE END PFP */
复制代码
编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。
: S+ P) ~+ w  w( ~' U7 w+ U
005.png
" d7 A! v7 S. G1 L! N$ B4 a下载简介一下FATFS的几个操作函数。. R- h9 n- A0 ]4 {; a5 b
1.f_mount- W4 M8 r1 Y$ q4 ~$ g) k. k
在FatFs模块上注册、注销一个工作区(文件系统对象)。' W) m- O' }7 K0 |: m
  1. FRESULT f_mount (
    # _9 n% e+ W6 m# o- g
  2.     FATFS* fs,         /* Pointer to the file system object (NULL:unmount)*/' @0 L. _! F3 e6 n) s) v
  3.     const TCHAR* path,    /* Logical drive number to be mounted/unmounted */
    & {5 p6 T( _: a+ z
  4.     BYTE opt           /* 0:Do not mount (delayed mount), 1:Mount immediately */
    6 h0 |1 w( g& K7 `1 g6 x
  5. )
复制代码
参数4 [4 [. @, x, a, b9 J5 V% G
fs 工作区(文件系统对象)指针7 k8 O, c4 Q, |- e
path  注册/注销工作区的逻辑驱动器号8 y9 v* z" k5 n& q' H
opt      注册或注销选项
8 v& `" z8 n2 d8 b+ ?1 @  n* r4 O7 q& u8 j! g5 f9 u
+ u4 }2 L  [  w/ X0 ^6 b  m9 k5 B
0 B) x# t. I! k3 q6 K9 j2 h# n, M
( h1 n) C3 x- O% L7 O; ^  W
2.f_open: w/ I2 E( T% u$ c* X$ J
创建/打开一个文件对象  K& n1 f) U4 j# E5 d
  1. FRESULT f_open (
    ) V2 h" l9 L  i) {6 l5 o! q
  2.     FIL* fp,           /* Pointer to the blank file object */' W7 Y/ \4 _  j8 ~5 q8 Z
  3.     const TCHAR* path,    /* Pointer to the file name */
    ; @8 v, d8 Z/ n7 u
  4.     BYTE mode          /* Access mode and file open mode flags */
    % o* O$ Y) x" F. e% _+ P
  5. )
复制代码
fp   将被创建的文件对象结构的指针
- r- i  G% {# M$ ?0 |path  文件名指针,指定将创建或打开的文件名
6 X% l- S  x' T# Zmode 访问类型和打开方法,由一下标准的一个组合指定的。
* F! G+ f4 I, _$ X, K. u$ i5 V: x2 i) m7 n) V5 s  o6 H& D

' e/ `  U* K' v; A% i8 d: S模式                      描述  3 l% v; S% u0 r! }4 G
FA_READ   指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问。   ; W. h6 @  c* `) v$ D# i) e
FA_WRITE   指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问。   ; Y  n) {) k9 b
FA_OPEN_EXISTING  打开文件。如果文件不存在,则打开失败。(默认)  
/ w# ~4 w% B9 S/ ~8 vFA_OPEN_ALWAYS   如果文件存在,则打开;否则,创建一个新文件。  ) l+ O  |/ u0 M% U
FA_CREATE_NEW   创建一个新文件。如果文件已存在,则创建失败。   
( L" r' |- r% b: T  P! U" nFA_CREATE_ALWAYS  创建一个新文件。如果文件已存在,则它将被截断并覆盖。
9 f# D* n- [& k# [/ o+ `+ T- r& M$ ^# _' T* d# u; ?! Z

3 K, L5 j- q" J) v3.f_close
& Y: l* I+ b0 l3 K关闭一个打开的文件; o: c$ r: Y  S* e: S1 H7 d
  1. FRESULT f_close (
    ' W, m2 U3 s8 v/ ^# o$ z3 _( G
  2.     FIL *fp        /* Pointer to the file object to be closed */
    7 |/ {$ v% ]0 L% Q7 O; N  i! j
  3. )
复制代码
fp 指向将被关闭的已打开的文件对象结构的指针。- y1 r- z  \: |" x

: ?- r9 R3 i( c! Z. E- U- j, ?

& @/ x( m9 t# i. Y6 A4.f_read4 q7 F  i$ }7 v2 b" T* H
从一个打开的文件中读取数据$ n) n% r8 q  Z/ Q4 g) p" N& n
  1. FRESULT f_read (+ S7 N9 c: T/ x" ?
  2.     FIL* fp,      /* Pointer to the file object */
    # h1 a8 S5 c  n' T$ M. D
  3.     void* buff,        /* Pointer to data buffer */; Z* N0 L/ |4 {- z3 o! b  X  C' x
  4.     UINT btr,      /* Number of bytes to read */# g, @8 j' D9 X. q, R, F9 c6 }+ }
  5.     UINT* br       /* Pointer to number of bytes read */
    8 F4 d8 w; f$ k/ F9 f  w
  6. )
复制代码
fp   指向将被读取的已打开的文件对象结构的指针) E- W6 l3 Y# ~! C4 d
' N2 Z) R; ?  Y+ L0 l% O
buff  指向存储读取数据的缓冲区的指针; k, Y! Q. ?7 k/ ^1 \) i, r
btr  要读取的字节数' Z0 J5 q# o( O4 P8 ]4 h$ ~9 Q0 m
br 指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数。& Z6 c$ N9 O5 j2 h1 q# C' u

7 G3 ~- J, ?. `* t9 s4 M. c) R
3 s1 t! Q3 E, A, U; p  w! e5 S
5.f_write3 e) B& u6 o! w0 T6 R8 K
写入数据到一个已打开的文件
% Y+ l9 y6 S7 y# g
  1. FRESULT f_write (
    ' {+ u8 ?# D: R/ F
  2.     FIL* fp,           /* Pointer to the file object */0 ~( m+ E+ l& t7 M# }" M
  3.     const void *buff, /* Pointer to the data to be written */
    . Z8 ]% a$ m3 T/ f3 I6 t5 @
  4.     UINT btw,          /* Number of bytes to write */% n( j; y+ a$ }. p* a! G
  5.     UINT* bw           /* Pointer to number of bytes written */8 }& ]4 X$ B# E# V4 e$ A$ f
  6. )
复制代码
fp   指向将被写入的已打开的文件对象结构的指针
3 ], ]8 S# L* j, K
2 E2 H3 x! ^% z" L% t7 r- j
buff  指向存储写入数据的缓冲区的指针2 u. W; p' Z( ]
btr  要写入的字节数" N% s6 u% o3 b; f5 m* z
br 指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数。  D; C! \3 q: v' w' Q; L2 s

2 J3 p8 ~, A6 u! l4 f' b/ b

. P+ h( i) u) _, s8 D) V5 }0 {& Y另外FatFs还有很多API操作函数,在这里不再作详细的介绍,详细信息请查看FatFs文件系统官网。& S; a! D+ N; F' Z( d: m$ |5 O5 `

4 x6 s9 U- y. E
5 ]% k( n9 H) e1 n- u4 b

6 J( [# n" Y* @: o6 g4 l: W$ s  T
/ |! `0 o6 z: {+ k/ `3 k

3 D) k8 D& h% ^
) s' r9 B7 H" f4 H: n0 w6 j

  d0 u1 ]! ^6 M& i
$ [/ Q* x7 w1 g& S9 W8 O! M

评分

参与人数 1 ST金币 +10 收起 理由
g921002 + 10 看起來之前的Bug都修訂了。XD

查看全部评分

收藏 评论1 发布时间:2017-12-26 17:53

举报

1个回答
东方惑思 回答时间:2017-12-26 20:46:26
学习中,谢谢!
; W4 f6 I" g/ R$ f6 W1 m

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版