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

STM32CubeMX配置文件系统FATFS

[复制链接]
科技人生 发布时间:2017-12-26 17:53
[转载]STM32CubeMX配置文件系统FATFS2 a( ~2 @: d. I5 s
http://www.waveshare.net/study/article-657-1.html
9 |; K" A" H) G; z(出处:微雪课堂)1 j0 O5 b- N( d0 z8 j
FATFS简介3 J! x( C% r+ I/ [3 y/ y* B
# U) P7 B2 s1 F' n9 k
    FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。它可以被嵌入到低成本的微控制器中,如AVR, 8051, PIC, ARM等等。兼容Windows文件系统。3 ~5 h% z: d8 [; m" `' l
关于FATFS文件系统的API函数介绍,底层移植接口和例程等可以查到FATFS官网。( }+ ^# m7 h" Z5 E

( V+ T* m5 ?  G: S7 j. sFATFS官网:http://elm-chan.org/fsw/ff/00index_e.html
, r# m! ?, P. d* i6 f; d2 I# j

$ n' x' f. @* ?. G# Z4 ?+ W4 a" }9 u
        结合STM32cubeMX软件移植FATFS文件系统非常简单。本章程序在上一章SDMMC工程的基础上修改,复制串口SDMMC的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。在中间件中选择SD卡,在SD上建立文件系统。
5 Z5 q3 @4 L% ?4 q9 k3 o8 K4 R  P
001.png / v( b3 r. q" b, w3 @5 ^$ c6 ~
    在FATFS配置中选择简体中文字GBK编码支持中文,使能长文件名,缓存存储在堆(STACK)中。
* t4 y! }/ z) ^' R 002.png
* ^) A2 k; S+ T  ~, W    点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。
: U* X2 v1 _/ r5 e+ k 003.png
& A9 q+ p1 K9 [" n6 W4 z6 ~  k5 V    生成报告以及代码,编译程序。在fatfs.c文件中可以看到FATFS初始化函数。在bsp_drver_sd.c文件中可以看到SD卡的板级操作函数,包括SD初始化,读写擦除块操作函数。在sd_diskio.c文件中可以看到FATFS文件系统移植的底层操作函数。! n& S% S+ p3 d4 c
004.png
4 }3 g+ P# M5 Y3 V( W3 O) l    删除上一章SDMMC的应用程序。在main.c文件前添加变量。fs为文件系统工作区,fil为文件对象结构的指针。rtext/wtext分别为读写缓存,bytesread/byteswritten分别存储读写的字节数。filename存储文件名(FATFS文件系统配置时使能了长文件名,最长255字节,若不支持长文件名,则文件名最多8个字节)。+ i  q2 t# @2 ~, {) v2 F  Z9 t1 U+ y
  1. /* USER CODE BEGIN PV */
    6 V8 N- p) i; }" k
  2. /* Private variables ---------------------------------------------------------*/# J$ u: n- Z' q& p, ]5 Q2 F) d" }
  3. FATFS fs;                 // Work area (file system object) for logical drive
    7 t4 M0 j0 h& l2 ^% V2 W' Q- }
  4. FIL fil;                  // file objects: y" a( G  j' H, r3 f6 M) N4 Z7 T
  5.   ; C# C( e/ {8 ~$ V, F' \% ]
  6. uint32_t byteswritten;                /* File write counts */; a& h& w' \# X% t1 z
  7. uint32_t bytesread;                   /* File read counts */
    6 K2 F; O! L) y. g; w0 `
  8. uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */, [7 A0 b8 `" X4 L3 @5 O0 w1 [. k
  9. uint8_t rtext[100];                     /* File read buffers */# ]  i1 j0 D' ?8 a
  10. char filename[] = "STM32cube.txt";
    0 o6 \  E4 q# J, _
  11. /* USER CODE END PV */
    # l4 \, ]: |0 x; n( C. S/ f' r0 Y
