关于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即可

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

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

相关推荐
yugi98783839 分钟前
基于51单片机的篮球计分器设计
单片机·嵌入式硬件·51单片机
编程之升级打怪42 分钟前
什么是PWM
嵌入式硬件
zmj3203241 小时前
单片机内存在C 语言编译后的 “逻辑分区”
c语言·单片机·内存分区
魈学习ing2 小时前
IO口无法外部上拉到3.3V以上,或被钳位到3.8V左右
stm32
小柯博客2 小时前
STM32MP2 Secure Boot实战
stm32·单片机·嵌入式硬件
Ww.xh2 小时前
STM32调用AI接口完整教程
stm32·单片机·嵌入式硬件
ZYNQRFSOC3 小时前
基于安路PH2A系列FPGA的JESD204B接口测试
嵌入式硬件·fpga开发
LCG元3 小时前
STM32实战:基于STM32F407的LWIP以太网通信(TCP Server)
stm32·嵌入式硬件·tcp/ip
Wave8454 小时前
嵌入式底层核心架构详解 (Cortex-M3)
stm32·架构
渡己之道4 小时前
笔记-lvgl移植到stm32f407
c语言·笔记·stm32