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_STM32_第1张图片

  • 橙色部分为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

程序存储器编程(写入)
FLASH_STM32_第2张图片

  • 注意:每次只能写入一个半字(16位),任何非半字的数据都会导致错误

程序存储器页擦除
FLASH_STM32_第3张图片

程序存储器全擦除
FLASH_STM32_第4张图片
选项字节
FLASH_STM32_第5张图片

  • 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版(江科大)

你可能感兴趣的:(stm32,嵌入式硬件,单片机)