STM32学习笔记 | 片内FLASH读写失败问题分析

FLASH,指Flash ,是一种非易失性存储器(闪存),掉电能正常保存数据 。
STM32的存储器通常包含内部SRAM、内部FLASH,部分系列还包含 。其中FLASH通常用于存储代码或数据,可被读写访问 。
嵌入式专栏
STM32 FLASH 基础内容
STM32的FLASH组织结构,可能因不同系列、型号略有不同 。比如大家熟悉的中小容量一页大小只有1K,而F1大容量一页有2K 。
还比如有些系列以扇区为最小单元,有的扇区最小16K,有的128K不等 。
本文主要结合F4系列来描述关于FLASH的相关内容 。
1.Flash 结构
通常Flash包含几大块,这里以F40x为例:
2.Flash常规操作
Flash 读、写(编程)、擦除:
(提示:不同系列可能存在差异,比如还有字节读取,页擦除等)
Flash 读、写保护:通过配置选项字节实现 。
3.Flash容量
STM32的Flash容量出厂已经决定,可根据型号得知容量大小 。
4.存储器端格式
目前STM32存储器组织结构默认为小端格式:数据的低字节保存在内存的低地址 。
更多内容请查阅芯片对应的参考手册 。
嵌入式专栏
FLASH 选项字节
STM32内部Flash具有读写保护功能,想要对Flash进行读写操作,首先要去除读写保护,读写保护通过配置选项字节完成 。
配置选项字节,常见两种方式:1.软件编码;2.编程工具;
1.软件编码
比如系列标准外设库库提供函数:
voidFLASH_OB_Unlock(void);voidFLASH_OB_Lock(void);voidFLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState);voidFLASH_OB_WRP1Config(uint32_t OB_WRP, FunctionalState NewState);voidFLASH_OB_PCROPSelectionConfig(uint8_t OB_PcROP);voidFLASH_OB_PCROPConfig(uint32_t OB_PCROP, FunctionalState NewState);voidFLASH_OB_PCROP1Config(uint32_t OB_PCROP, FunctionalState NewState);voidFLASH_OB_RDPConfig(uint8_t OB_RDP);voidFLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);voidFLASH_OB_BORConfig(uint8_t OB_BOR);voidFLASH_OB_BootConfig(uint8_t OB_BOOT);FLASH_Status FLASH_OB_Launch(void);uint8_tFLASH_OB_GetUser(void);uint16_tFLASH_OB_GetWRP(void);uint16_tFLASH_OB_GetWRP1(void);uint16_tFLASH_OB_GetPCROP(void);uint16_tFLASH_OB_GetPCROP1(void);FlagStatusFLASH_OB_GetRDP(void);uint8_tFLASH_OB_GetBOR(void);
软件编码通过调用这些函数接口就可以配置选项字节 。
2.编程工具
比如编程工具:
配置STM32选项字节,还可通过ST-LINK 、STVP等类似工具进行配置 。
提示:不同型号的STM32选项字节可能略有差异 。
嵌入式专栏
FLASH 读写擦除操作
STM32内部Flash和其他外部Flash类似,支持读、写、擦除等常规操作 。对内部Flash操作之前通常需要解锁、去保护等操作 。
比如:
FLASH_OB_Lock();FLASH_OB_WRPConfig(OB_WRP_Sector_All, ENABLE);FLASH_OB_PCROPConfig(OB_PCROP_Sector_All, ENABLE);
1.读数据
读取内部Flash数据通常有两种方式:
程序(编码)读取:
uint32_t uwData32 = 0;uint32_t uwAddress = 0x08001000;uwData32 = *(__IO uint32_t*)uwAddress;
外部编程工具读取:
【STM32学习笔记 | 片内FLASH读写失败问题分析】读取前提:没有读保护,设置好读取地址,长度、数据宽度等 。
2.写数据
往STM32内部Flash写数据和读数据类似,但写数据地址不能有数据,也就是写之前要擦除数据 。
所以,相对读数据,通常写之前需要一些额外操作,比如:
FLASH_Unlock();FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);