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

STM32CubeMX配置文件系统FATFS

[复制链接]
科技人生 发布时间:2017-12-26 17:53
[转载]STM32CubeMX配置文件系统FATFS
$ w9 g! x- }4 r$ _http://www.waveshare.net/study/article-657-1.html
" V; T3 S+ a5 ]$ S+ L(出处:微雪课堂)
6 ]5 i6 K+ V: V& jFATFS简介
6 [1 S: ~% v& X  e3 N: X$ [) c9 @+ D5 i
    FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。它可以被嵌入到低成本的微控制器中,如AVR, 8051, PIC, ARM等等。兼容Windows文件系统。5 t3 {) b6 U, |9 u) F( Y9 Q
关于FATFS文件系统的API函数介绍,底层移植接口和例程等可以查到FATFS官网。4 |' ]' N! I/ Y) ]/ L2 I

4 s3 w" P$ J4 Z2 _4 M3 jFATFS官网:http://elm-chan.org/fsw/ff/00index_e.html  ^! e  [$ s* w( |' Z0 @

# k8 q. A/ _+ s0 {9 x( c# ]6 d
% p4 B: X4 x! j( M$ |        结合STM32cubeMX软件移植FATFS文件系统非常简单。本章程序在上一章SDMMC工程的基础上修改,复制串口SDMMC的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。在中间件中选择SD卡,在SD上建立文件系统。: Y' ]5 }: u4 P7 n, p3 s/ j

1 _2 c4 `# r1 S' }" s/ z 001.png & R# f7 ~8 H3 {% |5 Z
    在FATFS配置中选择简体中文字GBK编码支持中文,使能长文件名,缓存存储在堆(STACK)中。
/ h/ l% ~9 G. ?  [- b: G 002.png # z5 O5 R& j/ L1 j3 c
    点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。
+ f. B9 J2 S$ z7 f; ^: j" L; U 003.png
* R) T0 H$ ^  E8 k( k" k    生成报告以及代码,编译程序。在fatfs.c文件中可以看到FATFS初始化函数。在bsp_drver_sd.c文件中可以看到SD卡的板级操作函数,包括SD初始化,读写擦除块操作函数。在sd_diskio.c文件中可以看到FATFS文件系统移植的底层操作函数。% Q  k0 E4 [" w$ `" C
004.png
1 H: A  |- `8 S' @' K    删除上一章SDMMC的应用程序。在main.c文件前添加变量。fs为文件系统工作区,fil为文件对象结构的指针。rtext/wtext分别为读写缓存,bytesread/byteswritten分别存储读写的字节数。filename存储文件名(FATFS文件系统配置时使能了长文件名,最长255字节,若不支持长文件名,则文件名最多8个字节)。
* T& w0 Y1 |" S" }+ |  j
  1. /* USER CODE BEGIN PV */
    6 ]0 q% O' z: [+ Q  q( J/ j
  2. /* Private variables ---------------------------------------------------------*/$ l/ K% b0 f- C( i8 m4 c
  3. FATFS fs;                 // Work area (file system object) for logical drive6 y- B- Y( _+ H' d
  4. FIL fil;                  // file objects$ H" u6 J! A% X; k
  5.   
    1 U% r3 v8 G2 V& o9 }6 z
  6. uint32_t byteswritten;                /* File write counts */
    $ d, e/ C8 M2 `" P
  7. uint32_t bytesread;                   /* File read counts */
    3 K: \) Y5 {3 p$ v) k, h
  8. uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
    " Y2 W+ ?0 n+ ]
  9. uint8_t rtext[100];                     /* File read buffers */
    6 c3 b$ }& i/ P9 b9 t) r- s
  10. char filename[] = "STM32cube.txt";
    - |' m$ W4 ^( F6 m( R- M
  11. /* USER CODE END PV */
    ; J7 `  @; p; h) @
复制代码
在main函数中添加应用程序。程序中首先注册一个文件系统对象,然后新建STM32cube.txt文件,将数据写文件中再读出来,判断文件系统是否工作正常。

$ x8 O; V7 Y. m
  1. /* USER CODE BEGIN 2 */' |3 l; b, t* `2 e8 i. z9 x
  2.     printf("\r\n ****** FatFs Example ******\r\n\r\n");
    , y6 _$ V/ l3 E' I
  3. , X6 G8 |4 u% U( _5 Q
  4.     /*##-1- Register the file system object to the FatFs module ##############*/
    , W# D* z$ q: ?. s* x
  5.     retSD = f_mount(&fs, "", 0);
    8 @& C+ y, S: r% c, @( `+ C' _5 |
  6.     if(retSD)
    + y: t* i3 p1 t$ T
  7.     {
    - @: E: k/ c, Z8 w6 X$ I. u1 C
  8.         printf(" mount error : %d \r\n",retSD);* P* Y) n4 V: c4 }( P
  9.         Error_Handler();
    , e2 }; Z- D& E1 E# y
  10.     }! @. q3 U1 e, V% a
  11.     else2 d0 h, B, B8 e, h8 {) x" z7 g7 T
  12.         printf(" mount sucess!!! \r\n");  j% F/ \3 ^& v; v
  13.      
    / I$ K1 e- Z' {3 u  v, h/ R
  14.     /*##-2- Create and Open new text file objects with write access ######*/; x( I& Z% `9 |$ u) m; T6 |; l
  15.     retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE);
    ! h5 j& n! M' T; w" P" N) {% }9 E* W
  16.     if(retSD)
    - F( |9 N# h3 G
  17.         printf(" open file error : %d\r\n",retSD);
    , Y7 m8 W# P5 V) `) r
  18.     else
    ! a7 }6 v% Y( U
  19.         printf(" open file sucess!!! \r\n");
    6 b4 T% l# }# D
  20.      ; u2 {% f+ P- y3 h
  21.     /*##-3- Write data to the text files ###############################*/$ i9 W0 a* p7 B) ]' J* Q1 H
  22.     retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten);1 l8 q7 T0 ~2 f7 \
  23.     if(retSD)
    0 @( O+ m: t: t& P- Q8 ~! Y! q
  24.         printf(" write file error : %d\r\n",retSD);
    6 k0 i1 f3 ]  p: B
  25.     else! B1 |5 G+ T2 r# H1 d2 C# p
  26.     {+ t3 {9 F) S% d; J7 q2 I) W
  27.         printf(" write file sucess!!! \r\n");
    7 @3 B- j1 O. J( \1 }
  28.         printf(" write Data : %s\r\n",wtext);/ W% d& c0 z9 r8 P) R; u
  29.     }
    2 h3 n" G, U0 c' m' w- K
  30.      
    # C3 \" i' m: n& |" k0 e) P
  31.     /*##-4- Close the open text files ################################*/, ^1 X/ p0 _2 O6 d
  32.     retSD = f_close(&fil);
    ! i* U0 x. g0 e5 {: G
  33.     if(retSD)
    + U- @- _+ G2 y" @. f( [( }
  34.         printf(" close error : %d\r\n",retSD);
    1 D' c7 r, Y' k1 i* A. O2 e
  35.     else
    0 l- a9 z- W( Z& e
  36.         printf(" close sucess!!! \r\n");
    9 z! t) ~0 j$ a- ^! f0 w
  37.      
    6 Z: }5 q! w/ [$ h. M2 C# S: \$ U
  38.     /*##-5- Open the text files object with read access ##############*/
    8 d) y3 j: D6 m7 N
  39.     retSD = f_open(&fil, filename, FA_READ);
    , m# ?8 M9 u* f  Y# U6 L
  40.     if(retSD)
      H" v6 d* O0 I7 J9 ~. m+ U
  41.         printf(" open file error : %d\r\n",retSD);1 Z+ N* y# J  E4 W
  42.     else" Z/ J2 ~0 G, t) i( f
  43.         printf(" open file sucess!!! \r\n");
    / G* @# T0 _6 l/ V5 S, D4 k
  44.      
    & H- s% m4 Q5 L
  45.     /*##-6- Read data from the text files ##########################*/
    + ~9 I5 G4 M$ w
  46.     retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread);/ n+ D4 E& O, S/ P
  47.     if(retSD)
    $ V- X; y" o4 Q: d6 {/ e" w
  48.         printf(" read error!!! %d\r\n",retSD);
    3 V6 A+ K! R* O$ }5 c5 Q
  49.     else7 z  ?& Q2 V; p4 }
  50.     {3 k' x: G/ _7 `  N# \
  51.         printf(" read sucess!!! \r\n");
    ' B1 H7 G2 q, j# [8 X
  52.         printf(" read Data : %s\r\n",rtext);
    % u1 o, D! ^& \& U; @
  53.     }
    6 {% Z. p/ q4 B
  54.      
    ' p8 v# E3 ~, g8 A% n. f6 K3 a' ~
  55.     /*##-7- Close the open text files ############################*/
    # v" `4 ]% O8 N
  56.     retSD = f_close(&fil);5 H2 y! W1 |' @' l% N
  57.     if(retSD)  
      w7 D8 E2 ^2 y, Q. @
  58.         printf(" close error!!! %d\r\n",retSD);' o: e" r$ |1 V8 b
  59.     else6 ^& u  q1 c" ^# V7 C9 d' w
  60.         printf(" close sucess!!! \r\n");
    , {% |  J6 L: @6 J3 h  R
  61.      1 v. o5 E+ L8 \# A1 @/ \
  62.     /*##-8- Compare read data with the expected data ############*/
    : k9 s( I% T  a# }
  63.     if(bytesread == byteswritten). y% Z) e! c& n  S) _2 {. x
  64.     {
    : g6 B& T2 v2 }( n9 ^& \2 W
  65.         printf(" FatFs is working well!!!\r\n");5 I. M) L5 X( K" x0 Y
  66.     }  r% j+ ~0 N4 M, y9 {9 I
  67.   /* USER CODE END 2 */
复制代码
在main.c文件后面添加错误处理函数。

9 N8 d$ ~) C6 ]4 T+ i& j$ h
  1. /* USER CODE BEGIN 4 */
    8 h( C8 u# J# k  S# I
  2. static void Error_Handler(void)
    3 @7 A2 H) Z; U$ w. S2 M
  3. {4 T& A2 d( ~$ Z
  4.   printf("something wrong ....\r\n");
    " c9 _3 c# W6 z9 K+ X& Z
  5.     /* User may add here some code to deal with this error */5 B7 n2 ~$ }, k: p+ O
  6.   while(1)1 q4 d  L4 K6 p$ g) H: k+ s7 v* O
  7.   {
    7 V9 ?& ?  ^* s5 C. q/ x" ~: }: ]
  8.   }9 A( v6 {% D% r; Z) j" H! \
  9. }
    & u8 G/ m) n3 f5 o
  10. /* USER CODE END 4 */
复制代码
在main.c文件前面添加错误处理函数声明。
2 G" K2 f% d6 |3 h% n$ ]- B1 X) w
  1. /* USER CODE BEGIN PFP */) ~: ~% ?3 q( t, ?- P! v' I3 G
  2. /* Private function prototypes -----------------------------------------------*/+ T3 l: b' Y; j+ B$ s/ ?& w% c/ B
  3. static void Error_Handler(void);
    : A2 B: ^- u. u' z! W
  4. /* USER CODE END PFP */
复制代码
编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。
. b* n* |3 {7 e" j& S
005.png / ^, F) k- Q0 g, I2 j7 ?7 D& D
下载简介一下FATFS的几个操作函数。
% p7 [, e+ K- V/ l1.f_mount
7 _2 D; w8 s$ K在FatFs模块上注册、注销一个工作区(文件系统对象)。( }  H! J0 J: {6 r) E8 f* P
  1. FRESULT f_mount (. {6 W! G' d: }. |4 h. @# O6 p
  2.     FATFS* fs,         /* Pointer to the file system object (NULL:unmount)*/
    : P' `2 T9 I- \! l, a
  3.     const TCHAR* path,    /* Logical drive number to be mounted/unmounted */4 ]* p& |" u) {1 u: A" C- ]
  4.     BYTE opt           /* 0:Do not mount (delayed mount), 1:Mount immediately */
    - {+ L) \, M" F' E' q8 ~
  5. )
复制代码
参数0 o  B# g- @+ e
fs 工作区(文件系统对象)指针
& R$ ~0 _: ^) npath  注册/注销工作区的逻辑驱动器号
- I! A) Q1 Q6 h. x1 H# e/ zopt      注册或注销选项
* h* k4 S: j  Z% ~: F% R  ]7 x5 z8 T! |4 x# W( ~% \1 V1 t+ K
5 i6 F; N/ z  i$ f2 X

