STM32CubeMX-Flash Hal库 内部Flash掉电存储

本文介绍了如何使用STM32F103ZET6的内部FLASH进行数据的读写操作,通过HAL库提供的函数,实现了数据的解锁、擦除、写入和锁定。文章强调了如何存储不同类型的數據,并提供了代码示例,包括`WriteFlash`、`Flash_Read`及自定义的读写函数,适用于不同场景下的数据持久化需求。
摘要由CSDN通过智能技术生成


前言

本文将介绍STM32F1的内部FLASH,通过内部FLASH实现数据读写操作。从而做到掉电存储。不同型号的STM32,其FLASH:容量也有所不同,最小的只有 16K字节,最大的则达到了1024K字节。此处我们使用的是 STM32F103ZET6,其FLASH容量为512K字节,属于大容量产品,大容量产品的闪存模块组织图如下图示
在这里插入图片描述

别的博主的文章大多都是用键盘来验证是否存储完成,但是我感觉我又不是每次都要用按键存储,且存储的东西都很单一,我这篇里面会提到如何存储各种数据。


一、HAL库提供的代码

//源文件: stm32f1xx_hal_flash.c和stm32f1xx_hal_flash_ex.c
HAL_FLASH_Unlock(void); //解锁函数
HAL_FLASH_Lock(void);   //锁定函数
HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);   //写操作函数
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);   //擦除函数
HAL_FLASH_WaitForLastOperation(uint32_t Timeout);   //等待操作完成函数

这些都是本文要用到的。

cubemx不需要进行额外的配置。

二、代码编程

1.flash.c文件

首先给出整体代码随后会对每一部分进行一定的分析

#include "flash.h"
#include <stdio.h>
#include <string.h>
/*FLASH写入程序*/
void WriteFlash(uint32_t addr,uint32_t *Data,uint32_t L)
{
	uint32_t i=0;
	/* 1/4解锁FLASH*/
	HAL_FLASH_Unlock();
	/* 2/4擦除FLASH*/
	/*初始化FLASH_EraseInitTypeDef*/
	/*擦除方式页擦除FLASH_TYPEERASE_PAGES,块擦除FLASH_TYPEERASE_MASSERASE*/
	/*擦除页数*/
	/*擦除地址*/
	FLASH_EraseInitTypeDef FlashSet;
	FlashSet.TypeErase = FLASH_TYPEERASE_PAGES;
	FlashSet.PageAddress = addr;
	FlashSet.NbPages = 1;
	/*设置PageError,调用擦除函数*/
	uint32_t PageError = 0;
	HAL_FLASHEx_Erase(&FlashSet, &PageError);
	/* 3/4对FLASH烧写*/
	for(i=0;i<L;i++)
	{
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr+4*i, Data[i]);
	}
	/* 4/4锁住FLASH*/
	HAL_FLASH_Lock();
}

void Flash_Read(uint32_t address, uint32_t *data, uint16_t length)
{
    uint16_t i;
    for (i = 0; i < length; i++) {
        data[i] = *(__IO uint32_t *)(address + (i * 4)); // 以字为单位读取Flash
    }
}
//
DataToSave data_to_save ;//这个是要保存的数据
void my_flash_write(void)
{
	// 将数据转换为uint32_t数组以便写入Flash
	uint32_t flash_data[sizeof(DataToSave) / sizeof(uint32_t)];
	memcpy(flash_data, &data_to_save, sizeof(DataToSave));

	// 将数据写入Flash
	WriteFlash(FLASH_SAVE_ADDR, flash_data, sizeof(DataToSave) / sizeof(uint32_t));
}
int fff;//这是用来测试的
void my_flash_read(void)
{
	// 将读取到的数据转换回原始结构体
	DataToSave data_read;
	// 从Flash中读取数据
	uint32_t flash_data_read[sizeof(DataToSave) / sizeof(uint32_t)];
	Flash_Read(FLASH_SAVE_ADDR, flash_data_read, sizeof(DataToSave) / sizeof(uint32_t));
	memcpy(&data_read, flash_data_read, sizeof(DataToSave));
	// 现在,data_read.float_data 和 data_read.int_data 中分别包含从Flash中读取的float和int数据
	//读取完以后的数据可以从这里拿出!!!!
	fff=data_read.int_data[0];
}

WriteFlash函数