复制代码
在main函数中添加应用程序。程序中首先注册一个文件系统对象,然后新建STM32cube.txt文件,将数据写文件中再读出来,判断文件系统是否工作正常。
' E  r, g% N$ M, j
  1. /* USER CODE BEGIN 2 */
    3 P- j1 h; N9 w
  2.     printf("\r\n ****** FatFs Example ******\r\n\r\n");
    , Y' v4 H1 _4 G6 h7 B) y
  3. - v% @& h2 B2 r* e
  4.     /*##-1- Register the file system object to the FatFs module ##############*/
    + z) G' r5 u+ |# I
  5.     retSD = f_mount(&fs, "", 0);5 G% q- A) u4 p" S1 g
  6.     if(retSD)  }% G! {0 l5 X) |* w
  7.     {
    : x* I3 R% f$ r: w* X
  8.         printf(" mount error : %d \r\n",retSD);
    / ]9 B. N- ~" x; B6 y% ]3 V
  9.         Error_Handler();9 \& F" q1 O5 @! Z
  10.     }; y. ]* q; P3 ^8 A! @( f1 z: `
  11.     else; i# G1 e( \" X2 ]
  12.         printf(" mount sucess!!! \r\n");
    ; p. n) H* ]0 ~& B% ^
  13.      : L( }8 ?& v( t# S3 m5 K
  14.     /*##-2- Create and Open new text file objects with write access ######*/
    ' h, s# n1 k' h1 s; X- ~' ?
  15.     retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE);2 g3 x/ }% a' \  ~5 W; ^+ E2 F
  16.     if(retSD)
    8 Z8 W' J% i* R! S8 i1 J# X
  17.         printf(" open file error : %d\r\n",retSD);5 i1 U# \7 D+ Y( u. b" J% K0 p
  18.     else0 B$ N: W( B0 ?5 ?% j/ s$ |
  19.         printf(" open file sucess!!! \r\n");
    * r9 ]: Z3 ?2 ]" [; ~
  20.      
    % P! T* J  S2 h
  21.     /*##-3- Write data to the text files ###############################*/
    / ]) E, B! u% f+ y6 k, c4 G3 S
  22.     retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten);
    & `; G- f* m) k" c0 v9 V
  23.     if(retSD)  @2 o4 _6 W" x9 [1 E0 a
  24.         printf(" write file error : %d\r\n",retSD);
    8 v- i( y, Q- @3 I3 o2 A9 w
  25.     else
    ) g/ r5 w  ~" }8 C9 n, A
  26.     {" @$ @: ~/ c( p6 M
  27.         printf(" write file sucess!!! \r\n");
    8 Q" j" r: H0 ?( g2 a4 Q. l
  28.         printf(" write Data : %s\r\n",wtext);$ ^/ M3 g) n" \/ e- n
  29.     }7 j* p& \3 D4 d1 [* \2 |% C
  30.      * K, b& N9 p" t# e
  31.     /*##-4- Close the open text files ################################*/( W6 ~  g8 f5 G; J0 z1 j
  32.     retSD = f_close(&fil);
    , V% o7 x0 W  V  J
  33.     if(retSD)2 O8 q% A. T8 ]6 i2 e" z
  34.         printf(" close error : %d\r\n",retSD);- j' F8 ?2 d4 Z4 y4 W% S
  35.     else
    + ?4 s( y# C- C0 C, l
  36.         printf(" close sucess!!! \r\n");2 M7 @; d! u6 w$ N# f; `# P, P2 O
  37.      , F; A- W  R- o; j
  38.     /*##-5- Open the text files object with read access ##############*/4 V) V& j9 L5 T9 K; r
  39.     retSD = f_open(&fil, filename, FA_READ);1 g' B0 ]& ~" e$ l5 ]) |
  40.     if(retSD)6 i, `! t- ]8 b  x2 u
  41.         printf(" open file error : %d\r\n",retSD);, F% ]9 g2 |: e% F( H$ i* {9 G
  42.     else
    ; e  O7 k2 S) w$ E
  43.         printf(" open file sucess!!! \r\n");
    " `/ t7 U5 V$ W! |+ w/ s, M
  44.      . q$ S) C4 ~! p# g8 l) R; O% ?
  45.     /*##-6- Read data from the text files ##########################*/5 m$ d' Y/ p# s, G# b
  46.     retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread);
    " E- Q. q! ]' M; h; f7 m, R
  47.     if(retSD)$ m# ?  h/ ^, R' P6 p$ ?1 s
  48.         printf(" read error!!! %d\r\n",retSD);
    4 v1 C3 g0 g6 V/ ^. F5 e
  49.     else
    3 a, D2 `! t1 {# |+ u
  50.     {
    ' P0 D7 k# X# \, [' B# [
  51.         printf(" read sucess!!! \r\n");* S3 Y. F1 e! F
  52.         printf(" read Data : %s\r\n",rtext);
    2 U5 |* Q0 v. v# _- `. N. z* {
  53.     }
    8 L! C9 p# Z: D
  54.      / S2 C8 [- y8 v, ~
  55.     /*##-7- Close the open text files ############################*/) h5 U; A8 ?) }' e1 C4 c
  56.     retSD = f_close(&fil);& Q3 d+ F. H, ~
  57.     if(retSD)  
    8 i" R" g* u# s# C  Q/ T
  58.         printf(" close error!!! %d\r\n",retSD);5 r5 j. D2 m( ~
  59.     else
    2 U1 s: l* H. j) c* W
  60.         printf(" close sucess!!! \r\n");' b" P3 r- V3 Q: \/ N) `: m
  61.      ' f( w5 P$ _0 l* j" \
  62.     /*##-8- Compare read data with the expected data ############*/
    0 |1 W  H1 `8 _0 G$ u) e$ w
  63.     if(bytesread == byteswritten)" C* d! p5 ?: n8 }, ~
  64.     {
    $ _5 {* J/ |9 |
  65.         printf(" FatFs is working well!!!\r\n");
    2 w% D! U4 v% j
  66.     }
    ' T; V; |$ ]% \2 r
  67.   /* USER CODE END 2 */
复制代码
在main.c文件后面添加错误处理函数。

* Q! |0 v: G( @3 Z! Y6 ^
  1. /* USER CODE BEGIN 4 */
    / Z" Q3 T7 ]5 S) v7 D
  2. static void Error_Handler(void)
    & H* L4 F9 ]  k# B& E5 O) o
  3. {1 u1 I( c. I- F+ I
  4.   printf("something wrong ....\r\n");$ d- f5 N9 [8 D2 w
  5.     /* User may add here some code to deal with this error */
    + F( f, m8 k# Q6 n7 N6 ]9 A+ U# n( ]: Z
  6.   while(1). |' t8 m+ d# W: A$ l. ]( X
  7.   {
    9 f; W: O$ v- l, l
  8.   }, F/ [% t) \7 i( S; t5 [
  9. }
    9 m0 Y! y& Y. _/ j& w" Z5 O  b, r
  10. /* USER CODE END 4 */
复制代码
在main.c文件前面添加错误处理函数声明。
  v4 G, H$ P- t- O
  1. /* USER CODE BEGIN PFP */9 E- z9 I7 i! {) P0 y; N1 L
  2. /* Private function prototypes -----------------------------------------------*/
    - V, e8 M1 a0 r( I, \- i* o
  3. static void Error_Handler(void);
    0 X/ u$ g! v. T7 S; N4 j0 Y& G
  4. /* USER CODE END PFP */
复制代码
编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。

% N4 l4 y+ z/ s$ k# G7 a 005.png
5 G  Y( ?% O" N: L下载简介一下FATFS的几个操作函数。
) g0 B; L3 G  Z% S- z5 V1.f_mount
4 n3 a4 F6 e5 A7 z在FatFs模块上注册、注销一个工作区(文件系统对象)。/ l$ A1 G& l, K" X
  1. FRESULT f_mount (
      L. `0 }  s' Q
  2.     FATFS* fs,         /* Pointer to the file system object (NULL:unmount)*/
    ; ?# W, X, ?- u2 l
  3.     const TCHAR* path,    /* Logical drive number to be mounted/unmounted */
    ; V0 f0 f  w, R4 J# B
  4.     BYTE opt           /* 0:Do not mount (delayed mount), 1:Mount immediately */
    - v# O1 B! L6 y: I% `
  5. )
