STM32 Flash详解

发布者:chwwdch最新更新时间:2020-12-25 来源: eefocus关键字:STM32  Flash  内部集成 手机看文章 扫描二维码
随时随地手机看文章

本文将根据ST官方Flashprogramming manual,文档编号:PM0059,讲解STM32F207内部Flash编程。

01、概述

这里的flash是指STM32F207内部集成的Flash

Flash存储器有以下特点

  • 最大1M字节的能力

  • 128位,也就是16字节宽度的数据读取

  • 字节,半字,字和双字写入

  • 扇区擦除和批量擦除

存储器的构成

主要存储区块包含4个16K字节扇区,1个64K字节扇区和7个128K字节扇区。

系统存储器是用于在系统boot模式启动设备的。这一块是预留给ST的。包括bootloader程序,boot程序用于通过以下接口对Flash进行编程。USART1、USART3、CAN2、USB OTG FS设备模式(DFU:设备固件升级)。boot程序由ST制造期间编写,用于保护防止错误写入和擦除操作。

512OTP(一次性编程)字节用于用户数据。OTP区域包含16个附加的字节,用于锁定响应的OTP数据。

选项字节,读写保护,BOR水平,软件/硬件看门狗和复位当设置处于待机和停机状态。

低功耗模式(参考参考手册的PWR部分)

对比参考手册的boot部分

当BOOT0为0是运行主存储区

当BOOT0为1,BOOT1为0时运行系统存储区

系统存储区运行的是ST出厂的bootloader代码,跳过过了用户的代码。如果在应用层代码锁定了JTAG管脚(将JTAG管脚用于普通GPIO),我们可以通过修改boot管脚状态,进入系统存储中,再进行debug。

 

02、Flash操作

2.1、读取

内置的Flash是处于CortexM3的数据总线上的,所以可以在通用地址空间之间寻址,任何32位数据的读操作都能访问Flash上的数据。

data32 = *(__IO uint32_t*)Address;


将Address强制转化为32位整型指针,然后取该指针所指向的地址的值,就得到了Address地址上的32位数据。


2.2、擦除

Flash 擦除操作可针对扇区或整个Flash(批量擦除)执行。执行批量擦除时,不会影响OTP扇区或配置扇区。


扇区擦除步骤


1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作


2、在FLASH_CR 寄存器中将SER 位置1 并选择要擦除的扇区(SNB)(主存储器块中的12个扇区之一)


3、将FLASH_CR 寄存器中的STRT 位置1


4、等待BSY 位清零


批量擦除步骤


1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作


2、将FLASH_CR 寄存器中的MER 位置1


3、将FLASH_CR 寄存器中的STRT 位置1


4、等待BSY 位清零


ST提供相应的库函数接口


FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_tVoltageRange)

FLASH_Status FLASH_EraseAllSectors(uint8_tVoltageRange)

注意到,有个特殊的参数VoltageRange,这是因为

这里就不再翻译了,就是在不同电压下数据访问的位数不同,我们是3.3V,所以是32位数据,这也就是在读数据是为什么要读取32位的原因。


2.3、写入

写入之前必须擦除,这里和NorFlash操作是相同的


复位后,Flash控制器寄存器(FLASH_CR)不允许写入的,去保护Flash闪存因为电气原因出现的以外操作,以下是解锁的步骤


1、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY1 = 0x45670123


2、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY2 = 0xCDEF89AB


将FLASH_CR 寄存器中的LOCK 位置为1 后,可通过软件再次锁定FLASH_CR 寄存器


ST提供了库函数


FLASH_Unlock();//解锁

FLASH_Lock();//重新上锁

备注:


当FLASH_SR 寄存器中的BSY 位置为1 后,将不能在写模式下访问FLASH_CR 寄存器。BSY 位置为1 后,对该寄存器的任何写操作尝试都会导致AHB 总线阻塞,直到BSY位清零


这要求我们在写入前必须判断下FLASH_SR寄存器中的BSY位。


ST提供了对用的库函数


FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR| FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);

 


写入步骤


1、检查FLASH_SR 中的BSY 位,以确认当前未执行任何主要Flash 操作


