STM32F103 内部片上flash读写操作实现掉电保存数据(附代码)
创作时间:
作者:
@小白创作中心
STM32F103 内部片上flash读写操作实现掉电保存数据(附代码)
引用
CSDN
1.
https://m.blog.csdn.net/DongJayYet/article/details/138610783
在许多嵌入式项目中,需要实现参数的掉电保存功能,即在设备重启后能够自动恢复之前设置的参数。对于数据量较小的情况,可以利用微控制器内部的Flash存储器来实现这一功能。本文将以STM32F103芯片为例,详细介绍如何通过编程实现内部Flash的读写操作,从而实现参数的掉电保存。
一、准备工作
在开始编写代码之前,需要对STM32F103芯片的内部Flash有基本的了解,包括其大小、地址范围等信息。这些信息可以在芯片的数据手册中找到。以STM32F103C8为例,其内部Flash的大小为64KB,每一页的大小为1KB。
为了确认可用的Flash空间,可以使用STM32Cube IDE的Build Analyzer工具进行查看。如下图所示,可以看到还有10几KB的Flash空间可以使用。
二、代码设计
A. 读操作
读取Flash中的数据需要使用以下函数:
uint32_t flash_read(uint32_t address, uint8_t* pdata, uint32_t size)
{
uint32_t read_index = 0;
uint8_t value;
uint32_t start_addr;
uint32_t end_addr;
if (!pdata || size < 1)
{
return 0; // FLASH_PARAM_ERROR;
}
start_addr = address;
end_addr = start_addr + size;
if (start_addr < FLASH_USER_START_ADDR || end_addr > FLASH_USER_END_ADDR)
{
return 0; // FLASH_ADDR_ERROR;
}
read_index = 0;
while (read_index < size)
{
value = *(__IO uint8_t*)start_addr;
start_addr = start_addr + 1;
*(pdata + read_index) = value;
read_index++;
}
return read_index;
}
B. 擦除操作
在写入数据之前,需要先对目标区域进行擦除。擦除操作使用以下函数:
FLASH_ERROR_CODE_E flash_erase(uint32_t start_addr, uint32_t end_addr)
{
static FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError = 0;
if ((start_addr > end_addr) || (start_addr < FLASH_USER_START_ADDR) || (end_addr > FLASH_USER_END_ADDR))
{
return FLASH_ADDR_ERROR;
}
/* Unlock the Flash to enable the flash control register access */
HAL_FLASH_Unlock();
/* Fill EraseInit structure */
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = start_addr;
EraseInitStruct.NbPages = (end_addr - start_addr + (FLASH_PAGE_SIZE - 1)) / FLASH_PAGE_SIZE;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
{
HAL_FLASH_Lock();
return FLASH_ERASE_ERROR;
}
/* Lock the Flash to disable the flash control register access */
HAL_FLASH_Lock();
return FLASH_SUCCESS;
}
C. 写操作
写入数据到Flash中使用以下函数:
FLASH_ERROR_CODE_E flash_write(uint32_t address, const uint8_t* pdata, uint32_t size)
{
HAL_StatusTypeDef result = HAL_ERROR;
uint32_t end_addr = 0;
uint32_t start_addr;
uint32_t word_num;
uint8_t half_word_num;
uint8_t byte_num;
uint32_t write_index = 0;
if ((!pdata) || (size < 1))
{
return FLASH_PARAM_ERROR;
}
word_num = (size >> 2); // size/4
half_word_num = (size % 4) >> 1; // (size%4)>>1
byte_num = (size % 2); // size % 2
start_addr = address;
end_addr = (start_addr + size);
if (start_addr < FLASH_USER_START_ADDR || end_addr > FLASH_USER_END_ADDR)
{
return FLASH_ADDR_ERROR;
}
/* Unlock the Flash to enable the flash control register access */
HAL_FLASH_Unlock();
write_index = 0;
while (write_index < word_num)
{
result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, start_addr, BUILD_UINT32(*(pdata), *(pdata + 1), *(pdata + 2), *(pdata + 3)));
if (HAL_OK == result)
{
start_addr = start_addr + 4;
pdata = pdata + 4;
write_index++;
}
else
{
return FLASH_WRITE_WORD_ERROR;
}
}
write_index = 0;
while (write_index < half_word_num)
{
result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, start_addr, BUILD_UINT16(*(pdata), *(pdata + 1)));
if (HAL_OK == result)
{
start_addr = start_addr + 2;
pdata = pdata + 2;
write_index++;
}
else
{
return FLASH_WRITE_HALF_WORD_ERROR;
}
}
write_index = 0;
while (write_index < byte_num)
{
result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, start_addr, BUILD_UINT16(*(pdata), 0xFFFF));
if (HAL_OK == result)
{
start_addr = start_addr + 2;
pdata = pdata + 2;
write_index++;
}
else
{
return FLASH_WRITE_BYTE_ERROR;
}
}
/* Lock the Flash to disable the flash control register access */
HAL_FLASH_Lock();
return FLASH_SUCCESS;
}
以上代码参考:stm32f0_flash/STM32/STM32F0/STM32F0_CUBE_FLASH at master · GreatWall51/stm32f0_flash · GitHub
三、结果验证
可以在STM32CubeIDE的debug模式下,通过memory窗口输入地址来查看写入的数据是否正确。
四、注意事项
- 写Flash时,需注意先要擦除;
- 地址要输入正确;
热门推荐
两岸饺子文化差异:从馅料到蘸料的饮食密码
微信二维码有效期多长
怎么分辨贷款中介是否正规?这几点要注意
换热机组厂家详解:换热面积计算方法与步骤
一直咳咳咳,警惕是肺结核!张文宏最新发声
鸳鸯:忠贞的爱情伴侣
美国枪支合法化的历史渊源与现代社会影响
湖南新宁:增殖放流鱼苗护一江碧水
曼谷住宿19泰铢一晚的“贫民窟”老屋,比五星酒店还抢手!
儿童营养补充:钙铁锌口服液的选择
【图朴解决方案】老旧燃气管道改造施工方法综合分析
仓库管理项目选址指南:八大关键因素全面解析
胶原蛋白面膜有用吗?抗老与修护的护肤利器
短视频时间太长?这些实用压缩方法帮你轻松应对
星露谷物语莱纳斯的位置在哪
如何区分A货、B货、B+C货、D货翡翠?看看你买的是什么类型的翡翠
治疗膝关节疼痛的中药方剂
岱宗夫如何,齐鲁青未了——探寻泰山文化的博大精深
兵马俑参观时间需求详解
Windows系统截图工具使用指南:从基础到进阶功能详解
如何做到网络安全审计
揭秘尼安德特人:为何20万年未能进化出文明?
曝欧洲联赛球探扎堆考察国青球员 新星闪耀引关注
国内首个面向青少年健康促进的指标体系! 《儿童青少年运动成长健康指数》创新发布
《猫猫的奇幻漂流》:纵使世界破破烂烂 总有生命缝缝补补
老年人用安眠药,“安全”吗?
认知偏见:理解的障碍与突破之道
人物、情节、背景:构建引人入胜的故事
路漫漫其修远兮,徐弭节而高厉。
紫微斗数命宫官符:影响与特质解析