复制代码
参数
7 j  Z$ P  ?6 Z* `+ l# g- J5 Zfs 工作区(文件系统对象)指针
/ d  U1 Y' u9 \. p; B$ ypath  注册/注销工作区的逻辑驱动器号( D8 U7 x$ X* l( w9 s# O
opt      注册或注销选项
/ ?3 O3 ~: x' \2 x
& }$ {( q2 P6 y6 @6 Z
9 c5 Q, Q+ J7 S5 w/ t

: E* d: N) t# j9 ]; b
& _6 A' j! U7 q  [
2.f_open$ ]: U& s) @/ S4 r: b
创建/打开一个文件对象
& F6 n/ V. r1 ~: @# G. P0 x
  1. FRESULT f_open (
      q" ~' d) N, r1 \2 a
  2.     FIL* fp,           /* Pointer to the blank file object */6 X( o4 D2 H/ P7 C1 l( r& A
  3.     const TCHAR* path,    /* Pointer to the file name */! J# p0 g3 N) c5 n) ~% d0 O
  4.     BYTE mode          /* Access mode and file open mode flags */4 \3 z9 `7 v; `8 Z  x
  5. )
复制代码
fp   将被创建的文件对象结构的指针) m  T8 t6 d* {6 o
path  文件名指针,指定将创建或打开的文件名) b& B( K, V( x7 i
mode 访问类型和打开方法,由一下标准的一个组合指定的。, ^! m9 n* K8 {* d

0 Y7 D# w' u5 d* v6 v
+ X& K2 g# O+ o+ C# |: l
模式                      描述    A8 K9 }' p/ Y
FA_READ   指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问。   " M. k, N* h, ^' k
FA_WRITE   指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问。   
" c! V8 _  b& d: \4 l  \& ZFA_OPEN_EXISTING  打开文件。如果文件不存在,则打开失败。(默认)  
1 L1 ~: U6 ^5 a0 J( n) Z8 g' KFA_OPEN_ALWAYS   如果文件存在,则打开;否则,创建一个新文件。  
6 m1 J& x# L. _7 D" LFA_CREATE_NEW   创建一个新文件。如果文件已存在,则创建失败。   + y& |2 D7 V# J
FA_CREATE_ALWAYS  创建一个新文件。如果文件已存在,则它将被截断并覆盖。5 i+ j- y, G& E6 I+ b# F

# k3 f1 w. E: m' q7 s* y

9 O+ i  c/ d; A  F3.f_close
) D) y' p. c  [( J" ^关闭一个打开的文件
1 q( @, t: M* @  Q" \: X! H6 N
  1. FRESULT f_close (4 ^1 }" E2 k8 l4 z" o# z' m
  2.     FIL *fp        /* Pointer to the file object to be closed */
    : s+ ?" O. _- M: [" _0 B
  3. )
复制代码
fp 指向将被关闭的已打开的文件对象结构的指针。
/ I& r$ z4 m5 R0 F+ h* N* g' m$ k- i" Z

6 P$ f& E- o' ]- G( Z0 Y4.f_read, A6 a' J7 N* `) _4 u
从一个打开的文件中读取数据# x" \9 A$ x1 z
  1. FRESULT f_read (% k2 f3 Q1 Q( U1 C! }0 |. C
  2.     FIL* fp,      /* Pointer to the file object */9 Q! B2 `& c0 H3 g$ B
  3.     void* buff,        /* Pointer to data buffer */. e4 J3 I3 P1 p$ \
  4.     UINT btr,      /* Number of bytes to read */
    & y7 M, o$ v7 j* T2 A
  5.     UINT* br       /* Pointer to number of bytes read *// \3 Y3 S2 Q' P  t
  6. )
复制代码
fp   指向将被读取的已打开的文件对象结构的指针: _6 h  {. V+ {5 ?2 f

; Z, S( `' X, \- V& A8 S! [buff  指向存储读取数据的缓冲区的指针4 {1 R! u" Q1 d
btr  要读取的字节数0 o4 S: n; I  y9 E. w% P* L4 G
br 指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数。. ]- P4 Q$ ~5 o+ c' ~
6 c# Y. S/ j7 ~' e1 s) Z5 P

