FLASH代码部分

FLASH

一. 核心参数定义

C 复制代码
#define STORE_START_ADDRESS		0x0800FC00		// FLASH存储起始地址(需对应FLASH页地址)
#define STORE_COUNT		512			// 存储数据的个数(半字,1个半字=2字节)
uint16_t Store_Data[STORE_COUNT];				// SRAM缓存数组(掉电丢失,需同步到FLASH实现掉电保存)
关键参数说明
  • 存储地址:0x0800FC00 为STM32F10x FLASH的某一页起始地址(需根据芯片FLASH容量调整,确保地址对齐),用于存储标志位和参数数据。

  • 存储个数:STORE_COUNT = 512,表示可存储512个半字(uint16_t)数据,总存储容量 = 512 × 2 = 1024字节(1KB)。

  • SRAM数组:Store_Data 作为缓存,程序运行时操作该数组,通过 Store_Save() 同步到FLASH,实现掉电不丢失。

FLASH操作核心规则
  1. STM32F10x 内部FLASH 最小操作单位为 半字(2字节),故读写均以半字为单位。

  2. FLASH 编程前必须先 擦除对应页(不能直接覆盖写入),擦除后所有位均为1(0xFFFF)。

  3. 地址计算:第i个数据(半字)的FLASH地址 = 起始地址 + i × 2(因每个半字占2字节)。


二. 初始化(FLASH参数存储模块)

初始化函数
C 复制代码
/**
  * 函    数:参数存储模块初始化
  * 参    数:无
  * 返 回 值:无
  * 核心功能:判断是否第一次使用,初始化FLASH并加载数据到SRAM
  */
void Store_Init(void)
{
	/*判断是不是第一次使用(通过FLASH标志位判断)*/
	if (MyFLASH_ReadHalfWord(STORE_START_ADDRESS) != 0xA5A5)	//读取起始地址的标志位,不相等则为第一次使用
	{
		MyFLASH_ErasePage(STORE_START_ADDRESS);					//擦除存储起始地址所在的FLASH页
		MyFLASH_ProgramHalfWord(STORE_START_ADDRESS, 0xA5A5);	//在起始地址写入标志位0xA5A5,标记已初始化
		for (uint16_t i = 1; i < STORE_COUNT; i ++)				//循环初始化所有有效数据(跳过标志位)
		{
			MyFLASH_ProgramHalfWord(STORE_START_ADDRESS + i * 2, 0x0000);		//有效数据全部清0
		}
	}

	/*上电加载:将FLASH中存储的数据加载回SRAM数组,实现掉电不丢失*/
	for (uint16_t i = 0; i < STORE_COUNT; i ++)					//循环读取所有数据(包含标志位)
	{
		Store_Data[i] = MyFLASH_ReadHalfWord(STORE_START_ADDRESS + i * 2);		//FLASH数据→SRAM数组
	}
}
初始化关键流程
  1. 标志位判断:通过读取FLASH起始地址的半字数据,与自定义标志位 0xA5A5 对比,判断是否为第一次使用。

  2. 第一次初始化:擦除对应FLASH页 → 写入标志位 → 初始化所有有效数据为0x0000,完成FLASH初始化。

  3. 上电加载:无论是否为第一次使用,均将FLASH中存储的所有数据(包含标志位)加载到SRAM数组,确保程序运行时操作的是最新数据。


三. 核心函数用法

  1. Store_Init(参数存储模块初始化) void Store_Init(void);

    • 核心作用:初始化FLASH(第一次使用时),并将FLASH中的数据加载到SRAM数组 Store_Data,为后续参数读写做准备。

    • 使用时机:程序上电后,其他模块初始化完成后调用(如OLED、按键初始化后)。

  2. Store_Save(数据保存到FLASH)

  • 函 数:参数存储模块保存数据到闪存

  • 参 数:无

  • 返 回 值:无

  • 核心功能:将SRAM数组数据同步到FLASH,实现掉电保存

    _/

    void Store_Save(void)

    {

    MyFLASH_ErasePage(STORE_START_ADDRESS); //先擦除对应FLASH页(必须擦除后才能编程)

    for (uint16_t i = 0; i < STORE_COUNT; i ++) //循环写入所有数据(包含标志位)

    {

    MyFLASH_ProgramHalfWord(STORE_START_ADDRESS + i _ 2, Store_Data[i]); //SRAM数组→FLASH

    }

    }`

    复制代码
    - 核心作用:将SRAM数组 `Store_Data` 中的所有数据(包含标志位),同步写入到内部FLASH,确保掉电后数据不丢失。
    
    - 核心流程:擦除FLASH页 → 逐一半字写入数据(因FLASH不能直接覆盖,需先擦除)。
    
    - 使用时机:当 `Store_Data` 数组中的参数修改后,需调用此函数保存(如参数设置完成后)。
  1. Store_Clear(有效数据清0)
  • 函 数:参数存储模块将所有有效数据清0

  • 参 数:无

  • 返 回 值:无

  • 核心功能:清0 SRAM数组有效数据,并同步到FLASH

    */

    void Store_Clear(void)

    {

    for (uint16_t i = 1; i < STORE_COUNT; i ++) //循环清0(跳过第一个标志位,保留标志位)

    {

    Store_Data[i] = 0x0000; //SRAM数组有效数据清0

    }

    Store_Save(); //调用保存函数,将清0后的数据同步到FLASH

    }`

    复制代码
    - 核心作用:将SRAM数组中除标志位(第一个数据)外的所有有效数据清0,并同步到FLASH,实现参数重置。
    
    - 注意:不清除标志位 `0xA5A5`,避免下次上电被判定为"第一次使用",重新初始化。

