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

【经验分享】STM32CUBEMX--Flash读写

[复制链接]
STMCU小助手 发布时间:2022-4-30 22:15
概述
+ W! A& y5 B% y+ W1 t本例程主要讲解如何对芯片自带Flash进行读写,用芯片内部Flash可以对一些需要断电保存的数据进行保存,无需加外部得存储芯片,本例程采用的是STM32F030R8T6,64K大小的Flash。
+ C) A& k5 v; ~0 c1 \, a  T6 i5 z6 N8 [  e  D
硬件准备
, y. l  i( Y0 a+ B首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:3 n  Q% o* X# C2 c) Q5 y$ c8 o
' H! Z; e+ w/ w
MSJXH{](V}{TTYGU_%HTU62.png & N# l3 T$ w! `0 m6 g

0 @; Z* |8 `0 A% `2 j2 e选择芯片型号# R9 O5 Y/ C  u8 y$ A/ M
使用STM32CUBEMX选择芯片stm32f030r8,如下所示:+ e8 H9 F1 O1 y* m! F8 t' ^
) @) R, U$ E& l0 Z7 w% Q* W) t
IV{O2PQRX~Y52_LYL4~8ZG0.png 1 z9 ^+ P4 b* `4 R2 t5 A& I7 S
' u( v+ P9 Z4 F9 F) q
配置时钟源* F0 Y( l1 o" X
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:) Y  l4 ~; ]% [7 B
' X1 L3 U' R6 {. U" F- B
BSOPI4B}@%(3@Z_E)U~C(IH.png
9 A% j8 T. _9 w) T" a# n
) `5 N9 x/ n' {5 f* O配置时钟树
& \8 n4 S8 q- x, ~* d( C0 N9 jSTM32F0的最高主频到48M,所以配置48即可:* w9 u' A( N1 C

; ~: a* |- q0 P ENVUG74`Q)0R{[CM`T8X5.png * U' J6 d6 t6 d- ?) w5 D

* Q! p$ a3 z: d% O1 Z串口配置
, C+ Q( I2 }& b) r% a6 S本次实验使用的串口1进行串口通信,波特率配置为115200。. [+ d, ?- x2 I8 J# w. @( K- H
2 e6 m! x$ L' x; Y
WZ8LCE]}IB3XV[8E29A_J3B.png $ |1 K" T- m0 G6 t# {+ a& L

5 u% g5 J2 Z- a! ^# V: p7 u: z生成工程设置
  g3 f0 i) O7 T1 U: |, N' ]
注意在生产工程设置中不能出现中文,不然会报错。
, n1 g# _5 H* z6 X# e
  r8 q& Y! ~* \: K( E/ h" w9 L X3GSDQ3K@ZY`6B)U%S4QF.png
$ C- `7 E4 R. o9 G% E' i, `: w: ?- g5 o- [
生成代码

& \4 J2 {* ^& E, `( N
+ ?0 C! o4 b! d; W: C4 O5 X PME@)UWAQK_NL55NE_5[C.png # l- n' g) x8 r2 [
6 @3 U* k# g$ X' _8 x6 E, W
配置keil

4 _7 B7 p5 Z/ J
5 |8 e. n* @4 P8 G! H' N+ w [F1FA0J(LV1MSL([7$FAH$K.png
" q: m/ h+ v& p( a" ?6 c! B
# |. v) w' A. M4 a+ ~% D代码
, N" u4 D5 O- ^, u  ~在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
* h; Q* n/ G* h! H3 s9 w* l
8 \8 X- J. E# B  r+ r9 j; G
  1. /* USER CODE BEGIN Includes */
    , B$ ]1 H1 M4 L
  2. #include "stdio.h"+ L- k) m" I' D% z7 q
  3. /* USER CODE END Includes */
复制代码

, Q" g" @2 r; Q* \函数声明和串口重定向:
8 B! R8 C/ O) l; K# H) I; M# A
3 ]$ s/ [' n, N4 C0 ?* H% z% K
  1. /* USER CODE BEGIN PV */
    6 e$ p- D/ i. L
  2. void WriteFlashTest(uint32_t L,uint32_t Data[],uint32_t addr);//flash写函数0 V4 h0 x! U+ v8 S7 T% g9 `- j. ]
  3. void PrintFlashTest(uint32_t L,uint32_t addr);//flash读取
    9 k+ G: C" O  ~' D3 b; C2 ~
  4. #ifdef __GNUC__* H* ~8 l  ^+ H; C" x& D
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    ! n: }! Z) A7 u6 O) ]
  6. #else
    : `- _: E! I: P! p! b
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)5 g* N' L6 g! ~( Y. x
  8. #endif /* __GNUC__ */: j8 _% e) z' @( p: C9 \& D0 Y" Z

  9. # y- G4 M. |( r4 L5 ~* d* @  D" ]5 y

  10. 6 B$ s) i0 Z; B
  11. int fputc(int ch, FILE *f)
    / F* C, l/ z  X8 ~3 g
  12. {
    6 c8 O3 r& m: |# u; v! R: W
  13.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1, 0xFFFF);5 X; k% e9 m$ _
  14.     return ch;2 z2 W- T( ]- N: N6 J
  15. }
    ) {! Q3 N! ^2 ]0 Y: P2 t- V3 {
  16. /* USER CODE END PV */
复制代码
3 j4 b& f0 S& U; Q
变量定义:
. e, p# D3 @7 \& E5 t: \5 Q7 [9 |$ A9 G# c7 C
  1. /* USER CODE BEGIN 0 */
    $ Y! f% S! R( J
  2. uint32_t WriteFlashData[3] = {0x11111111,0x22222222,0x33333333};//数据- S$ n# Q/ N2 ~/ M, _( _
  3. uint32_t addr = 0x08007000;
    1 K; X! M5 k( `; ~" N
  4. /* USER CODE END 0 */
