本文将根据ST官方Flashprogramming manual,文档编号:PM0059,讲解STM32F207内部Flash编程。git
这里的flash是指STM32F207内部集成的Flashgithub
Flash存储器有如下特色编程
存储器的构成app
主要存储区块包含4个16K字节扇区,1个64K字节扇区和7个128K字节扇区。函数
系统存储器是用于在系统boot模式启动设备的。这一块是预留给ST的。包括bootloader程序,boot程序用于经过如下接口对Flash进行编程。USART一、USART三、CAN二、USB OTG FS设备模式(DFU:设备固件升级)。boot程序由ST制造期间编写,用于保护防止错误写入和擦除操做。ui
512OTP(一次性编程)字节用于用户数据。OTP区域包含16个附加的字节,用于锁定响应的OTP数据。this
选项字节,读写保护,BOR水平,软件/硬件看门狗和复位当设置处于待机和停机状态。spa
低功耗模式(参考参考手册的PWR部分)翻译
对比参考手册的boot部分debug
当BOOT0为0是运行主存储区
当BOOT0为1,BOOT1为0时运行系统存储区
系统存储区运行的是ST出厂的bootloader代码,跳过过了用户的代码。若是在应用层代码锁定了JTAG管脚(将JTAG管脚用于普通GPIO),咱们能够经过修改boot管脚状态,进入系统存储中,再进行debug。
内置的Flash是处于CortexM3的数据总线上的,因此能够在通用地址空间之间寻址,任何32位数据的读操做都能访问Flash上的数据。
data32 = *(__IO uint32_t*)Address;
将Address强制转化为32位整型指针,而后取该指针所指向的地址的值,就获得了Address地址上的32位数据。
Flash 擦除操做可针对扇区或整个Flash(批量擦除)执行。执行批量擦除时,不会影响OTP扇区或配置扇区。
扇区擦除步骤
一、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操做
二、在FLASH_CR 寄存器中将SER 位置1 并选择要擦除的扇区(SNB)(主存储器块中的12个扇区之一)
三、将FLASH_CR 寄存器中的STRT 位置1
四、等待BSY 位清零
批量擦除步骤
一、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操做
二、将FLASH_CR 寄存器中的MER 位置1
三、将FLASH_CR 寄存器中的STRT 位置1
四、等待BSY 位清零
ST提供相应的库函数接口
FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_tVoltageRange)
FLASH_Status FLASH_EraseAllSectors(uint8_tVoltageRange)
注意到,有个特殊的参数VoltageRange,这是由于
这里就再也不翻译了,就是在不一样电压下数据访问的位数不一样,咱们是3.3V,因此是32位数据,这也就是在读数据是为何要读取32位的缘由。
写入以前必须擦除,这里和NorFlash操做是相同的
复位后,Flash控制器寄存器(FLASH_CR)不容许写入的,去保护Flash闪存由于电气缘由出现的之外操做,如下是解锁的步骤
一、在Flash 密钥寄存器(FLASH_KEYR) 中写入KEY1 = 0x45670123
二、在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);
写入步骤
一、检查FLASH_SR 中的BSY 位,以确认当前未执行任何主要Flash 操做
二、将FLASH_CR 寄存器中的PG 位置1。
三、经过不一样的位宽对指定地址写入
四、等待BSY 位清零
对于写入接口,ST提供相应的库函数,提供了8位,16位,32位的操做,由于咱们是3.3V电压,因此使用32位写入接口
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
若是对于写入要求较高,可使能中断,对于写入完成,写入错误都会有响应的中断响应。我也没有详细研究,参看Flash编程手册的15.5章节
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)
修改用户字节的步骤
一、检查FLASH_SR 寄存器中的BSY 位,以确认当前未执行任何Flash 操做
二、在FLASH_OPTCR 寄存器中写入所需的选项值
三、将FLASH_OPTCR 寄存器中的选项启动位(OPTSTRT) 置1
四、等待BSY 位清零
从上面概述中得知,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)
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)
没有使用过,使用了芯片就废了吧,没有作过这个等级等保护,能够参看Flash编程手册的2.7章节
关于读写保护代码如何调用的问题,在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 * @{ */
编程Flash,写保护,读保护代码开源
开源地址:
https://github.com/strongercjd/STM32F207VCT6
点击查看本文所在的专辑,STM32F207教程