本译文仅供参考,如有翻译错误,请以英文原稿为准 
PM0042 
编程手册 
编程手册
编程手册
编程手册
 
STM32F10x闪存编程
闪存编程 
闪存编程
闪存编程
简介简介简介简介 
本编程手册介绍了如何烧写STM32F10x微控制器的闪存存储器。 
STM32F10x内嵌的闪存存储器可以用在线编程(ICP)或在程序中编程(IAP)烧写。 
在线编程(In-Circuit  Programming  –  ICP)方式用于更新闪存存储器的全部内容,它通过JTAG或
SWD协议下载用户应用程序到微控制器中。ICP是一种快速有效的流程,消除了封装和管座的
困扰。 
与ICP方式对应,在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一
种通信接口(如I/O端口、USB、CAN、UART等)下载程序或数据到存储器中。IAP允许你在程序
运行时重新烧写闪存存储器中的内容。然而,IAP要求至少有一部分程序已经用ICP烧到某个闪
存块中。 
本文的内容适用于STM32F101和STM32F103系列。 
闪存接口是在AHB协议上实现了对指令和数据的访问,通过对存储器的分区和预取缓存的实
现,加快了存储器的访问;闪存接口还实现了闪存编程和擦除所需的逻辑电路,这里还包括访
问和写入保护以及选择字节的控制。 
 
 
 
 
STM32F10x闪存编程 
 
页1/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
目录目录目录目录 
1  概述 ................................................................................................................................................................... 4 
1.1  特性 ....................................................................................................................................................... 4 
1.2  闪存模块组织 ....................................................................................................................................... 4 
2  读/编写STM32F10x内置闪存.......................................................................................................................... 6 
2.1  简介 ....................................................................................................................................................... 6 
2.2  读操作 ................................................................................................................................................... 6 
2.2.1  取指令 ....................................................................................................................................... 6 
2.2.2 
D-Code接口............................................................................................................................... 6 
2.2.3  闪存访问控制器 ....................................................................................................................... 6 
2.2.4  信息模块访问 ........................................................................................................................... 7 
2.3  闪存编程和擦除控制器(FPEC) ........................................................................................................... 7 
2.3.1  键值 ........................................................................................................................................... 7 
2.3.2  解除闪存锁 ............................................................................................................................... 7 
2.3.3  闪存编程 ................................................................................................................................... 7 
2.3.4  信息块的编程 ........................................................................................................................... 8 
2.3.5  闪存擦除 ................................................................................................................................... 9 
2.4  保护 ..................................................................................................................................................... 11 
2.4.1  读保护 ..................................................................................................................................... 11 
2.4.2  写保护 ..................................................................................................................................... 11 
2.4.3  信息块保护 ............................................................................................................................. 12 
2.5  选择字节加载 ..................................................................................................................................... 12 
2.6  低功耗管理 ......................................................................................................................................... 13 
3  寄存器说明 ..................................................................................................................................................... 14 
3.1  闪存访问控制寄存器(FALSH_CR)................................................................................................... 14 
3.2 
FPEC键寄存器(FLASH_KEYR)........................................................................................................ 15 
3.3  闪存OPTKEY寄存器(FLASH_OPTKEYR)...................................................................................... 15 
3.4  闪存状态寄存器(FLASH_SR) ........................................................................................................... 16 
3.5  闪存控制寄存器(FLASH_CR)........................................................................................................... 17 
3.6  闪存地址寄存器(FLASH_AR)........................................................................................................... 18 
3.7  选择字节寄存器(FLASH_OBR)........................................................................................................ 19 
3.8  写保护寄存器(FLASH_WRPR)......................................................................................................... 20 
3.9  闪存寄存器映像 ................................................................................................................................. 21 
4  版本历史 ......................................................................................................................................................... 22 
 
STM32F10x闪存编程 
 
页2/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
术语术语术语术语 
下面列出了本文档中所用到的术语和缩写的简要说明: 
  Cortex-M3内核集成了两个调试端口: 
− 
JTAG调试接口(JTAG-DP)提供基于JTAG(Joint Test Action Group 联合测试行动小组)
协议的5线标准接口。 
−  SWD调试接口(SWD-DP)提供基于SWD(Serial Wire Debug 串行线调试)协议的2线标
准接口。 
有关JTAG和SWD协议,请参考Cortex M3 Technical Reference Manual。 
  选择字节:存放在闪存中的产品配置位。 
  字(Word):32位长的数据或指令 
  半字(Half Word):16位长的数据或指令 
  字节(Byte):8位长的数据或指令 
  FPEC(FLASH Program/Erase  controller  闪存编程/擦除控制器):对内置闪存的写操作是由一
 
 
 
