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

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

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

相关推荐
不悔哥2 天前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
XiHongShi20162 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
优信电子2 天前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
深圳老胡2 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
wuyk5552 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
女神下凡2 天前
嵌入式设计的各种存储芯片的硬件/软件设计规范,非常全面。
arm开发·单片机·嵌入式硬件
梅梅9662 天前
一款mipi转lvds的lcd调试(LT8912B)
单片机·计算机外设·电脑·显示器·pd芯片
开发笔记-阿牛2 天前
蓝牙音乐灯拆解,又一次拆到蓝牙音乐灯芯片CK6865L
人工智能·单片机·嵌入式硬件·音视频·音频
从零开始的嵌入式之旅2 天前
day47
arm开发·经验分享·笔记·嵌入式硬件
恒锐丰科技林技术员2 天前
EG1164 高压大电流升压同步整流芯片解析
经验分享·嵌入式硬件·硬件工程