' e" h7 [# F- z1 ^/ s" Y0 D2 Y5.f_write/ [- `; e7 c, d8 N1 v5 d  b! \
写入数据到一个已打开的文件$ ^/ l, B# f) c, w) L2 A! R' L! f
  1. FRESULT f_write (  ~0 d. p" Z& e
  2.     FIL* fp,           /* Pointer to the file object */; ^* o8 v0 ?2 n' n/ ?3 f
  3.     const void *buff, /* Pointer to the data to be written */
    - [- ?$ S4 [' L5 ^
  4.     UINT btw,          /* Number of bytes to write */
      D9 l* [2 }- z7 _8 `, R+ U
  5.     UINT* bw           /* Pointer to number of bytes written */
    - p2 _# K, t# z" ?, W
  6. )
复制代码
fp   指向将被写入的已打开的文件对象结构的指针
! c. E' d' l0 ^/ u
$ j2 @) f/ d6 S% K
buff  指向存储写入数据的缓冲区的指针6 o' r* v) y) e( x4 }& k4 E6 ]3 G
btr  要写入的字节数9 Z3 R. P4 s4 P; B" e! _
br 指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数。
- M6 r- }+ Q0 e9 r, L( ~+ A  q6 l5 z4 q$ e- r
: O( W' X+ h& h/ r2 Z6 U
另外FatFs还有很多API操作函数,在这里不再作详细的介绍,详细信息请查看FatFs文件系统官网。7 Q2 Z4 A9 v5 x* w% C

5 T* n/ r2 ~3 D) l3 @) s* M5 C, g! X

# y' Q% Y& q. D" {

3 M6 J3 O# Q+ U3 u/ X& F+ W2 _
, D$ f$ X2 p3 j' S
6 [# B% ~/ m! _; M2 E/ V

/ c3 M0 r' |8 d1 J5 D, |3 E/ |* d

9 L, c3 a( p, b9 s" }4 U
$ A- [8 C4 z+ ^1 w  ?2 ]6 K

评分

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

查看全部评分

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

举报

1个回答
东方惑思 回答时间:2017-12-26 20:46:26
学习中,谢谢!
) f# s% L- z0 f
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版