0 ^$ T$ y+ N$ j8 m3 i/ d

8 f0 ?6 Z8 U- ?* D2.f_open
2 X1 S; f; S# c( H创建/打开一个文件对象( @) f# k, o0 a* Q, ]8 V4 {3 `: o
  1. FRESULT f_open (- N7 ^0 J' D. T/ L
  2.     FIL* fp,           /* Pointer to the blank file object */4 l" S7 L$ r/ W" \/ y8 n
  3.     const TCHAR* path,    /* Pointer to the file name */& k. Y" ]' `( t3 C
  4.     BYTE mode          /* Access mode and file open mode flags */& ~5 m: f, O+ f' D8 R' j+ d$ l
  5. )
复制代码
fp   将被创建的文件对象结构的指针) M6 c& h! Z: v2 |
path  文件名指针,指定将创建或打开的文件名
8 Q+ ?' U6 e0 G6 d6 t9 n2 |mode 访问类型和打开方法,由一下标准的一个组合指定的。0 I% _9 F9 R4 O
+ `. F$ B* o4 y( ^+ x9 s
% b  G6 g3 N/ X/ Q7 h
模式                      描述  5 ]- J  t# ?! |$ j6 m& R. A- }0 D5 b
FA_READ   指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问。   ) v  Q7 z; s  s' ]/ V8 I% |
FA_WRITE   指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问。   
* t" w1 D9 ]$ S' ^# _FA_OPEN_EXISTING  打开文件。如果文件不存在,则打开失败。(默认)  $ u& c5 I" h, W- K% \9 m
FA_OPEN_ALWAYS   如果文件存在,则打开;否则,创建一个新文件。  
/ ]5 K+ Q; l; ~, U/ oFA_CREATE_NEW   创建一个新文件。如果文件已存在,则创建失败。   ; D( X) }8 R6 l# m# j% c$ s/ p
FA_CREATE_ALWAYS  创建一个新文件。如果文件已存在,则它将被截断并覆盖。' x! S: n" @/ ^- A
' p1 `/ w% S% ]" B+ A. R
7 _* v. S0 Q; i
3.f_close
1 u- i" ]  _. i" i关闭一个打开的文件
& H& `7 p1 v- m- y
  1. FRESULT f_close (* w1 G- r& x/ M3 ?6 R: B8 k4 ?
  2.     FIL *fp        /* Pointer to the file object to be closed */( v( I0 v( I) `8 c" R4 N
  3. )
