依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
PM0042
编程手册
STM32F10xxx闪存编程
简介
本编程手册介绍了如何烧写STM32F101xx、STM32F102xx和STM32F103xx微控制器的闪存存
储器。为方便起见,在本文中除特别说明外,统称它们为STM32F10xxx。
STM32F10xxx内嵌的闪存存储器可以用于在线编程(ICP)或在程序中编程(IAP)烧写。
在线编程(In-Circuit Programming – ICP)方式用于更新闪存存储器的全部内容,它通过JTAG、
SWD协议或系统加载程序(Bootloader)下载用户应用程序到微控制器中。ICP是一种快速有效的
编程方法,消除了封装和管座的困扰。
与ICP方式对应,在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任
一种通信接口(如I/O端口、USB、CAN、UART、I2C、SPI等)下载程序或数据到存储器中。IAP
允许用户在程序运行时重新烧写闪存存储器中的内容。然而,IAP要求至少有一部分程序已经
使用ICP烧到闪存存储器中。
闪存接口是在AHB协议上实现了对指令和数据的访问,它通过对存储器的预取缓存,加快了存
储器的访问;闪存接口还实现了在所有工作电压下对闪存编程和擦除所需的逻辑电路,这里还
包括访问和写入保护以及选择字节的控制。
STM32F10xxx闪存编程手册
页1/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
目录
1 概述...................................................................................................................................................4
1.1 特性 ........................................................................................................................................4
1.2 闪存模块组织..........................................................................................................................4
2 读/编写STM32F10xxx内置闪存 .........................................................................................................7
2.1 简介 ........................................................................................................................................7
2.2 读操作.....................................................................................................................................7
2.2.1 取指令..........................................................................................................................7
2.2.2
D-Code接口 .................................................................................................................7
2.2.3 闪存访问控制器............................................................................................................7
2.3 闪存编程和擦除控制器(FPEC)................................................................................................8
2.3.1 键值..............................................................................................................................8
2.3.2 解除闪存锁...................................................................................................................8
2.3.3 主闪存编程...................................................................................................................8
2.3.4 闪存擦除 ......................................................................................................................9
2.3.5 选择字节编程 .............................................................................................................10
2.4 保护 ......................................................................................................................................12
2.4.1 写保护........................................................................................................................12
2.4.2 读保护........................................................................................................................12
2.4.3 选择字节块写保护 ......................................................................................................13
2.5 选择字节说明........................................................................................................................13
3 寄存器说明 ......................................................................................................................................15
3.1 闪存访问控制寄存器(FLASH_ACR)......................................................................................15
3.2
FPEC键寄存器(FLASH_KEYR)............................................................................................16
3.3 闪存OPTKEY寄存器(FLASH_OPTKEYR) ............................................................................16
3.4 闪存状态寄存器(FLASH_SR)................................................................................................17
3.5 闪存控制寄存器(FLASH_CR) ...............................................................................................18
3.6 闪存地址寄存器(FLASH_AR)................................................................................................19
3.7 选择字节寄存器(FLASH_OBR).............................................................................................19
3.8 写保护寄存器(FLASH_WRPR) .............................................................................................20
3.9 闪存寄存器映像 ....................................................................................................................21
STM32F10xxx闪存编程
页2/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
术语
下面列出了本文档中所用到的术语和缩写的简要说明:
小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx、STM32F102xx
和STM32F103xx微控制器。
中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx、STM32F102xx
和STM32F103xx微控制器。
大 容 量 产 品是 指 闪 存 存 储 器 容 量 在256K 至 512K 字 节 之 间 的 STM32F101xx 和
STM32F103xx微控制器。
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总线(常数和调试访问)与闪存数据存储器接口
的总线。
选择字节:存放在闪存中的产品配置位。
OBL:选择字节加载单元。
AHB:先进高性能总线。
STM32F10xxx闪存编程
页3/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
1 概述
1.1 特性
多达512K字节闪存
存储器配置:
− 主存储块:
小容量产品:4K x 64位
中容量产品:16K x 64位
大容量产品:64K x 64位
− 信息块:258 x 64位
闪存接口的特性:
带预取缓冲器的读接口(2x64位)
选择字节加载
闪存编程/擦除操作
读出/写入保护
低功耗模式
1.2 闪存模块组织
按照不同容量,存储器组织成32个1K字节/页(小容量)、128个1K字节/页(中容量)、256个2K字
节/页(大容量)的主存储器块和一个信息块,见表1、:
表1 闪存模块组织(小容量产品)
块
主存储器
信息块
闪存存储器
接口寄存器
名称
页0
页1
页2
页3
页4
.
.
.
页31
启动程序代码
用户选择字节
FLASH_ACR
FLASH_KEYR
FLASH_OPTKEYR
FLASH_SR
FLASH_CR
FLASH_AR
保留
FLASH_OBR
FLASH_WRPR
地址范围
长度(字节)
0x0800 0000 – 0x0800 03FF
0x0800 0400 – 0x0800 07FF
0x0800 0800 – 0x0800 0BFF
0x0800 0C00 – 0x0800 0FFF
0x0800 1000 – 0x0800 13FF
.
.
.
0x0800 7C00 – 0x0800 FFFF
0x1FFF F000 – 0x1FFF F7FF
0x1FFF F800 – 0x1FFF F80F
0x4002 2000 – 0x4002 2003
0x4002 2004 – 0x4002 2007
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
1K
1K
1K
1K
1K
.
.
.
1K
2K
16
4
4
4
4
4
4
4
4
4
STM32F10xxx闪存编程
页4/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
表2 闪存模块组织(中容量产品)
块
主存储器
信息块
闪存存储器
接口寄存器
名称
页0
页1
页2
页3
页4
.
.
.
页127
启动程序代码
用户选择字节
FLASH_ACR
FLASH_KEYR
FLASH_OPTKEYR
FLASH_SR
FLASH_CR
FLASH_AR
保留
FLASH_OBR
FLASH_WRPR
表3 闪存模块组织(大容量产品)
地址范围
长度(字节)
0x0800 0000 – 0x0800 03FF
0x0800 0400 – 0x0800 07FF
0x0800 0800 – 0x0800 0BFF
0x0800 0C00 – 0x0800 0FFF
0x0800 1000 – 0x0800 13FF
.
.
.
0x0801 FC00 – 0x0801 FFFF
0x1FFF F000 – 0x1FFF F7FF
0x1FFF F800 – 0x1FFF F80F
0x4002 2000 – 0x4002 2003
0x4002 2004 – 0x4002 2007
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
1K
1K
1K
1K
1K
.
.
.
1K
2K
16
4
4
4
4
4
4
4
4
4
地址范围
长度(字节)
2K
2K
2K
2K
.
.
.
2K
2K
16
4
4
4
4
4
4
4
4
4
块
主存储器
信息块
闪存存储器
接口寄存器
名称
页0
页1
页2
页3
.
.
.
0x0800 0000 – 0x0800 07FF
0x0800 0800 – 0x0800 0FFF
0x0800 1000 – 0x0801 17FF
0x0800 1800 – 0x0801 FFFF
.
.
.
页255
启动程序代码
用户选择字节
FLASH_ACR
FLASH_KEYR
FLASH_OPTKEYR
FLASH_SR
FLASH_CR
FLASH_AR
保留
FLASH_OBR
FLASH_WRPR
0x0807 F800 – 0x0807 FFFF
0x1FFF F000 – 0x1FFF F7FF
0x1FFF F800 – 0x1FFF F80F
0x4002 2000 – 0x4002 2003
0x4002 2004 – 0x4002 2007
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
闪存存储器被组织成32位宽的存储器单元,可以存放代码和数据常数。每一个STM32F10xxx微
控制器的闪存模块都有一个特定的启始地址,有关的启始地址请参考STM32F10xxx参考手册。
STM32F10xxx闪存编程
页5/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
信息块分为两个部分:
系统存储器是用于存放在系统存储器自举模式下的启动程序,这个区域只保留给ST使用,
启动程序使用USART1串行接口实现对闪存存储器的编程;ST在生产线上对这个区域编程
并锁定以防止用户擦写。关于使用这个启动程序的详细信息,请参阅AN2606。
选择字节
对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压
由内部产生。
闪存存储器有两种保护方式防止非法的访问(读、写、擦除):
页写入保护
读出保护
详情请参考0节。
在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地
进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。
进行闪存编程操作时(写或擦除),必须打开内部的RC振荡器(HSI)。
闪存存储器可以用ICP或IAP方式编程。
注: 在低功耗模式下,所有闪存存储器的操作都被中止。详情请阅STM32F10xxx参考手册。
STM32F10xxx闪存编程
页6/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
2 读/编写STM32F10xxx内置闪存
2.1 简介
本节介绍如何读和对STM32F10xxx的内置闪存编程。
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时进行,使用HSI或HSE并且关闭PLL时可得到这样的
频率);在闪存访问控制寄存器中有一个控制位可以选择这种工作方式。
注意: 当使用了预取缓冲器和AHB时钟的预分频系数不为’1’时,不能使用半周期访问方式。
访问时间调节器
为了维持读闪存的控制信号,预取控制器的时钟周期与闪存访问时间的比例由闪存访问控制器
控制;这个值给出了能够正确地读取数据时,闪存控制信号所需的时钟周期数目;芯片复位
后,该值为’0’,闪存访问仅为一个时钟周期。
2.2.2 D-Code接口
D-Code接口包含CPU端简单的AHB接口和对闪存访问控制器的仲裁器提出访问请求的逻辑电
路。D-Code的访问优先于预取指令的访问。这个接口使用预取缓冲器的访问时间调节器模块。
2.2.3 闪存访问控制器
这个模块就是在I-Code上的指令预取请求和D-Code接口上读请求的仲裁器。
D-Code接口的请求优先于I-Code的请求。
STM32F10xxx闪存编程
页7/22
依据2008年9月英文第4版翻译。本译文仅供参考,如有翻译错误,请以英文原稿为准
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模块,这个特定的序列是在FLASH_KEYR写入两个键值
(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暂停,直到此次闪存编程结束。
STM32F10xxx闪存编程
页8/22