复制代码

! p/ Q$ W$ Z' S7 D如果要对FLASH进行写入数据,需要执行以下四步:
2 |* Y7 K" J3 F( U9 c) A& a. y7 e3 S& J5 t
1.解锁FLASH* A8 s; p2 H6 s
2.擦除FLASH
( k. R7 I) s# {+ U/ n1 R3.写入FLASH
  @4 y, Q# ?  O1 W* g4.锁住FLASH
5 ^; ?3 x# J/ q! o擦除只能是按页或者整块擦除。
/ x% E+ ?- U; X" V( }2 Y( `9 b* l
STM32F030芯片内部的Flash存储器内存分布如下:
. a/ f3 d) b% j* V# V2 @% I5 z2 A2 J, V1 h
CB7FYK)%SVFSVM_S37P]H$D.png   p2 I; A) x7 ^% g1 |; K& q% _

* w& U. T4 l' X* J! V' M6 t$ [0 SSTM32F030R8T6的Flash容量是64KB,所以只有63页,每页1KB。
8 q  ~' P0 b! ]) O* c我们可以写入到页60中,即0x08007000-0x080073FF中。
  M0 ^0 ]- ?$ a9 l# y8 H/ P由于单片机是32位,故连续写入多个uint32_t的数据时,地址应该依次增加4。
