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时,需注意先要擦除;
- 地址要输入正确;
热门推荐
如何选择创业的团队成员
如何安全地注销金融账户?这种注销过程有什么注意事项?
Nature重磅 | “心死”还能复生?抑制脂肪酸氧化可实现心脏再生!
数据管理能力成熟度评估对企业战略规划有何影响?
新经济与法|数据资产值不值钱,需要数据合规管理来“校准”
长颈鹿脖子的用处有哪些?想不到吧!长颈鹿脖子竟然有这么多用处!
科学小知识:长颈鹿
《存在与时间》30句经典名言,句句精髓
骨骼肌是什么
网络安全如何构建
四步把握G类书信语气(下)
蘑菇和鸡蛋可以一起吃吗
产品经理如何指定app转化目标
科技成果转化如何提供证明材料?
Valorant错误代码135怎么回事 有效解决方法来了
小学生练字指南:11个实用技巧助你写出一手好字
“倒反天罡!”这个梗真的代表很严重的事吗?
红旗H5选黑色还是量子银灰好?
茶道与禅宗:一种独特的文化现象
惠明禅师与惠明茶
“风评被害”的奶龙,做错了什么?
了解 18650 电池电压:从基础到高级
动车组司机的这个操作和你有关,你知道吗?
情感秘籍 | 高情商的人如何回应别人的辱骂?
今年诺奖获得者曾经“Gap了一年”,这是个什么梗?
公积金提取规则全面解析
丽江必去的9个景点,全部去过才能说真正去过丽江,你去过几个?
Netdiscover工具的详细教程
如何培养团队优秀品质
科学小知识:长颈鹿