先解锁flash然后配置一下,再进行擦除(写入0即可),接着把需要数据写入,最后还需要上锁

Flash_Read函数

以字为单位读取Flash

my_flash_read函数

当你需要存储数据的时候直接调用这个函数就可以

my_flash_read函数

当你需要读取的时候直接调用就可以

2.flash.h文件

这里注意定义了一个结构体DataToSave,结构体里面就是你需要的存储的数据,你只需要定义好你需要存储的类型即可。

#ifndef __FLASH_H
#define __FLASH_H
#include "main.h"
void WriteFlash(uint32_t addr,uint32_t *Data,uint32_t L);
void Flash_Read(uint32_t address, uint32_t *data, uint16_t length);
#define FLASH_SAVE_ADDR  (0x08060000) // 这地方不用改直接用这个地址。
typedef struct {
    float float_data[4];
    int int_data[4];
} DataToSave;								//这个是要保存数据的结构体
extern DataToSave data_to_save ;//这个是要保存的数据
void my_flash_write(void);
void my_flash_read(void);
#endif

三、主函数编写

由于我们在.h文件中声明了外部变量extern DataToSave data_to_save ;所以当使用的时候只需要包含头文件就可以了,不用在main.c中进行变量的声明了。
由此在循环之前写这些。

	data_to_save.float_data[0] = float_variable1;
	data_to_save.float_data[1] = float_variable2;
	data_to_save.float_data[2] = float_variable3;
	data_to_save.float_data[3] = float_variable4;

	data_to_save.int_data[0] = int_variable1;
	data_to_save.int_data[1] = int_variable2;
	data_to_save.int_data[2] = int_variable3;
	data_to_save.int_data[3] = int_variable4;	

//	my_flash_write();//写入的时候就可以把这个注释取消。
	my_flash_read();//读取的时候就可以把这个注释取消。

由于在.h文件的函数my_flash_read()中有fff这个全局变量,所以当你写入以后,断电,再重新烧录读取的那个代码就可以在调试窗口中看到那个全局变量的值是你存进去的值!!!!!


总结

本文讲述了STM32CubeMX-ADC Hal库 内部Flash掉电存储
也说明了如何存储和读取不同类型数据,希望对你有所帮助。

HAL库(Hardware Abstraction Layer,硬件抽象层)是STM32CubeMX的一部分,它提供了一种标准化的方式来访问STM32微控制器的各种功能,包括读写内部。在STM32F4系列中,内部Flash通常用于存储程序代码、配置数据等。 以下是使用STM32CubeMXHAL库通过代码来操作内部Flash的基本步骤: 1. **初始化**: 首先,在你的C代码中,需要包含相关的HAL库头文件,并初始化HAL库,例如 `stm32f4xx_hal_flash.h` 和 `stm32f4xx_hal_flash_ex.h`。 ```c #include "stm32f4xx_hal_flash.h" ... HAL_Init(); FLASH年由HAL_FLASH_Init()函数初始化; ``` 2. **选择Flash分区**: STM32F4有多种Flash分区,如Program Flash、Option Bytes等。你需要明确你要操作的是哪一块分区,比如使用`FLASH分区管理结构体`,如`FLASH分区结构体` (FLASH分区结构体)。 ```c FLASH分区_t flash分区; flash分区.Address = FLASH_REGION_1; // 设置分区地址 ``` 3. **擦除**: 使用`HAL_FLASH erased_ranges`函数选择要擦除的范围并执行擦除操作。 ```c FLASH_EraseOptionsTypeDef erase_options; erase_options.TypeOfOperation = FLASH_TYPEERASE; erase_options.EraseAllPages = ENABLE; HAL_FLASHEx_Erase(&flash分区, &erase_options); ``` 4. **编程**: 使用`HAL_FLASH_Program`函数将数据写入Flash。 ```c uint8_t data[] = {0x01, 0x02, 0x03}; // 数据字节数组 HAL_FLASH_Program(FLASH_WRITE, flash分区.Address, 0, sizeof(data), data); ``` 5. **等待操作完成**: 对于一些长时间的操作(如擦除),可能会有延时或确认请求,可以使用`HAL_Delay`等待或检查操作状态。 6. **处理异常**:记得捕获和处理可能出现的错误,比如`HAL_StatusTypeDef status = HAL_FLASHEx_WaitForLastOperationUntilEnd()`。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>