2、将FLASH_CR 寄存器中的PG 位置1。


3、通过不同的位宽对指定地址写入


4、等待BSY 位清零


对于写入接口,ST提供相应的库函数,提供了8位,16位,32位的操作,因为我们是3.3V电压,所以使用32位写入接口


FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)

2.4、中断

如果对于写入要求较高,可以使能中断,对于写入完成,写入错误都会有响应的中断响应。我也没有详细研究,参看Flash编程手册的15.5章节


03、Flash保护

3.1概述

Flash具有读写保护机制,主要是用过选项地址实现的。还有一次性编程保护


这讲述了选项字节的构成

用户修改选项字节


To run any operation on this sector, the option lock bit (OPTLOCK) inthe Flash option control register (FLASH_OPTCR) must be cleared. Tobe allowed to clear this bit, you have to perform the followingsequence:


1. Write OPTKEY1 = 0x0819 2A3B in the Flash option key register(FLASH_OPTKEYR)


2. Write OPTKEY2 = 0x4C5D 6E7F in the Flash option key register(FLASH_OPTKEYR)


The user option bytes can be protected against unwanted erase/programoperations by setting the OPTLOCK bit by software.


这个上面讲述的解锁Flash相同,就是要写入不能的数值


ST提供相应的库函数


void FLASH_OB_Unlock(void)

void FLASH_OB_Lock(void)


修改用户字节的步骤


1、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操作


2、在FLASH_OPTCR 寄存器中写入所需的选项值


3、将FLASH_OPTCR 寄存器中的选项启动位(OPTSTRT) 置1


4、等待BSY 位清零


3.2 读保护

从上面概述中得知,Flash读保护共分三个等级


 

等级0:没有保护


将0xAA 写入读保护选项字节(RDP) 时,读保护级别即设为0。此时,在所有自举配置(Flash用户自举、调试或从RAM 自举)中,均可执行与Flash 或备份SRAM 相关的所有读/写操作(如果未设置写保护)。



等级1:闪存读保护


这是擦除选项字节后的默认读保护级别。将任意值(分别用于设置级别0 和级别2 的0xAA和0xCC 除外)写入RDP 选项字节时,即激活读保护级别1。设置读保护级别1 后:


-在连接调试功能或从RAM 进行自举时,将不执行任何Flash 访问(读取、擦除和编程)。Flash 读请求将导致总线错误。而在使用Flash 用户自举功能或在系统存储器自举模式下操作时,则可执行所有操作


-激活级别1 后,如果将保护选项字节(RDP) 编程为级别0,则将对Flash 和备份SRAM执行批量擦除。因此,在取消读保护之前,用户代码区域会清零。批量擦除操作仅擦除用户代码区域。包括写保护在内的其它选项字节将保持与批量擦除操作前相同。OTP 区域不受批量擦除操作的影响,同样保持不变。


只有在已激活级别1 并请求级别0 时,才会执行批量擦除。当提高保护级别(0->1,1->2, 0->2) 时,不会执行批量擦除。


等级2:禁止调试/芯片读保护


注意:


在注意中写道,如果使能了等级2的读保护,永久禁止JTAG端口(相当于JTAG熔丝)ST也无法进行分析,说白了就是没办法再debug了,目前我没有使用到这个水平的读保护


读保护库函数


void FLASH_OB_RDPConfig(uint8_t OB_RDP)

查询读保护状态库函数


FlagStatus FLASH_OB_GetRDP(void)

3.3 写保护

Flash 中的用户扇区(0到11)具备写保护功能,可防止因程序计数器(PC) 跑飞而发生意外的写操作。当扇区i 中的非写保护位(nWRPi, 0 ≤ i ≤ 11) 为低电平时,无法对扇区i 执行擦除或编程操作。因此,如果某个扇区处于写保护状态,则无法执行批量擦除。


如果尝试对Flash 中处于写保护状态的区域执行擦除/编程操作(由写保护位保护的扇区、锁定的OTP 区域或永远不能执行写操作的Flash 区域,例如ICP),则FLASH_SR 寄存器中的写保护错误标志位(WRPERR) 将置1。


写保护库函数


void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)

查询写保护状态库函数


