[APM32F1]

用APM32F103内部flash模拟eeprom

[复制链接]
1809|12
手机看帖
扫描二维码
随时随地手机跟帖
hexbei|  楼主 | 2023-11-10 17:46 | 显示全部楼层 |阅读模式
本帖最后由 hexbei 于 2023-11-13 17:31 编辑

背景
一些项目中,有数据存储的需求,且读写较为频繁,每次读写数据量不大(几个或几十个字节),这种情况使用EEPROM是比较方便的选择。但如果不**在硬件上多挂一个外置eeprom的时候,也可以用单片机内部flash模拟eeprom来使用。

原理
下面以极海APM32F103为例,简单介绍如何实现模拟eeprom驱动。
APM32F103的内部flash,读取和写入可以按半字为单位操作。但在写入之前,需要先进行擦除。擦除的单位是一个页大小,为1024字节。
因此,简单的擦除和写入不能模拟eeprom的随机读写功能,需要额外的驱动算法来实现。

存储结构
我们使用内部flash的两个页轮流擦写的方式,实现数据的随机读写。
1. 每个页的前4个字节用来存储该页状态标志位,有三种:已擦除、待传输、有效。
2. 同一时刻,两个页中只有一个是处于“有效”的状态,数据读写都发生在该页中。
3. 页内以4个字节为单位划分存储单元。每个单元前两个字节是虚拟地址,后两个字节为实际存储数据。
4. 第一次上电初始化时,先擦除两个页,并设置第一页为“有效”。
5. 当其中一页写满时,另一页状态设置为“待传输”,并把数据从有效页复制到待传输页。复制完毕,设置待传输页为有效页,原有效页进行擦除并设置为“已擦除”。
6. 后续上电初始化,检查两个页的标志位,如果不满足上述第2点的条件,进行第4点中的操作。如果一个是有效页另一个是待传输页,进行第5点中的操作。

写入
内部flash页擦除后,页内每个地址的数据只能单次写入。为了实现eeprom的随机写入,我们采取虚拟地址+数据的结构,按物理地址顺序存储每一次的写入操作,并以最新操作为准。类似日志文件系统。
1. 每次以2字节虚拟地址+2字节数据为单位写入数据。
2. 为了区分有效数据和无效数据,4字节数据不能全为0xFF。因此规定虚拟地址不能为0xFFFF。
3. 所有数据按物理地址递增的顺序写入,地址增量为4个字节。
4. 写入前需要搜索当前页下一个可写入物理地址,也就是找到第一个无效数据(0xFFFFFFFF)的物理地址。
5. 当前页满了之后,按上一节中的操作处理。

读取
内部flash本身可以实现随机读取,但在我们模拟eeprom驱动的存储结构之下,略有不同。
读取的时候,按物理地址顺序搜索所有有效数据,直到找到与需读取虚拟地址匹配的存储单元,即可读出该存储单元的2字节数据。

工程文件
在极海sdk的基础上,实现eeprom.c/.h文件即可。

接口 1.png

注意
* 虚拟地址与实际flash地址不对应
* 虚拟地址范围是0~0xFFFE
* 虚拟地址可以任意指定,与实际存储顺序不对应
* 每个虚拟地址存放16位的数据
* 写入和读取都按16位数据为单位操作

地址分配
* 修改  EE_BASE_ADDRESS  指定eeprom数据在flash中的起始地址
* 结束地址为  EE_BASE_ADDRESS + EE_PAGE_SIZE * 2
* 最多可以存放  EE_PARA_MAX_NUMBER  个16位数据
* 如果空间不够,可以修改  EE_SECTOR_NUM 使用更多的扇区

使用特权

评论回复
weifeng90| | 2023-11-11 10:28 | 显示全部楼层
如果数据量本身不大,直接读写FLASH就是了。

使用特权

评论回复
lix1yr| | 2023-11-15 12:41 | 显示全部楼层
记得很多内部flash都是按页擦除和写入的吧

使用特权

评论回复
cen9ce| | 2023-11-15 13:48 | 显示全部楼层
其实,如果非必要,没必要去弄内部的存储

使用特权

评论回复
y1n9an| | 2023-11-15 14:51 | 显示全部楼层
这种存储你要计算好单片机程序的大小之后,才能去做其他应用的

使用特权

评论回复
tax2r6c| | 2023-11-15 15:54 | 显示全部楼层
用内部存储挺好的,还挺省钱

使用特权

评论回复
b5z1giu| | 2023-11-15 17:06 | 显示全部楼层
这种操作是不是很容易出现问题啊?

使用特权

评论回复
g0d5xs| | 2023-11-15 18:15 | 显示全部楼层
我还是建议使用单独的flash来做存储就好了,能好点

使用特权

评论回复
w2nme1ai7| | 2023-11-16 09:02 | 显示全部楼层
能随机写入吗?是不是也得先解锁,按页操作,之后再写入啊

使用特权

评论回复
su1yirg| | 2023-11-16 10:13 | 显示全部楼层
原来这个能按照半字为单位读写啊?那挺好

使用特权

评论回复
kaif2n9j| | 2023-11-16 11:44 | 显示全部楼层
觉得不太行,至少没有像铁电的方面方便

使用特权

评论回复
lamanius| | 2023-11-16 13:56 | 显示全部楼层
内部存储都是按照页擦除,比较难弄

使用特权

评论回复
逍遥怡天| | 2023-12-12 13:01 | 显示全部楼层
数据量少还是很方便的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

21

帖子

2

粉丝