本文介绍: 【代码】FLASH_STM32。
一、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
易变的,直接存取原始内存地址,防止编译器优化。
电子签名
- 存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名
- 闪存容量寄存器:
基地址:0x1FFF F7E0
大小:16位 - 产品唯一身份标识寄存器:
基地址: 0x1FFF F7E8
大小:96位
Reference
STM32入门教程-2023版(江科大)
原文地址:https://blog.csdn.net/Blank_3/article/details/135742458
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_61727.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。