赞
踩
本文将介绍STM32F1的内部FLASH,通过内部FLASH实现数据读写操作。从而做到掉电存储。不同型号的STM32,其FLASH:容量也有所不同,最小的只有 16K字节,最大的则达到了1024K字节。此处我们使用的是 STM32F103ZET6,其FLASH容量为512K字节,属于大容量产品,大容量产品的闪存模块组织图如下图示
别的博主的文章大多都是用键盘来验证是否存储完成,但是我感觉我又不是每次都要用按键存储,且存储的东西都很单一,我这篇里面会提到如何存储各种数据。
//源文件: 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不需要进行额外的配置。
首先给出整体代码随后会对每一部分进行一定的分析
#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函数
当你需要读取的时候直接调用就可以
这里注意定义了一个结构体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掉电存储
也说明了如何存储和读取不同类型数据,希望对你有所帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。