STM32+HAL+ FLASH

STM32+HAL+ FLASH

一、什么是FLASH

可以理解为一种存储空间,和EEPROM差不多,能使数据掉电不丢失

下图为大容量的

STM32+HAL+ FLASH_第1张图片

  • 主存储器

  • 信息块

  • FPEC

  • 主存储器

该部分用来存放代码和数据常数(如 const 类型的数据)。对于大容量产品,其被划分为 256 页,每页 2K 字节。注意,小容量和中容量产品则每页只有 1K 字节。从上图可以看出主存储器的起始地址就是0X08000000, BOOT0、BOOT1 都接 GND 的时候,就是从 0X08000000 开始运行代码的。

  • 信息块

该部分分为 2 个小部分,其中启动程序代码,是用来存储 ST 自带的启动程序,用于串口下载代码,当 BOOT0 接 V3.3, BOOT1 接 GND 的时候,运行的就是这部分代码。用户选择字节,则一般用于配置写保护、读保护等功能,这里我们不做介绍,大家可以百度了解。

  • 闪存存储器接口寄存器(FPEC)

该部分用于控制闪存读写等,是整个闪存模块的控制机构。对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理;编程与擦除的高电压由内部产生。

闪存的编程与擦除

FPEC的7个寄存器

  • FPEC 键寄存器(FLASH_ KEYR)
  • 选择字节键寄存器(FLASH OPTKEYR)
  • 闪存控制寄存器(FLASH CR)
  • 闪存状态寄存器(FLASH SR)
  • 闪存地址寄存器(FLASH_ AR)
  • 选择字节寄存器(FLASH OBR)
  • 写保护寄存器(FLASH_ _WRPR)
FLASH_KEYR 写入键值解锁
FLASH_OPTKEYR 写入键值解锁选项字节操作
FLASH_CR 选择并启动闪存操作
FLASH_SR 查询闪存操作状态
FLASH_AR 存储闪存操作地址
FLASH_OBR 选项字节中主要数据的映象
FLASH_WRPR 选项字节中写保护字节的映象

FPEC键寄存器 (FLASH_KEYR)

RDPRT键 KEY 1 KEY 2
0X000000A5 0X45670123 0XCDEF89AB

用途:写入KEY1和KEY2后解锁FPEC

HAL库函数

锁定与解锁

HAL_StatusTypeDef HAL_FLASH_Unlock(void);//解锁函数
HAL_StatusTypeDef HAL_FLASH_Lock(void);//锁定函数

写操作

HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);//FLASH写操作函数 

TypeProgram用来区别要写入的类型:

  • FLASH_TYPEPROGRAM_BYTE-----------------------8位
  • FLASH_TYPEPROGRAM_HALFWORD------------16位
  • FLASH_TYPEPROGRAM_WORD-------------------32位
  • FLASH_TYPEPROGRAM_DOUBLEWORD-------64位

擦除函数

HAL_StatusTypeDef
 HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);

pEraseInit结构体定义

typedef struct
{
  uint32_t TypeErase;   /*!< TypeErase: Mass erase or page erase.  擦除类型
                             This parameter can be a value of @ref FLASHEx_Type_Erase */
  
  uint32_t Banks;       /*!< Select banks to erase when Mass erase is enabled.Bank编号
                             This parameter must be a value of @ref FLASHEx_Banks */    
  
  uint32_t PageAddress; /*!< PageAdress: Initial FLASH page address to erase when mass erase is disabled  擦除页面地址
                             This parameter must be a number between Min_Data = 0x08000000 and Max_Data = FLASH_BANKx_END 
                             (x = 1 or 2 depending on devices)*/
  
  uint32_t NbPages;     /*!< NbPages: Number of pagess to be erased.
               页数              This parameter must be a value between Min_Data = 1 and Max_Data = (max number of pages - value of initial page)*/
                                                          
} FLASH_EraseInitTypeDef;

等待函数

HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
     flag will be set */

读 FLASH特定地址数据函数(正点原子)

u16 STMFLASH_ReadHalfWord(u32 faddr){
    return *(vu16*)faddr;
}

编程流程

解锁 HAL_FLASH_Unlock();
擦除 **HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef pEraseInit, uint32_t PageError);
写入 HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
上锁 HAL_FLASH_Lock();

参考代码

uint32_t writeFlashData = 0x00000009;
uint32_t addr = 0x08007000;

//FLASH写入数据测试
void FLASH_WRITE(void)
{
    FLASH_EraseInitTypeDef f;
	f.TypeErase = FLASH_TYPEERASE_PAGES;
	f.PageAddress = addr;
	f.NbPages = 1;
	uint32_t PageError = 0;
    //解锁
  HAL_FLASH_Unlock();
	//擦除
	HAL_FLASHEx_Erase(&f, &PageError);

	//写入
	HAL_FLASH_Program(TYPEPROGRAM_WORD, addr, writeFlashData);
	
	//上锁
  HAL_FLASH_Lock();
}

//FLASH读取数据测试
void Prinf_FLASH(void)
{
  uint32_t temp = *(__IO uint32_t*)(addr);

	printf("addr:0x%x, data:0x%x\r\n", addr, temp);
}

主函数

void main(void)
{
	writeFlashData = 0x00000009;
	FLASH_WRITE();
	Prinf_FLASH();
	while(1);
}

你可能感兴趣的:(每周记录)