
一、关于FLASH 1.内存映射 首先我们需要了解一个内存映射:; y' G1 v: q2 S; M: T ![]() # {3 N4 c* D" q stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同。3 V$ I. Z: u& |' l$ B RAM起始地址是0x2000 0000,结束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。 Flash中的内容一般用来存储代码和一些定义为const的数据,断电不丢失, l' M5 d4 U' Q RAM可以理解为内存,用来存储代码运行时的数据,变量等等。掉电数据丢失。2 f7 Y8 N5 r: ~* ~( n! N% V4 P STM32将外设等都映射为地址的形式,对地址的操作就是对外设的操作。3 J" M; D) I* s+ b1 L" J% `, L stm32的外设地址从0x4000 0000开始,可以看到在库文件中,是通过基于0x4000 0000地址的偏移量来操作寄存器以及外设的。( \! ]6 [+ Z M% I" h" t 5 n1 Q7 Y5 n+ q0 h J 一般情况下,程序文件是从 0x0800 0000 地址写入,这个是STM32开始执行的地方,0x0800 0004是STM32的中断向量表的起始地址。 Z& [8 t/ W9 v0 E4 G: K1 A* C0 p 在使用keil进行编写程序时,其编程地址的设置一般是这样的:5 w/ Q1 A* k9 t+ x. y6 O- q0 G ![]() 2.内部FLASH STM32 的内部 FLASH 包含主存储器、系统存储器、 OTP 区域以及选项字节区域,它们的地址分布及大小如下: b3 Z" o( T( g' h8 d$ X4 l4 [ - `" @7 g& e' |& w c ![]() ( F$ a: E& H) ^3 |& s+ |/ E 1.主存储器:一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域它是存储用户应用程序的空间,芯片型号说明中的 1M FLASH、 2M FLASH 都是指这个区域的大小。与其它 FLASH 一样,在写入数据前,要先按扇区擦除, 2.系统存储区:系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、 USB 以及 CAN 等 ISP 烧录功能。3 }' E6 }, Z, \ |0 I7 `9 E% P 3.OTP 区域:OTP(One Time Program),指的是只能写入一次的存储区域,容量为 512 字节,写入后数据就无法再更改, OTP 常用于存储应用程序的加密密钥。 4.选项字节:选项字节用于配置 FLASH 的读写保护、电源管理中的 BOR 级别、软件/硬件看门狗等功能,这部分共 32 字节。可以通过修改 FLASH 的选项控制寄存器修改。 l& h7 V8 i% \4 E/ O0 U: f l 3.对内部Flash的写入过程8 W1 K( y5 G% Z& U 1.解锁5 A% g$ D; G A) o5 ^. L8 S (1) 往 Flash 密钥寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123 ]6 _; X) j( D7 G o (2) 再往 Flash 密钥寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB: [) X5 L, r- V2 s 2.数据操作位数 最大操作位数会影响擦除和写入的速度,其中 64 位宽度的操作除了配置寄存器位外,还需要在 Vpp 引脚外加一个 8-9V 的电压源,且其供电间不得超过一小时,否则 FLASH可能损坏,所以 64 位宽度的操作一般是在量产时对 FLASH 写入应用程序时才使用,大部分应用场合都是用 32 位的宽度。 3.擦除扇区 在写入新的数据前,需要先擦除存储区域, STM32 提供了扇区擦除指令和整个FLASH 擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。1 k, E3 g5 x k8 F- _ 扇区擦除的过程如下:2 c+ E9 G" Q- ?* O5 Q* M* t9 j (1) 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何/ d _: k# W$ C Flash 操作; (2) 在 FLASH_CR 寄存器中,将“激活扇区擦除寄存器位 SER ”置 1,并设置“扇 区编号寄存器位 SNB”,选择要擦除的扇区;1 b; G3 l% a5 n$ ^4 I# n (3) 将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;2 d5 @* z! A I (4) 等待 BSY 位被清零时,表示擦除完成。9 L& A3 Z( q3 R, _! R( S. ? 4.写入数据 擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下: (1) 检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作; (2) 将 FLASH_CR 寄存器中的 “激活编程寄存器位 PG” 置 1; (3) 针对所需存储器地址(主存储器块或 OTP 区域内)执行数据写入操作;) Q! A% D$ Z8 k* t# F. w r# A (4) 等待 BSY 位被清零时,表示写入完成。 + q3 z8 z( N# B N 二、工程尝试向STM32的内部FLASH写入数据+ Q/ T& |' w* }% l. A 修改好后在MDK-ARM中打开工程,可以将想要存入Flash中的内容修改为自定义内容 ( `& w+ R' |( ~& w
![]() 进行程序调试前,先完成配置:1 k( ?% j$ k( @4 V8 h- p* ?; V 注意:下载的工程代码调试用的是硬件 st-link debuger,不是软件仿真,因此用软件仿真做,可能情况略有不同(小编这里软件仿真就没有出现结果) 点击Options->Debug->右边使用硬件ST-Link Debugger,接着点击S T-Link Debugger右边的Settings ![]() 5 C) Q% F" W5 _* [; z) g 进入到Cortex-M Target Driver Setup的Debug页面,其中的Port选择为SW , q, ?# W( G* _' P# I0 B ![]() & W. R9 J( }' A* T* a0 a 依次点击Flash Download->勾选Reset and Run->Add->选择STM32F10x Med-density Flash->Add->确定即可 7 o+ F- l4 U$ M# ]$ w ![]() * O; m! q% v8 E% G8 r 最后点击OK完成硬件配置 , K3 w' i7 l1 t7 ]* F( R 由于要连接硬件ST-Link,所以要下载一个STLink驱动,不然下载不成功& W2 F, e5 e+ U. {) s+ f. p 连线如下图所示:6 u' b# i3 \7 R 5 [% N4 t! t! V; A6 _' D5 R, b7 X ![]() ! v2 n$ x R9 e1 B8 b+ d 点击左上角的LOAD按钮将程序下载到STM32中:9 Y, w1 s4 @* x 0 K9 H% X4 d; u# f% C8 K h ![]() : T% d% X M5 x, Q+ z 之后点击dubug按钮,进入硬件仿真调试(断点已自动设置好): ![]() 点击View->memory windows->memory 1打开内存观察窗口,并在地址栏中输入:0x800C000,观察将要修改的flash区间区容: ![]() : |0 ?% K7 K) S 其中点击某一字符右击可选择显示格式,修改为Ascii:; G' l2 F2 h# d6 R# X' \ ![]() 6 g L M- a9 z( s/ C 点击View->Watch windows->Watch 1打开一个变量观察窗口: ![]() & `6 g/ w+ A; q( h, W 将变量FlashWBuff 和FlashRBuff加入到Watch 1观察窗口 ![]() ! C% i. d/ k1 U, r3 r j5 E: I 另外View->勾选Periodic Windows Update,开启变量自动更新:2 b. m6 u$ d" [& C3 l ) q" m4 ?$ o" v ![]() 按如图所示的全速运行按钮或者F5:# J5 h) Z! F! P& ]0 |( _ . E, F3 V$ `; S9 ^! x ![]() 这时就可以看到Watch 1窗口的数组FlashRBuff中的内容与数组FlashWBuff中的内容是一样的:$ y3 Q3 \1 h" h( Z& N; Q7 { , b. ?' I- B! H! G: Y6 J* r2 y+ T) \ ![]() 0 f1 W( {1 q5 x1 g8 V6 k, j 同时在Memory 1窗口中可以看到在FLASH地址0x0800C000区成功写入对应内容 ![]() ; {4 M& s; \" P 断电后再重新上电进行调试,程序停在main入口处时还可以看到Flash对应区间的内容保持上一次写入内容值: ![]() 6 e: o9 [. D( X2 m; ]8 C9 n$ ^) f ———————————————— 版权声明:LaiYiFei255 \3 z j- ?! ^0 O8 ^; Y |
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
OpenBLT移植到STM32F405开发板
为什么要先开启STM32外设时钟?
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【经验分享】STM32实例-RTC实时时钟实验④-获取RTC时间函数与中断服务函数
STM32 以太网 MAC Loopback 的实现
STM32功能安全设计包,助力产品功能安全认证
基于STM32启动过程startup_xxxx.s文件经验分享
HRTIM 指南
ST 微控制器电磁兼容性 (EMC) 设计指南