7 I* I& O: h: O
8 ?# _$ y! J* r& F
  1. /* USER CODE BEGIN 4 */! V* N8 F! T2 }

  2. # g7 C6 W" }! w! o8 v9 g
  3. /*FLASH写入程序*/1 H$ o  i) M* Z' {
  4. void WriteFlashTest(uint32_t L,uint32_t Data[],uint32_t addr)5 ^* z  K+ C+ \! ]& c
  5. {
    " d. {0 B9 ~' }( d" ^9 |; d
  6.         uint32_t i=0;
    7 C# o- h  Z' V" F4 i
  7.         /* 1/4解锁FLASH*/9 v0 q; w1 F, [: H+ O( ~
  8.         HAL_FLASH_Unlock();7 }3 G# N7 h6 J* [' j3 s1 t
  9.         /* 2/4擦除FLASH*/8 r0 M, _* E9 z' n' X) S1 S3 w( U
  10.         /*初始化FLASH_EraseInitTypeDef*/
    5 F: X' j) j  ~7 ?8 ]% {
  11.         /*擦除方式页擦除FLASH_TYPEERASE_PAGES,块擦除FLASH_TYPEERASE_MASSERASE*/0 b0 N4 \: k3 |, K
  12.         /*擦除页数*/: |0 `5 ~. o4 ]* S
  13.         /*擦除地址*/
    ! ]6 h. c) z. R1 `- `
  14.         FLASH_EraseInitTypeDef FlashSet;- _# x, G8 J+ u( i  y5 E
  15.         FlashSet.TypeErase = FLASH_TYPEERASE_PAGES;: J- l& C1 o# K5 N
  16.         FlashSet.PageAddress = addr;+ Z! h1 D6 i1 T0 {* `
  17.         FlashSet.NbPages = 1;5 ^4 I! A4 S( d+ T" y" _6 N+ i
  18.         /*设置PageError,调用擦除函数*/
    $ o/ Q: S5 C4 n0 p- y, b/ o
  19.         uint32_t PageError = 0;
    - V. ~, \" V7 h" h7 l- q& ^5 q* ^" D
  20.         HAL_FLASHEx_Erase(&FlashSet, &PageError);4 S0 i: m5 J  t
  21.         /* 3/4对FLASH烧写*/
    8 I- K0 v4 W: q6 E* u0 @
  22.         for(i=0;i<L;i++)
    % Z5 g1 V9 H( F3 D' Q6 |
  23.         {: j2 t; W  ]/ A. g
  24.                 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr+4*i, Data<i>);
    ( o3 S; V! W! f% H6 r4 E
  25.         }
    $ m6 {' ~1 [# T, S
  26.         /* 4/4锁住FLASH*/5 a( m0 e# t1 B( [( ~+ w
  27.         HAL_FLASH_Lock();- S( u5 z- b$ p7 _
  28. }
    0 g" A$ |' f' h3 d+ B" n0 u
  29. ) \$ C; `# X4 X
  30. / R1 N/ N; `8 i$ A8 E7 E  G
  31. /*FLASH读取打印程序*/; Y+ u2 s2 Y5 }) x2 G3 j' Z
  32. void PrintFlashTest(uint32_t L,uint32_t addr)
    8 N/ B4 L- M- J
  33. {% Z/ j5 K3 q$ H% G
  34.         uint32_t i=0;7 Y, B0 o- t7 \2 r/ p9 b- m
  35.         for(i=0;i<L;i++)3 \, D: V+ V2 |+ ]$ \
  36.         {) v, }6 H7 R5 g% g. C" I( d
  37.                 printf("\naddr is:0x%x, data is:0x%x", addr+i*4,  *(__IO uint32_t*)(addr+i*4));
    # o% D' U% U+ v) q4 Q
  38.         }
    " a$ K5 O; g2 g; Q$ s; T
  39.         
    $ Q- ^/ L, g' k; Q2 E0 F. I7 l
  40. }
    , _7 b1 K1 f; T. c+ V
  41. /* USER CODE END 4 */
    / q8 J8 r6 y/ H! \6 O
  42. </i>
复制代码

, M7 t! C, Z1 Z$ c主程序
  1.   /* USER CODE BEGIN WHILE */
    4 _* n3 B/ R2 H7 M  C  K0 V
  2.   while (1)0 G( }( i" l1 h  g# P
  3.   {+ T- d, S7 A) ?
  4.     /* USER CODE END WHILE */) K3 Z5 r& Q$ D4 b
  5. 2 o) w/ s3 \; p7 v
  6.     /* USER CODE BEGIN 3 */               
    / l$ m3 G' s! S% q" u" ~9 i  o5 X
  7.                 WriteFlashTest(3,WriteFlashData,addr);3 H: U5 v5 P, p5 L# E
  8.                 PrintFlashTest(3,addr);
    1 m8 q, M- o7 m7 d, j* [
  9.                 HAL_Delay(5000);
      T; a" E+ T$ k5 A! ^  c$ g+ R
  10.   }( o! i2 Z5 m% h) }8 G6 O: Y
  11.   /* USER CODE END 3 */
复制代码
3 q" P) i5 ^# u+ S1 u) A
演示效果
# U; T+ \. \5 I( [- f$ f4 Z; @+ w6 Z, F& I
NG8_L9U_U78%(MBP)5@XV5I.png 9 T  {! _! J% i# {  l6 V

, `* F: }1 @& o" y通过keil查看地址也可以看到,值正确写入。: g: U6 O  n7 \8 K- q
; ?6 `+ {" `  W
KL2H{X~W7MYM7M(8UN{D3JJ.png 4 N9 E  ^) Y2 R* w, R
# U- r4 Q; X+ `3 C
9 ~3 m! Y$ @7 h8 o7 e' x/ Y
赞 收藏 评论0 发布时间:2022-4-30 22:15

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版