关于stm32(CubeMX+HAL库)的掉电检测以及flash读写

1.掉电检测

CubeMX配置

只需使能PVD中断即可

但是使能了PVD中断后还需要自行配置一些PWR寄存器中的参数,我也通过HAL库进行编写

复制代码
void PVD_config(void)
{
	//配置PWR
	PWR_PVDTypeDef sConfigPVD;                    
	sConfigPVD.PVDLevel = PWR_PVDLEVEL_7;            //低于2.9V触发掉电中断
	sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING;        //掉电后PVDO会置一,因此选择上升沿触发
	HAL_PWR_ConfigPVD(&sConfigPVD);                  //HAL库配置PVD函数
 
	//使能PVD
	HAL_PWR_EnablePVD();        //开启掉电中断
}

因为我们使用了CubeMX配置了中断优先级,因此此处不需要再次配置,

优先级在void HAL_MspInit(void)中配置

2.Flash的读写

我使用的是stm32f103c8t6 flash最大地址为 0x08010000

这里我把数据存放在0x0800C000

a).flash的擦除

在写之前需要擦除flash中的内容

flash擦除函数

复制代码
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit,uint32_t *SectorError)
描述    :    擦除指定的Flash页
返回    :    状态    HAL_OK    HAL_ERROR    HAL_TIMEOUT
参数1    :    擦除flash时使用的结构体指针
参数2    :    错误信息

擦除flash时使用的结构体指针
typedef struct
{
  uint32_t    TypeErase;        //擦除方式 : 批量擦除或页面擦除
  uint32_t    Banks;            //
  uint32_t    PageAddress;    //要擦除的首地址    (0x08000000        -    FLASH_BANKx_END)
  uint32_t    NbPages;        //待擦除的页面数    (1    -    max number of pages - value of initial page)
} FLASH_EraseInitTypeDef;

擦除方式
#define FLASH_TYPEERASE_PAGES     0x00U          /*!<Pages erase only*/
#define FLASH_TYPEERASE_MASSERASE 0x02U      /*!<Flash mass erase activation*/

FLASH_BANKx_END		stm32f103c8t6的最大地址是0x08010000(64kb)

b).flash的写入

flash写入函数

复制代码
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
描述	:	向flash中的一页写入数据
返回	:	状态	HAL_OK	HAL_ERROR	HAL_TIMEOUT
参数1	:	传输的数据类型
参数2	:	要写入的首地址
参数3	:	要写入的数据

传输的数据类型
#define FLASH_TYPEPROGRAM_HALFWORD			0x01U
#define FLASH_TYPEPROGRAM_WORD				0x02U
#define FLASH_TYPEPROGRAM_DOUBLEWORD		0x03U

c).flash的读取

*(__IO uint32_t *)Flash_Addr;

Flash_Addr : 要读取的首地址

在擦除和写入前都需要解锁flash结束后需要上锁

//解锁

HAL_FLASH_Unlock();

//上锁

HAL_FLASH_Lock();

实例代码

复制代码
/******************************************************************************
function : void erase_flash(uint32_t addr)
describtion : 擦除flash的一个扇区
input : uint32_t addr		//擦除的首地址
return : void
******************************************************************************/
void erase_flash(uint32_t addr)
{
	uint32_t Errcode = 0;
	
	//初始化擦除结构体
	FLASH_EraseInitTypeDef Erase;
	Erase.TypeErase = FLASH_TYPEERASE_PAGES;
	Erase.PageAddress = FLASH3_ADDR;
	Erase.NbPages = 1;
	
	//解锁
	HAL_FLASH_Unlock();
	
	//擦除要写入的扇区
	if(HAL_FLASHEx_Erase(&Erase,&Errcode) != HAL_OK)
	{
		return;
	}
	
	//上锁
	HAL_FLASH_Lock();
}

/******************************************************************************
function : uint16_t read_flash(uint32_t addr)
describtion : 读flash中的一个16位数据
input : uint32_t addr		//读取的首地址
return : uint16_t			//读到的数据
******************************************************************************/
uint16_t read_flash(uint32_t addr)
{
	return *((__IO uint32_t *)addr);
}

/******************************************************************************
function : void write_flash(uint32_t addr , uint16_t w_data)
describtion : 将一个十六位数据写入flash
input : void
return : void
******************************************************************************/
void write_flash(uint32_t addr , uint16_t w_data)
{	
	//解锁
	HAL_FLASH_Unlock();
	
	//写入数据
	if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,addr,w_data) != HAL_OK)
	{
		return;
	}
	
	//上锁
	HAL_FLASH_Lock();
}

如果要实现掉电写入数据,只需要在程序读完数据后擦除flash,然后在掉电中断的回调函数中写入flash即可

注:不可以在掉电回调函数中擦除,因为擦除比较费时,掉电的时间可能不够!

有哪里写的不好欢迎在评论区讨论!

相关推荐
传感器与混合集成电路1 天前
210℃与175℃高温存储器选型研究:LHM256MB与LDMF4GA-H架构与可靠性对比(上)
嵌入式硬件·能源
时光找茬1 天前
【瑞萨AI挑战赛-FPB-RA6E2】+ 从零开始:FPB-RA6E2 开箱测评与 e2 studio 环境配置
c++·单片机·边缘计算
17(无规则自律)1 天前
【CSAPP 读书笔记】第二章:信息的表示和处理
linux·嵌入式硬件·考研·高考
@good_good_study1 天前
FreeRTOS内存管理
单片机
Hello_Embed1 天前
libmodbus 移植 STM32(基础篇)
笔记·stm32·单片机·学习·modbus
qq_397562311 天前
QT工程 , 生成别的电脑运行的exe程序
嵌入式硬件·qt
qqssss121dfd1 天前
STM32H750XBH6的ETH模块移植LWIP
网络·stm32·嵌入式硬件
想放学的刺客2 天前
单片机嵌入式试题(第27期)设计可移植、可配置的外设驱动框架的关键要点
c语言·stm32·单片机·嵌入式硬件·物联网
天昊吖2 天前
stc8H启用DMA发送后 卡住【踩坑日志】
单片机
李永奉2 天前
杰理芯片SDK开发-ENC双麦降噪配置/调试教程
人工智能·单片机·嵌入式硬件·物联网·语音识别