四. MyFLASH函数

c 复制代码
#include "stm32f10x.h"                  // Device header

/**
  * 函    数:FLASH读取一个32位的字
  * 参    数:Address 要读取数据的字地址
  * 返 回 值:指定地址下的数据
  */
uint32_t MyFLASH_ReadWord(uint32_t Address)
{
	return *((__IO uint32_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

/**
  * 函    数:FLASH读取一个16位的半字
  * 参    数:Address 要读取数据的半字地址
  * 返 回 值:指定地址下的数据
  */
uint16_t MyFLASH_ReadHalfWord(uint32_t Address)
{
	return *((__IO uint16_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

/**
  * 函    数:FLASH读取一个8位的字节
  * 参    数:Address 要读取数据的字节地址
  * 返 回 值:指定地址下的数据
  */
uint8_t MyFLASH_ReadByte(uint32_t Address)
{
	return *((__IO uint8_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

/**
  * 函    数:FLASH全擦除
  * 参    数:无
  * 返 回 值:无
  * 说    明:调用此函数后,FLASH的所有页都会被擦除,包括程序文件本身,擦除后,程序将不复存在
  */
void MyFLASH_EraseAllPages(void)
{
	FLASH_Unlock();					//解锁
	FLASH_EraseAllPages();			//全擦除
	FLASH_Lock();					//加锁
}

/**
  * 函    数:FLASH页擦除
  * 参    数:PageAddress 要擦除页的页地址
  * 返 回 值:无
  */
void MyFLASH_ErasePage(uint32_t PageAddress)
{
	FLASH_Unlock();					//解锁
	FLASH_ErasePage(PageAddress);	//页擦除
	FLASH_Lock();					//加锁
}

/**
  * 函    数:FLASH编程字
  * 参    数:Address 要写入数据的字地址
  * 参    数:Data 要写入的32位数据
  * 返 回 值:无
  */
void MyFLASH_ProgramWord(uint32_t Address, uint32_t Data)
{
	FLASH_Unlock();							//解锁
	FLASH_ProgramWord(Address, Data);		//编程字
	FLASH_Lock();							//加锁
}

/**
  * 函    数:FLASH编程半字
  * 参    数:Address 要写入数据的半字地址
  * 参    数:Data 要写入的16位数据
  * 返 回 值:无
  */
void MyFLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{
	FLASH_Unlock();							//解锁
	FLASH_ProgramHalfWord(Address, Data);	//编程半字
	FLASH_Lock();							//加锁
}
相关推荐
java1234_小锋2 小时前
Spring AI 2.0 vs LangChain4j,怎么选?
spring·springai·langchain4j
逍遥德2 小时前
skill模板-基于java maven项目
java·人工智能·自然语言处理·maven
XiYang-DING2 小时前
【Java EE】单例模式
java·单例模式·java-ee
Rust研习社2 小时前
添加依赖库时的 features 是什么?优雅实现编译期条件编译与模块化开发
开发语言·后端·rust
志飞2 小时前
springboot配置可持久化本地缓存ehcache
java·spring boot·缓存·ehcache·ehcache持久化
itzixiao2 小时前
L1-051 打折(5分)[java][python]
java·python·算法
马艳泽3 小时前
接到新需求后快速产出可执行的方案和时间估算
后端
それども3 小时前
Spring Bean 注入的优先级顺序
java·数据库·sql·spring
ID_180079054733 小时前
Python 实现京东商品详情 API 数据准确性校验(极简可直接用)
java·前端·python