个内嵌的FPEC管理的。 
IAP(In-Application  Programming):IAP是在用户程序运行时对闪存微控制器中存储器重新
编程的一种能力。 
ICP(In-Circuit  Programming):ICP是在芯片安装在用户应用板上后通过JTAG协议对闪存微
控制器中存储器编程的一种能力。 
I-Code:这是连接Cortex-M3核心的指令总线与闪存程序存储器接口的总线,指令预取是在
这个总线上实现的。 
  D-Code:这是连接Cortex-M3核心的D-Code总线(常数和调试访问)与闪存数据存储器接口
的总线。 
  SIF:用户选择字节的小信息块(详见图4)。 
  AHB:先进高性能总线。 
STM32F10x闪存编程 
 
页3/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
1  概述概述概述概述 
1.1  特性特性特性特性 
  128K字节闪存 
  擦写周期:1000次 
  存储器配置: 
−  主存储块:16K x 64位 
−  信息块:320 x 64位 
闪存接口的特性: 
  带预取缓冲器的读接口(2x64位) 
  选择字节加载 
  闪存编程/擦除操作 
  读出/写入保护 
1.2  闪存闪存闪存闪存模块组织
模块组织 
模块组织
模块组织
存储器组织成主存储器块和信息块;主存储器块包含128页,每页1K字节;信息块包括2页(2K
字节和0.5K字节);如表一: 
模块组织 
表一表一表一表一     闪存闪存闪存闪存模块组织
模块组织模块组织
地址范围 
地址范围
地址范围地址范围
长度长度长度长度(字节字节字节字节) 
块块块块 
主存储器 
信息块 
闪存寄存器 
4 x 1K 
4 x 1K 
4 x 1K 
. 
. 
. 
4 x 1K 
2K 
512 
4 
4 
4 
4 
4 
4 
4 
4 
4 
100 
名称名称名称名称 
页0 
页1 
页2 
页3 
页4~7 
页8~11 
. 
. 
. 
0x0800 0000 – 0x0800 03FF 
0x0800 0400 – 0x0800 07FF 
0x0800 0800 – 0x0800 0BFF 
0x0800 0C00 – 0x0800 0FFF 
0x0800 1000 – 0x0800 1FFF 
0x0800 2000 – 0x0800 2FFF 
. 
. 
. 
页124~127 
启动程序代码 
用户选择字节 
FLASH_ACR 
FLASH_KEYR 
0x0801 F000 – 0x0801 FFFF 
0x1FFF F000 – 0x1FFF F7FF 
0x1FFF F800 – 0x1FFF F9FF 
0x4002 2000 – 0x4002 2003 
0x4002 2004 – 0x4002 2007 
FLASH_OPTKEYR  0x4002 2008 – 0x4002 200B 
0x4002 200C – 0x4002 200F 
0x4002 2010 – 0x4002 2013 
0x4002 2014 – 0x4002 2017 
0x4002 2018 – 0x4002 201B 
0x4002 201C – 0x4002 201F 
0x4002 2020 – 0x4002 2023 
0x4002 2024 – 0x4002 2087 
FLASH_OBR 
FLASH_WRPR 
FLASH_SR 
FLASH_CR 
FLASH_AR 
保留 
保留 
闪存存储器被组织成32位宽的存储器单元,可以存放代码和数据常数。每一个STM32F10x微控
制器的闪存模块都有一个特定的启始地址,有关的启始地址请参考STM32F10x参考手册。 
系统存储器是用于存放在系统存储器自举模式下的启动程序,这个区域只保留给ST使用;ST在
生产线上对这个区域编程并锁定以防止用户擦写。 
STM32F10x闪存编程 
 
页4/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压由
内部产生。 
闪存存储器有两种保护方式防止非法的访问(读、写、擦除): 
  页写入保护 
  读出保护 
详情请参考2.4节。 
在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地
进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。 
进行闪存编程操作时(写或擦除),必须打开内部的RC振荡器(HSI)。 
闪存存储器可以用ICP或IAP方式编程。 
STM32F10x闪存编程 
 
