一、FLASH简介
- STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程。
- 程序存储器(主存储器):存储程序代码;起始地址:0x0800 0000
- 系统存储器:存储Bootloader,用于串口下载;起始地址:0x1FFF F000
- 选项字节:存储独立的配置参数;起始地址:0x1FFF F800
- 闪存存储器接口即为STM32的FLASH外设,由于直接对FLASH进行操作较为复杂,所以借助FLASH外设,通过操作外设的寄存器,由外设自动对FLASH进行擦除和编程。
- 读写FLASH的用途:
- 利用程序存储器的剩余空间来保存掉电不丢失的用户数据
- 通过在程序中编程(IAP),实现程序的自我更新
- 在线编程(In-Circuit Programming – ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序
- 在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序。
二、FLASH外设基本结构
- 橙色部分为FLASH存储器;绿色部分为FLASH外设,是FLASH存储器的“管理员”。
三、FLASH流程
FLASH解锁
- FPEC共有三个键值:
- RDPRT键 = 0x000000A5
- KEY1 = 0x45670123
- KEY2 = 0xCDEF89AB
- 解锁:
- 复位后,FPEC被保护,不能写入FLASH_CR
- 在FLASH_KEYR先写入KEY1,再写入KEY2,解锁
- 错误的操作序列会在下次复位前锁死FPEC和FLASH_CR
- 加锁:
- 设置FLASH_CR中的LOCK位锁住FPEC和FLASH_CR
程序存储器编程(写入)
- 注意:每次只能写入一个半字(16位),任何非半字的数据都会导致错误
程序存储器页擦除
程序存储器全擦除
选项字节
- RDP:写入RDPRT键(0x000000A5)后解除读保护
- USER:配置硬件看门狗和进入停机/待机模式是否产生复位
- Data0/1:用户可自定义使用
- WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量)
四、FLASH配置
uint32_t MyFlash_ReadWord(uint32_t Address)
{
return *((__IO uint32_t *)(Address));
}
uint16_t MyFlash_ReadHalfWord(uint32_t Address)
{
return *((__IO uint16_t *)(Address));
}
uint8_t MyFlash_ReadByte(uint32_t Address)
{
return *((__IO uint8_t *)(Address));
}
void MyFlash_EraseAllPages(void)
{
FLASH_Unlock(); // 解锁
FLASH_EraseAllPages(); // 全擦除
FLASH_Lock(); // 加锁
}
void MyFlash_EraseAPage(uint32_t PageAddress)
{
FLASH_Unlock(); // 解锁
FLASH_ErasePage(PageAddress); // 页擦除
FLASH_Lock(); // 加锁
}
void MyFlash_ProgramWord(uint32_t Address, uint32_t Data)
{
FLASH_Unlock(); // 解锁
FLASH_ProgramWord(Address, Data); // 写入字
FLASH_Lock(); // 加锁
}
void MyFlash_ProgramWord(uint32_t Address, uint32_t Data)
{
FLASH_Unlock(); // 解锁
FLASH_ProgramHalfWord(Address, Data); // 写入半字
FLASH_Lock(); // 加锁
'对闪存读写的基本逻辑是:上电时将闪存读取到SRAM内存中,下电前再写回闪存,避免频繁的读写闪存'
'因为在读写FLASH闪存时,CPU会停止,会可能导致中断程序无法按时执行'
}
五、FLASH库函数
void FLASH_SetLatency(uint32_t FLASH_Latency);
void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess);
void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer);
void FLASH_Unlock(void);
// FLASH解锁
void FLASH_Lock(void);
// FLASH加锁
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
// 擦除某页
FLASH_Status FLASH_EraseAllPages(void);
// 全擦除
FLASH_Status FLASH_EraseOptionBytes(void);
// 擦除选项字节
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
// 在指定地址写入全字(32位),其实是写入两次半字
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
// 在指定地址写入半字(16位)
// 以下四个函数为选项字节写入函数
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);
//以下三个函数为获取选项字节当前状态
uint32_t FLASH_GetUserOptionByte(void);
uint32_t FLASH_GetWriteProtectionOptionByte(void);
FlagStatus FLASH_GetReadOutProtectionStatus(void);
FlagStatus FLASH_GetPrefetchBufferStatus(void);
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
// 中断使能
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
// 获取标志位
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
// 清除标志位
FLASH_Status FLASH_GetStatus(void);
// 获取状态
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
// 等待忙
五、补充
使用指针访问存储器
- 使用指针读指定地址下的存储器:
uint16_t Data = *((__IO uint16_t *)(0x08000000)); - 使用指针写指定地址下的存储器:
*((__IO uint16_t *)(0x08000000)) = 0x1234; - 其中:
#define __IO volatile
易变的,直接存取原始内存地址,防止编译器优化。
电子签名文章来源:https://www.toymoban.com/news/detail-835822.html
- 存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名
- 闪存容量寄存器:
基地址:0x1FFF F7E0
大小:16位 - 产品唯一身份标识寄存器:
基地址: 0x1FFF F7E8
大小:96位
Reference
STM32入门教程-2023版(江科大)文章来源地址https://www.toymoban.com/news/detail-835822.html
到了这里,关于FLASH_STM32的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!