复制代码
fp 指向将被关闭的已打开的文件对象结构的指针。
2 p0 @1 m- x! L* ]# D7 t: |+ c8 r, H, v( @* W/ g2 o/ R' H
  G0 S& w/ s4 Z& f5 y/ ^
4.f_read
; t( H' f: }1 {1 u% |: k8 g从一个打开的文件中读取数据
6 @% q+ a/ i  @, Y
  1. FRESULT f_read (5 X5 H) s1 F3 T2 O3 [) p
  2.     FIL* fp,      /* Pointer to the file object */; U0 a* m5 p6 r+ I! p  ~
  3.     void* buff,        /* Pointer to data buffer */
    1 h( _/ Z! B/ S# m
  4.     UINT btr,      /* Number of bytes to read */
    8 o* V3 G& @6 T1 g$ p+ T. J
  5.     UINT* br       /* Pointer to number of bytes read */, }0 d* w4 u- P8 ~
  6. )
复制代码
fp   指向将被读取的已打开的文件对象结构的指针
" K0 i7 \  [4 G+ G- y" k, D3 w2 Q
6 z6 ^5 c* B) \: C1 T7 i/ Z$ i
buff  指向存储读取数据的缓冲区的指针$ L2 X" R" V+ o
btr  要读取的字节数
1 x# H9 Q' D7 zbr 指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数。
9 v4 h. y0 L! n) ?2 p) g" ?; @  c. a. F  U3 ~
1 H: Z. Q" e; k+ m3 U6 I% T3 ~
5.f_write$ B' {, W7 w5 f8 c9 G
写入数据到一个已打开的文件
# \) b" M5 L! N' o' Q+ s/ k
  1. FRESULT f_write (& g: ]8 E8 l7 u  f9 \9 n# h
  2.     FIL* fp,           /* Pointer to the file object */
    5 `! B, I2 c9 {# y
  3.     const void *buff, /* Pointer to the data to be written *// _/ a9 i$ e1 }6 V
  4.     UINT btw,          /* Number of bytes to write */
    ; l+ U2 T: D2 v! t! o7 K
  5.     UINT* bw           /* Pointer to number of bytes written */
    1 K: f/ M% Z# t. ?
  6. )
复制代码
fp   指向将被写入的已打开的文件对象结构的指针
. _. i# J0 q' Z1 N- Q3 z3 e
; i5 h1 V; [4 q' {+ n6 M
buff  指向存储写入数据的缓冲区的指针; o8 n  B2 N5 }; N7 X. h
btr  要写入的字节数
( d6 `6 r0 h; _, x- mbr 指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数。
+ U6 T+ o: g( X! F2 f! F9 C* [# ]+ d, h3 I1 x

! f2 i5 x* z+ K- ]6 |" j/ X另外FatFs还有很多API操作函数,在这里不再作详细的介绍,详细信息请查看FatFs文件系统官网。2 `- P4 K1 _% U& ?7 d3 N

% h& J, m' }4 |, t9 ]5 K
0 t' o: G' c! y6 e. N

) G" F3 o5 F& Q+ m; a

# o1 R4 @, o9 q5 L8 i1 T" h

+ |7 `1 G) t& {' R  O
5 K& r, n7 L' \+ ^2 j  F

6 B2 c; g: m) y: V2 M. I" H% Y

2 T* `, N1 T& ?3 b7 K

评分

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

查看全部评分

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

举报

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