你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F1x系列——Flash 模拟 EEPROM

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:02
STM32F10x芯片本身没有集成EEPROM,替代方案是用片上Flash来模拟EEPROM。Flash与EEPROM的区别主要是:一、EEPROM可以按位擦写,而Flash只能按块(页)擦除;二、Flash的擦除寿命约1 万次,较EEPROM低一个量级。ST网站有个Flash模拟EEPROM的范例:AN2594: EEPROM emulation in STM32F10x microcontrollers(包括源码和文档)。范例在保存修改的数据时,以写入新数据来替代对原数据的修改,并使用两个页面轮流写入,单页写满后进行数据迁移,再一次性擦除旧页面。这个策略可以有效降低Flash擦除次数。9 d! b5 N+ B) _- S

) _/ e: v- ^5 G6 a* ~" g$ t  不过,范例代码只能保存固定大小的数据(16bits),虽然容易改成不同的固定大小,但实际用起来还是很不方便。我改写了一下,新的特性包括:
8 s! Z/ J% t1 t# k  t
) O  U2 d! E1 D支持不同大小数据(字符数组、结构体等)的混合存储;
/ n4 M9 u; ~( j1 Y! L* M6 Q2 C增加对数据的校验和(Checksum)检查。- ]0 p4 N; Y0 v7 Z* F
  附件提供了源码。使用方法很简单,比如要保存一个字符数组 title 和一个 point 结构体:2 F% u, f1 g8 F- W$ _0 Z
  1. #include "eeprom.h"
    6 n" k  u- h1 j# \
  2. 3 m/ l$ Y7 v6 a9 r: a0 R5 U5 Y( i
  3. #define TITLE_SIZE    80, k! h& i. a$ X* n3 T
  4. #define TITLE_KEY     1. P- m' X: V- k8 {9 n7 P
  5. #define POINT_KEY     2
    $ r3 ~7 r6 d( f& R) }* s
  6. 5 p+ h3 g, I: ]) w$ H! a; T. n+ X0 m
  7. typedef struct {
    - y5 f1 ?0 H- z* C, R% u7 X
  8.     float x;9 L1 s5 X  l4 t! c! U
  9.     float y;
    7 D5 M* t3 g  h, g8 _- i3 m
  10.     float z;
    % j" T* w( T& n* b
  11. } Point;
    ; K( [! c/ c6 z/ z8 V- M. Y
  12. ( g1 S# n0 Z0 ]; r* d  ?  p7 B& ^7 o
  13. char title[TITLE_SIZE] = "eeprom test string.";
    ) l) |0 e  f/ k
  14. Point point;
复制代码
$ a, O5 ]4 e- R3 f, y0 ?# i
执行必要的初始化操作后,就可以进行写入和读取:
3 n" s) H+ N. Z. l2 G% ^' G
  1. uint16_t result = 0;
    0 H0 T  E2 C8 N7 q  e5 K/ r

  2. % p1 J5 i0 P5 X% j5 f' R
  3. FLASH_Unlock();% r, w  N9 V; ]  \; P* M

  4. : {5 D3 ^) D, v' u' K* T0 L
  5. EE_Init();
    0 u) y6 C- m4 R4 n: r: C9 g" ?

  6. 9 B1 P# \3 G& E2 R9 z5 a
  7. result = memcpy_to_eeprom_with_checksum(TITLE_KEY, title, TITLE_SIZE);
    1 z  s: }& }1 l5 V
  8. result = memcpy_to_eeprom_with_checksum(POINT_KEY, &point, sizeof(point));
    . n1 G+ m2 ?4 C+ Y
  9. ' w/ S8 o! ?+ u% X3 b! ]
  10. result = memcpy_from_eeprom_with_checksum(title, TITLE_KEY, TITLE_SIZE);
    9 U. N: e$ f) ?
  11. result = memcpy_from_eeprom_with_checksum(&point, POINT_KEY, sizeof(point));
复制代码

) n! w- `8 q" p7 _实现混合存储的办法,是给每个变量附加8字节的控制信息。因此,在存储小数据时会有较大的空间损耗,而在存储较大的数据结构时空间利用率更高(相对于范例)。代码是针对STM32F103VE的实现。不同芯片需要对应修改头文件中 EEPROM_START_ADDRESS 的定义:
: ?: e/ X0 N1 U' H
  1. #define EEPROM_START_ADDRESS    ((uint32_t)0x0807F000)
复制代码

* k1 C& [5 t6 a  I" K% D/ q
" ?8 H" \* \9 x* ^& m: S& m* }% J. t* U) p' w* p$ D
收藏 评论0 发布时间:2021-11-29 22:02

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版