uint16_t FLASH_OB_GetWRP(void)

 

04、一次性可编程字节

没有使用过,使用了芯片就废了吧,没有做过这个等级等保护,可以参看Flash编程手册的2.7章节


05、代码

关于读写保护代码如何调用的问题,在stm32f2xx_flash.c文件中有调用说明.。


/** @defgroup FLASH_Group3 Option Bytes Programming functions

 *  @brief   Option Bytes Programming functions 

 *

@verbatim   

 ===============================================================================

                        Option Bytes Programming functions

 ===============================================================================  

 

   This group includes the following functions:

   - void FLASH_OB_Unlock(void)

   - void FLASH_OB_Lock(void)

   - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)

   - void FLASH_OB_RDPConfig(uint8_t OB_RDP)

   - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)

   - void FLASH_OB_BORConfig(uint8_t OB_BOR)

   - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data)              

   - FLASH_Status FLASH_OB_Launch(void)

   - uint32_t FLASH_OB_GetUser(void)            

   - uint8_t FLASH_OB_GetWRP(void)            

   - uint8_t FLASH_OB_GetRDP(void)              

   - uint8_t FLASH_OB_GetBOR(void)

   

   Any operation of erase or program should follow these steps:

   1. Call the FLASH_OB_Unlock() function to enable the FLASH option control register access

   2. Call one or several functions to program the desired Option Bytes:

      - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable 

        the desired sector write protection

      - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level

      - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure 

        the user Option Bytes.

      - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level

   3. Once all needed Option Bytes to be programmed are correctly written, call the

      FLASH_OB_Launch() function to launch the Option Bytes programming process.

     

     @note When changing the IWDG mode from HW to SW or from SW to HW, a system 

           reset is needed to make the change effective.

   4. Call the FLASH_OB_Lock() function to disable the FLASH option control register

      access (recommended to protect the Option Bytes against possible unwanted operations)

    

@endverbatim

  * @{

  */


关键字:STM32  Flash  内部集成 引用地址:STM32 Flash详解

上一篇:STM32 DMA详解
下一篇:TQ210_裸机编程(二)——按键控制LED灯

推荐阅读最新更新时间:2024-10-24 12:32