页5/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
2  读读读读/编写编写编写编写 STM32F10x 内置内置内置内置闪存闪存闪存闪存 
2.1  简介简介简介简介 
本节介绍如何读和对STM32F10x的内置闪存编程 
2.2  读操作读操作读操作读操作 
内置闪存模块可以在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容
并得到相应的数据。 
读接口在闪存端包含一个读控制器,还包含一个AHB接口与CPU衔接。这个接口的主要工作就
是产生读闪存的控制信号并预取CPU要求的指令块,预取指令块仅用于在I-Code总线上的取指
操作,数据常量是通过D-Code总线访问的。这两条总线的访问目标是相同的闪存模块,访问D-
Code将比预取指令优先级高。 
2.2.1  取指令取指令取指令取指令 
Cortex-M3在I-Code总线上取指令,在D-Code总线上取数据。预取指令块可以有效地提高对I-
Code总线访问的效率。 
预取缓冲器 
预取缓冲器
预取缓冲器
预取缓冲器
预取缓冲器包含两个数据块,每个数据块有8个字节;预取指令(数据)块直接映像到闪存中,因
为数据块的大小与闪存的宽度相同,所以读取预取指令块可以在一个读周期完成。 
设置预取缓冲器可以使CPU更快地执行,CPU读取一个字的同时下一个字已经在预取缓冲器中
等候,即当代码跳转的边界为8字节的倍数时,闪存的加速比例为2。 
预取控制器 
预取控制器
预取控制器
预取控制器
 
 
预取控制器根据预取缓冲器中可用的空间决定是否访问闪存,预取缓冲器中有至少一块的空余
空间时,预取控制器则启动一次读操作。 
清除闪存访问控制寄存器中的一个控制位能够关闭预取缓冲器,这样预取缓冲器将处于关闭状
态。 
注意:  当AHB时钟的预分频系数不为“1”时,必须打开预取缓冲器(FLASH_ACR[4]= 1 )。 
如果在系统中没有高频率的时钟,即HCLK频率较低时,闪存的访问只需半个HCLK周期(半周
期的闪存访问只能在时钟频率低于8MHz时进行,使用HIS或HSE并且关闭PLL时可得到这样的
频率);在闪存访问控制寄存器中有一个控制位可以选择这种工作方式。 
注意:  当使用了预取缓冲器和AHB时钟的预分频系数不为“1”时,不能使用半周期访问方式。 
 
访问时间调节 
访问时间调节
访问时间调节
访问时间调节
为了维持读闪存的控制信号,预取控制器的时钟周期与闪存访问时间的比例由闪存访问控制器
控制;这个值给出了能够正确地读取数据时,闪存控制信号所需的时钟周期数目;复位后,该
值为1,闪存访问为两个时钟周期(FLASH_ACR的复位值为01,长度=1)。 
2.2.2  D-Code接口接口接口接口 
D-Code接口包含CPU端简单的AHB接口和对闪存访问控制器的仲裁器提出访问请求的逻辑电
路。D-Code的访问优先于预取指令的访问。这个接口使用预取缓冲器的访问时间调节模块。 
2.2.3  闪存访问控制器
闪存访问控制器 
闪存访问控制器
闪存访问控制器
这个模块就是在I-Code上的指令预取请求和D-Code接口上读请求的仲裁器。 
STM32F10x闪存编程 
 
页6/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
D-Code接口的请求优先于I-Code的请求。 
2.2.4  信信信信息模块访问
息模块访问 
息模块访问
息模块访问
信息模块的内容可以通过I-Code总线执行并且可以在D-Code总线上读出,小信息模块可以在任
一模式下读写。 
选择字节模块包含配置选择字节和其他用户定义的信息。 
2.3  闪存编程和擦除控制器
闪存编程和擦除控制器(FPEC) 
闪存编程和擦除控制器
闪存编程和擦除控制器
FPEC模块处理闪存的编程和擦除操作,它包括7个32位的寄存器: 
  FPEC键寄存器(FLASH_KEYR) 
  选择字节键寄存器(FLASH_OPTKEYR) 
  闪存控制寄存器(FLASH_CR) 
  闪存状态寄存器(FLASH_SR) 
  闪存地址寄存器(FLASH_AR) 
  选择字节寄存器(FLASH_OBR) 
  写保护寄存器(FLASH_WRPR) 
只要CPU不访问闪存,闪存操作不会延缓CPU的执行。 
2.3.1  键值键值键值键值 
共有三个键值: 
  RDPRT键 = 0x000000A5 
  KEY1 = 0x45670123 
  KEY2 = 0xCDEF89AB 
2.3.2  解除闪存锁
解除闪存锁 
解除闪存锁
解除闪存锁
复 位 后 , FPEC 模 块 是 被 保 护 的 , 不 能 写 入 FLASH_CR 寄 存 器 ; 通 过 写 入 特 定 的 序 列 到
FLASH_KEYR寄存器可以打开FPEC模块,这个特定的序列是两个键值(KEY1和KEY2,见2.3.1
节);写入任何其他序列都会在下次复位前锁死FPEC模块和FLASH_CR寄存器。 
写入错误的键序列还会产生总线错误;总线错误发生在第一次写入的不是KEY1,或第一次写入
的 是KEY1 但 第 二 次写 入的 不 是KEY2 时 ;FPEC模 块 和FLASH_CR 寄 存器 可 以 由 程 序 设置
FLASH_CR寄存器中的LOCK位锁住,这时可以通过在FLASH_KEYR中写入正确的键值对FPEC
解锁。 
2.3.3  闪存编程
闪存编程 
闪存编程闪存编程
每次闪存编程可以写入16位。当FLASH_CR寄存器的PG位为1时,写入一个半字到一个闪存地
址将启动一次编程;写入任何非半字的数据,FPEC都会产生总线错误。在编程过程中(BSY位
为1),任何读写闪存的操作都会使CPU暂停,直到此次闪存编程结束。 
STM32F10x闪存编程 
 
页7/23 
本译文仅供参考,如有翻译错误,请以英文原稿为准 
编程过程 
图一图一图一图一     编程过程
编程过程编程过程
= 1 
执行解锁序列 
读FLASH_CR的LOCK位 
LOCK位=1 
= 0 
置FLASH_CR的PG位=1 
在指定的地址写入半字(16位) 
FLASH_SR的
BSY位= 1? 
= 1 
= 0 
读编程地址并检查写入的数据 
 
标准编程 
标准编程
标准编程标准编程
 
这种模式下CPU以标准的半字写的方式烧写闪存,FLASH_CR寄存器的PG位必须置1。FPEC先
读出指定地址的内容并检查它是否被擦除,如未被擦除则不执行编程并在FLASH_SR寄存器的
PGERR位提出警告(唯一的例外是当要烧写的数值是0x0000时,0x0000可被正确烧入且PGERR
位不置位);如果指定的地址在FLASH_WRPR中指定为写保护,则不执行编程并在FLASH_SR
寄存器的WRPRTERR位置1提出警告。FLASH_SR寄存器的EOP为1时表示编程结束。 
标准的闪存编程顺序如下: 
  检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作; 
  设置FLASH_CR寄存器的PG位为1; 
  写入要编程的半字到指定的地址; 
  等待BSY位变为0; 
  读出写入的地址并验证数据。 
注意:  当FLASH_SR寄存器的BSY位为1时,不能对任何寄存器执行写操作。 
2.3.4  信息块的编程
信息块的编程 
信息块的编程
信息块的编程
选择字节编程 
 
选择字节编程
选择字节编程
选择字节编程
选择字节是通过特殊的地址进行编程。选择字节只有6个字节(4个用于写保护,1个由于读保
护 , 另 一 个 用 于 器 件 配 置 ) 。 对 FPEC 解 锁 后 , 分 别 写 入 KEY1 和 KEY2( 见 2.3.1 节 ) 到
FLASH_OPTKEYR,再设置FLASH_CR寄存器的OPTWRE位为1,此时可以对小信息块进行编
程:设置FLASH_CR寄存器的OPTPG位为1后写入半字到指定的地址。 
FPEC先读出指定地址的选择字节内容并检查它是否被擦除,如未被擦除则不执行编程并在
FLASH_SR寄存器的WRPRTERR位提出警告。FLASH_SR寄存器的EOP为1时表示编程结束。 
FPEC使用半字中的低字节并自动地计算出高字节(高字节为低字节的反码),并开始编程操作,
这将保证选择字节和它的反码始终是正确的。 
烧写编程的顺序如下: 
  检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作; 
  设置FLASH_CR寄存器的OPTWRE位为1; 
  设置FLASH_CR寄存器的OPTPG位为1; 
  写入要编程的半字到指定的地址; 
STM32F10x闪存编程 
 
页8/23