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

【经验分享】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擦除次数。
" G9 D( f2 d9 m; x
0 ^) \* e2 N& W  {% `  不过,范例代码只能保存固定大小的数据(16bits),虽然容易改成不同的固定大小,但实际用起来还是很不方便。我改写了一下,新的特性包括:
+ B" T: t6 t0 ?2 b, ~& H2 T: P
2 e9 @9 s/ v3 B+ @+ N) k( V- \支持不同大小数据(字符数组、结构体等)的混合存储;. P, P) ]" v- j* s0 Y
增加对数据的校验和(Checksum)检查。2 n$ u: w/ }" |, Z1 d3 {; B
  附件提供了源码。使用方法很简单,比如要保存一个字符数组 title 和一个 point 结构体:! |, v2 p4 `. n2 W' `
  1. #include "eeprom.h"+ M$ t2 S# J, f5 o" v" W
  2. $ o0 Q8 V: h0 g0 f* @4 j# ^
  3. #define TITLE_SIZE    80
    5 r; A( d4 h# c4 d1 H
  4. #define TITLE_KEY     15 q% y1 X% I  z  \  u' d
  5. #define POINT_KEY     2, [/ ~5 v2 A! H0 s2 f# W3 N' c$ ~
  6. - C8 G0 X6 n, i! G1 g$ Y
  7. typedef struct {
    % I9 O  f+ U: t
  8.     float x;
    # [& v! o) q( w8 Y5 b
  9.     float y;
    " B) a# R: r, f
  10.     float z;
    " T/ y' V) l, g' Y# B; j) {: k3 O+ X
  11. } Point;% M  g8 U5 i" `# r3 h" N; w
  12. ' P$ P+ v$ v/ V7 i6 `1 M( D2 X
  13. char title[TITLE_SIZE] = "eeprom test string.";
    4 o% y8 f- @7 J1 J0 N! a
  14. Point point;
复制代码

' t4 D+ {3 h6 v0 f  |执行必要的初始化操作后,就可以进行写入和读取:
) ?, A+ \/ Y  V7 Y9 |# t
  1. uint16_t result = 0;
    / E6 ~. ~* \* E

  2. + s6 ~( ?8 h, P3 t9 ?; a* J' K
  3. FLASH_Unlock();
    + j0 @  }, T/ A1 t1 Y. P4 ]
  4. : U! E4 o6 Q, N0 w5 n; X
  5. EE_Init();
    ! F5 ^: C- O! [! Z" W  A& v/ d* r
  6. ' ]/ x% ~% [4 f# n5 p6 V# o
  7. result = memcpy_to_eeprom_with_checksum(TITLE_KEY, title, TITLE_SIZE);, ?, _, b: @8 P2 k$ T
  8. result = memcpy_to_eeprom_with_checksum(POINT_KEY, &point, sizeof(point));# }" d8 O5 ?( B$ o4 q/ Q4 C; l

  9. ! w% q1 a7 Z/ O3 n9 O: D; {
  10. result = memcpy_from_eeprom_with_checksum(title, TITLE_KEY, TITLE_SIZE);: j% ^/ `% T9 c  T; B
  11. result = memcpy_from_eeprom_with_checksum(&point, POINT_KEY, sizeof(point));
复制代码

/ {/ F8 Q& c4 a+ D' X% @实现混合存储的办法,是给每个变量附加8字节的控制信息。因此,在存储小数据时会有较大的空间损耗,而在存储较大的数据结构时空间利用率更高(相对于范例)。代码是针对STM32F103VE的实现。不同芯片需要对应修改头文件中 EEPROM_START_ADDRESS 的定义:
" h$ d# Z) I. D7 A/ M- }8 F) R
  1. #define EEPROM_START_ADDRESS    ((uint32_t)0x0807F000)
复制代码
0 I1 w4 d  E; X) j2 F. w

, R; B% B, @. e, ], [& L' U0 x7 A) z
收藏 评论0 发布时间:2021-11-29 22:02

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版