stm32中将结构体数据写到内部Flash时遇到的问题
在一次写代码的过程中,想把一个结构体的数据写到stm32单片机内部代码没有用到的空闲Flash,结构体开始时这样的: //#pragma pack(1) typedef struct { u8 DeviceAddr;//设备地址 LEDMODE LED_Mode; //LED 控制模式 BAUTRARE Baudrate; //串口波特率 u16 CRC16; //CRC校验 }SYSTEM_CONFIG; //#pragma pack() SYSTEM_CONFIG SystemConfig; LEDMODE和BAUTRARE是定义好的两个枚举类型,开始时发现同样的数据,在两次不同的CRC校验中得到的校验
[单片机]
STM32内部FLASH编程时遇到的ADC异常问题
某STM32用户使用STM32F407芯片开发产品。用到内部3个ADC,其中ADC1与ADC2工作在ADC双模式,ADC3独立工作。运行代码时给FLASH开锁编程后,发现ADC3不工作了(其DR数据寄存器似乎不更新了,倒是用来触发ADC的定时器TIM2依然正常),Flash编程前后ADC3配置寄存器CR1、CR2没有发生改变。如果重新配置ADC3后就能正常工作。 从问题现象来看,初步感觉跟flash编程有些关系。 经了解,客户的确做了flash编程,有一部分参数需要存放在FLASH内。他的ADC3是由TIM2触发的,ADC3的转换结果是通过DMA搬运。 鉴于此,我这边便提醒他,如果不是基于双BANK条件,在flash编程时CP
[单片机]
基于STM32内部Flash读写操作
本文主要介绍STM32多种的内部Flash读写方式和读写长文件的功能函数怎样编写。阅读完本文可以使你能够正常的完成Flash读写操作。 介绍 STM32 FLASH 不同型号的 STM32,其 FLASH 容量也有所不同,最小的只有 16K 字节,最大的则达到了1024K 字节。本次实验选用的STM32 开发板是F103ZET6,其 FLASH 容量为 512K 字节,属于大容量产品(另外还有中容量和小容量产品),大容量产品的闪存模块组织如图 所示: STM32 的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等 3 部分组成。 主存储器,该部分用来存放代码和数据常数(如 const 类型的数据)。对于大容量产品
[单片机]
基于<font color='red'>STM32</font>的<font color='red'>内部</font><font color='red'>Flash</font>读写操作
STM32CubeMX系列 | STM32内部FLASH
1. 内部FLASH简介 之前的文章中介绍过STM32F1利用SPI与外部FLASH(W25QXX芯片)通讯的例程,本例程将介绍STM32F1的内部FLASH,通过内部FLASH实现数据读写操作。 不同型号的STM32,其FLASH容量也有所不同,最小的只有16K字节,最大的则达到了1024K字节。此处我们使用的是STM32F103ZET6,其FLASH容量为512K字节,属于大容量产品,大容量产品的闪存模块组织图如下图示 STM32F1的闪存模块由:主存储器、信息块和闪存存储器接口寄存器3部分组成 主存储器:用来存放代码和数据常量,起始地址是0x08000000,BOOT0和BOOT1都接GND时,就是从该起始地址运行代码
[单片机]
STM32内部Flash
说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置、芯片ID、自举程序等等。当然, FLASH还可以用来装数据。 自己收集了一些资料,现将这些资料总结了一下,不想看的可以直接调到后面看怎么操作就可以了。 FLASH分类 根据用途,STM32片内的FLASH分成两部分:主存储块、信息块。 主存储块用于存储程序,我们写的程序一般存储在这里。 信息块又分成两部分:系统存储器、选项字节。 系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用ISP方式加载程序时,就是由这个程序执行。这个区域由芯片厂写入BootL
[单片机]
stm32 内部flash
嵌入式闪存 闪存 存储器有主存储块和信息块组成 大容量产品主存储块最大为64K×64位,每个存储块划分为256个2K字节的页 编程和擦除闪存 闪存编程一次可以写入16位(半字) 闪存擦除操作可以按页面擦除或完全擦除(全擦除)。全擦除不影响信息块 编程过程 页擦除过程 操作步骤 1.解锁 2.读操作 3.擦除操作 4.写操作 5.获取FLASH状态 6.锁定 举例 #define STM32_FLASH_BASE 0x08000000 #define STM32_PAGE_NUM 256 #define STM32_PAGE_SIZE (2 * 1024) void FLASH_read(u16 *buf,
[单片机]
<font color='red'>stm32</font> <font color='red'>内部</font><font color='red'>flash</font>
STM32单片机-操作访问内部Flash
目录: 1、STM32 FLASH操作流程 2、Flash基本知识点 3、OK,上干货,上代码 ------------------------------------------------------------------------------------------------- STM32中存储区分为:随机存取存储器RAM和只读存储器ROM。 其中: RAM为常说的内存,比如手机的2G内存4G内存等,就是程序跑起来的时候所占用的存储空间,特点是掉电数据丢失。 ROM为常说的硬盘,比如手机的64G和128G等,可以简单的理解为硬盘的存储空间,特点是掉电数据不丢失,所以又叫“非易失性存储器件”。 ROM又包含:
[单片机]
<font color='red'>STM32</font>单片机-操作访问<font color='red'>内部</font><font color='red'>Flash</font>
stm32专题二十八:读写内部Flash
内部Flash STM32芯片内部有一个FLASH存储器,主要用于存储代码。我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部FLASH中,由于FLASH存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部FLASH中加载代码并运行。 除了使用外部的工具(如下载器)读写内部FLASH外,STM32芯片在运行的时候,也能对自身的内部FLASH进行读写,因此,若内部FLASH存储了应用程序后还有剩余的空间,我们可以把它像外部SPI-FLASH那样利用起来,存储一些程序运行时产生的需要掉电保存的数据。 由于访问内部FLASH的速度要比外部的SPI-FLASH快得多,所以
[单片机]
<font color='red'>stm32</font>专题二十八:读写<font color='red'>内部</font><font color='red'>Flash</font>
热门资源推荐
热门放大器推荐
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved