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

了解STM32的内部FLASH空间

[复制链接]
攻城狮Melo 发布时间:2022-11-8 22:42
一、关于FLASH
0 P( H/ D2 Y/ l2 I& i& u7 W1.内存映射2 x; }  A" s1 \* Q) t
首先我们需要了解一个内存映射:
7 w3 G7 l' w8 z& ] 1a437bda156b462c8bb68e70b743e9d3.png
; G& P- S' f# v$ {  ]9 Q1 t. l* Z9 n2 H# j" X& n
stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同。2 O  L# g+ r8 A: j  `6 Y8 b4 C

$ X5 Z2 X; y* M4 F7 o0 ORAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。
2 `. B9 X0 n2 Y3 E  c) p* }
7 u1 `; c4 Y+ r3 D- j7 |7 tFlash中的内容一般用来存储代码和一些定义为const的数据,断电不丢失,6 J0 K9 B& r% C0 ~
RAM可以理解为内存,用来存储代码运行时的数据,变量等等。掉电数据丢失。
5 J% ~! B! l4 A% q* ]3 E" z
, @' y- e5 g% d/ hSTM32将外设等都映射为地址的形式,对地址的操作就是对外设的操作。  [: i' d% I. o, s; b) I- B) j
stm32的外设地址从0x4000 0000开始,可以看到在库文件中,是通过基于0x4000 0000地址的偏移量来操作寄存器以及外设的。
9 l, ^: v! m  B0 Y/ ~
/ d3 Q3 W! }2 L4 B% Y一般情况下,程序文件是从 0x0800 0000 地址写入,这个是STM32开始执行的地方,0x0800 0004是STM32的中断向量表的起始地址。7 ]% N0 q% h& A
在使用keil进行编写程序时,其编程地址的设置一般是这样的:
1 W+ o4 d' ~' e
7 v. ~* H* ~8 r) U, b- ~* U! [* g 3baeeda13bd34f1da0d4dc90ee00177d.png   p5 v# M, M& a& i8 G

! R; M7 G# U' ?. `0 u& _2.内部FLASH3 B1 ]$ q+ J2 G1 Q1 u
STM32 的内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域,它们的地址分布及大小如下:
( P8 M$ M5 }  m
. ~9 ^1 r) s6 c9 I: O4 d% a ab30c39fee444c28931868da50a7f8e1.png
+ M/ Y2 c6 S6 b* F! s
# P; v' p$ q  Y) ^* J% y1 ]6 }1.主存储器:一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域它是存储用户应用程序的空间,芯片型号说明中的 1M FLASH、 2M FLASH 都是指这个区域的大小。与其它 FLASH 一样,在写入数据前,要先按扇区擦除,+ ^. K: U+ ^4 Y9 C0 X
2.系统存储区:系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、 USB 以及 CAN 等 ISP 烧录功能。
: R$ Q- {2 D- S$ C& B, N3.OTP 区域:OTP(One Time Program),指的是只能写入一次的存储区域,容量为 512 字节,写入后数据就无法再更改, OTP 常用于存储应用程序的加密密钥。
7 ], l9 i/ ~* k! U' l) ]4.选项字节:选项字节用于配置 FLASH 的读写保护、电源管理中的 BOR 级别、软件/硬件看门狗等功能,这部分共 32 字节。可以通过修改 FLASH 的选项控制寄存器修改。
0 V9 k  F) Y4 p7 j% _2 d' h5 U' k
- m8 h# @  d# i6 v- N" z3.对内部Flash的写入过程3 ~% W, q1 `# j  m+ ?8 t# _
1.解锁
' H& w& S1 \. g" {(1) 往 Flash 密钥寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123
/ n4 \/ l) n! I8 ^: c(2) 再往 Flash 密钥寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB
6 L, t" q  t  j: Z) j2.数据操作位数8 M% }3 c& ~+ k8 ?/ H! z1 j& O* W. z7 n
最大操作位数会影响擦除和写入的速度,其中 64 位宽度的操作除了配置寄存器位外,还需要在 Vpp 引脚外加一个 8-9V 的电压源,且其供电间不得超过一小时,否则 FLASH可能损坏,所以 64 位宽度的操作一般是在量产时对 FLASH 写入应用程序时才使用,大部分应用场合都是用 32 位的宽度。1 q: F, P6 {5 o% u
3.擦除扇区3 [+ U7 z; s: _' b4 w4 r' O# l
在写入新的数据前,需要先擦除存储区域, STM32 提供了扇区擦除指令和整个FLASH 擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。
' x( ~5 v7 ?0 |, c: h& C2 F3 |扇区擦除的过程如下:; p* G+ v3 v, J" [( A# i. Z
(1) 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何
& j2 t8 x) S% _4 A+ c" W7 lFlash 操作;
9 D% @3 t  D' P4 v4 k4 F(2) 在 FLASH_CR 寄存器中,将“激活扇区擦除寄存器位 SER ”置 1,并设置“扇2 s+ J2 t0 |' M, q
区编号寄存器位 SNB”,选择要擦除的扇区;4 u$ X0 e" c9 ?, `  z
(3) 将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;
6 ~  V$ G% U& _% E8 T  c2 N(4) 等待 BSY 位被清零时,表示擦除完成。. k3 c, W( J$ p9 q' g3 D
4.写入数据
$ c( B5 m. @" ~% q& s, O6 n/ d+ l! D擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下:" [  f% A- c5 Q; ^) q
(1) 检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;! C* C3 a2 Z3 f+ U
(2) 将 FLASH_CR 寄存器中的 “激活编程寄存器位 PG” 置 1;3 F7 `* [& n8 K0 q, v
(3) 针对所需存储器地址(主存储器块或 OTP 区域内)执行数据写入操作;9 z; G5 F# m9 o/ G
(4) 等待 BSY 位被清零时,表示写入完成。
  V, E  i( |6 b- Z, x$ h
5 c; e$ _/ U% B" `二、工程尝试向STM32的内部FLASH写入数据
# w; m; l' \5 i& c
5 Q& _" ~) N, Y2 R+ J修改好后在MDK-ARM中打开工程,可以将想要存入Flash中的内容修改为自定义内容
8 S' q" _, t3 h1 B
+ h% s! |  W5 P: X% G( K& A
  1. uint8_t FlashTest[] = "LaiYiFei25";
复制代码

8 n- K6 R/ F3 X9 s 08324ee6dd114b5ba710d00e4c9a2354.png 6 s  n' P" T" C# i0 C+ |9 A
# A; x& z/ z( [& @- d
进行程序调试前,先完成配置:8 k; k: [( S5 S2 B8 X, w" o
注意:下载的工程代码调试用的是硬件 st-link debuger,不是软件仿真,因此用软件仿真做,可能情况略有不同(小编这里软件仿真就没有出现结果)
; ~% a7 o* k9 q0 u, P* q点击Options->Debug->右边使用硬件ST-Link Debugger,接着点击S T-Link Debugger右边的Settings
) B1 i" q- r2 {8 E6 h: d
( v$ c1 [; I) K! n# E 1518367c801d45aeaeaf46436091dffb.png
9 \9 `. m" v: x, ?
' b# p0 o* U0 d进入到Cortex-M Target Driver Setup的Debug页面,其中的Port选择为SW+ z* O: {1 D" w4 N

( s0 n: S( T, O' i+ T+ P; d9 U; ^8 r8 s 306bbe0704cb4ced9e5e093067c8e2e7.png
4 U8 t4 }! A, _- E9 d+ \" h) ?" F$ t4 v7 `/ c* h. W
依次点击Flash Download->勾选Reset and Run->Add->选择STM32F10x Med-density Flash->Add->确定即可
7 K1 L3 Z. H9 M" `6 S# n* w7 ?
8 A+ H7 Y5 m) @+ y3 X4 K a5ef5c613330424b9bc23f544c4a5603.png ! ^3 Z8 w; N5 Z$ v0 U

6 K. [" f8 q! M/ U8 F最后点击OK完成硬件配置
: |$ M+ i. h; [; v3 g  P3 R9 o9 x1 K* Q3 i+ w" A  d
由于要连接硬件ST-Link,所以要下载一个STLink驱动,不然下载不成功0 E4 W8 w7 U2 P' o

! c6 b. `# T" M6 p" f1 w连线如下图所示:2 L) L$ X- u- o

& b) z4 z" U- Y! h d68ecfff232e480d98c051d0773b34b7.png . p- @/ l3 ?. O6 J8 I5 E# a

' _& e) U& r' o点击左上角的LOAD按钮将程序下载到STM32中:0 B" E. ]  V6 P3 D0 j* f) U
' Q4 `4 u' j0 F% x! Y
ed0882797d49425b94a9d11347dd4ae4.png
: B% {% B  h( Z. R; }( V; }# Y/ G# z# P; D4 f
之后点击dubug按钮,进入硬件仿真调试(断点已自动设置好):
4 I+ V+ e. z. H5 O) r# G# ~5 T) {$ f
d8f0c25f9f8745f78953f935e7dad5d3.png
. D2 K. j# E/ B+ \9 f% M' O6 ]4 {8 o! r
点击View->memory windows->memory 1打开内存观察窗口,并在地址栏中输入:0x800C000,观察将要修改的flash区间区容:7 C. U6 P  F* u& t. s& \
' l% ^/ {0 h% M! e( n2 K  V2 ]& M
8c50ecb07e4c432ba6a445dc4f1fbd9b.png 7 G  O- h" G6 \: O

% E$ I+ i- O! Z( p其中点击某一字符右击可选择显示格式,修改为Ascii:
; i4 g( R5 w7 w+ o' Z, W
- L7 }- q8 l5 V 352e9bf3746a4cee9bba1b741ffcd5c0.png
& |. s8 R  M! e- s
/ I- w8 f5 E3 U* R& i% U! x点击View->Watch windows->Watch 1打开一个变量观察窗口:& {. c! v$ P+ o9 K  Q0 s; a' o& _
+ \; F7 k& \/ Q2 Y- y" q$ ~$ E! U
672ad36cddf1414883d68eee9bbbb24c.png
& I( k) [9 v8 W4 t3 [( }1 q8 H3 i) s0 a" u0 L7 R: r5 F
将变量FlashWBuff 和FlashRBuff加入到Watch 1观察窗口. t, k8 r5 g# Q1 C

8 _8 a) E, f4 a 4092a8efe22548d1ad67f9b357e27226.png " S) T8 \7 j# f" o! v0 a  Z. @

( N: p  k( {& O1 N5 O5 j: `另外View->勾选Periodic Windows Update,开启变量自动更新:
# G$ v$ L4 e% L& p0 H5 k1 j  R8 y! L+ s  [4 q
0175ba289eb842e2b8dec78489af29c5.png & c, M* v2 d$ Z( N
- k1 d5 e- }0 \5 l
按如图所示的全速运行按钮或者F5:1 q3 \, @2 p) j
% m& v2 J( b; J7 t0 z+ L( E
97ded6d38c2b427a9bed00c318b7b8bd.png # m+ g: [3 N* x
* l7 U8 ~/ G4 a. ~- B% B. k) u  W& F
这时就可以看到Watch 1窗口的数组FlashRBuff中的内容与数组FlashWBuff中的内容是一样的:' v; r# m( a  ~2 J5 @' ]

. l; f5 j( C* m  Z  J# H  U d31c59af55bb49d9a5d1b98606e04bca.png
/ {& x- d( o( V) F, b$ Q7 z
# [! x2 O' N  D* T0 V5 @( j1 r# u同时在Memory 1窗口中可以看到在FLASH地址0x0800C000区成功写入对应内容, A7 @. d$ E# B7 A3 T
# Y* h& }7 o: l+ N4 s# c- ?# L
59bc392fa3bf409a94b1ca1b951d9071.png $ [& Q, e# e3 D/ C
) Y3 g; _3 l! I) e
断电后再重新上电进行调试,程序停在main入口处时还可以看到Flash对应区间的内容保持上一次写入内容值:
5 z* h' {! e; I9 P8 g; V. c% N' I0 Y8 B! w
0181d7e3b12d4957a265c5613cf1129b.png
/ @# A/ ^. \' U1 N. K) n" ]3 k4 H1 K$ y% a  k. ]
————————————————
: F# M+ c5 f! T" X' z& C版权声明:LaiYiFei25) W0 c, c) s. N( B, H% y
6 i- d9 J* Z4 D. |: v

/ p! Z0 c: Q0 ~! |7 S
赞 收藏 1 评论0 发布时间:2022-11-8 22:42

举报

0个回答

所属标签

相似技术帖

官网相关资源

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