掉电瞬间数据会丢?别只怪 Flash,看看写操作与时序
2026/6/16 2:00:03 网站建设 项目流程

摘要:系统在正常运行时数据存储正常,但突然断电重启后,发现 Flash 里的参数变成了 0xFF 或乱码?不是 Flash 寿命到了,而是掉电瞬间写操作未完成​ 或擦除-写入时序被破坏。本文解析 Flash 存储的“原子性”陷阱。


一、问题描述(现象)

**设备运行正常,参数保存在 Flash 中;

模拟突然断电(拔掉电源),再次上电;

读取参数,发现校验失败,数据全变成 0xFF 或 0x00。**

很多工程师的排查方向是:

  1. Flash 擦写次数到了?

  2. 写入函数没执行完?

  3. 校验算法错了?


二、原理分析

1. 物理模型

Flash 的写入不是瞬间的,而是一个高压隧穿的过程。

擦除 (Erase) -> 写入 (Program) -> 校验 (Verify)

2. 核心参数

  • Tprog(编程时间):写一个字(Word)所需的时间(通常 10~100µs)。

  • Vpp(编程电压):Flash 内部泵升的电压(依赖 VDD)。

  • Write Buffer:Flash 接口的写缓冲区。

3. 反直觉真相

“写入函数返回 Success,并不代表数据已经落地。”

  • Flash 控制器通常有缓存。

  • 如果在HAL_FLASH_Program()返回后、但缓存还没刷入物理单元时断电:

    • 数据丢失。

  • 如果掉电发生在擦除完成后、写入开始前

    • 扇区是空的(0xFF),数据丢失。


三、工程级解决方案

方案 1:双备份 + 标志位(黄金法则)

永远不要在原地覆盖数据。

存储结构:

Sector A: [Valid Flag] [Data] Sector B: [Valid Flag] [Data]

流程:

  1. 写 Sector B(新数据)。

  2. 校验 Sector B。

  3. 擦除 Sector A。

  4. 设置 Sector B 的 Valid Flag。

结果:​ 任何时候断电,至少有一份数据是完整的。

方案 2:掉电检测(BOR)中断

利用 MCU 的掉电中断(BOR IT)​ 或PVD(可编程电压检测器)

void PVD_IRQHandler(void) { // 1. 立刻关闭不必要的外设(减少电流消耗) // 2. 停止 Flash 写操作 // 3. 点亮 LED 报警 // 4. 等待电容放电(维持 10ms 以上) }

关键点:​ 必须在 VDD 跌落到 Flash 最低工作电压(如 2.7V)之前,停止所有写操作。

方案 3:大电容蓄能

在电源输入端增加大容量储能电容。

Vbat -> [LDO] -> [100uF 电解] -> [10uF MLCC] -> MCU

计算:

  • 假设 MCU 运行电流 50mA,最低工作电压 3.0V。

  • 需要在 3.3V -> 3.0V 跌落期间,维持 50ms。

  • C=ΔVI×Δt​=0.30.05×0.05​≈8330μF。


四、选型避坑建议

  1. 不要在中断里写 Flash

    • 写 Flash 时间长,会阻塞系统。

  2. 写操作期间不要关中断

    • Flash 控制器可能需要中断来同步状态。

  3. ECC(纠错码)

    • 高端 MCU 支持 Flash ECC,能纠正 1bit 错误,但无法防止掉电。


五、总结 Checklist

  • [ ] 是否采用了“双备份 + 标志位”的存储结构?

  • [ ] 是否利用了 BOR/PVD 中断在掉电前停止写操作?

  • [ ] 电源输入端是否有足够的储能电容(> 1000µF)?

  • [ ] 写入数据后,是否进行了回读校验?


六、写在最后(关注我,少走弯路)

我是 gqqsherry,一个拒绝调包、专注底层逻辑的嵌入式工程师。

数据的持久化是“最后的一公里”,如果这一步没走好,前面的功能再完美也是零。

关注我的专栏《嵌入式底层避坑指南》,《复位与启动》系列到此正式完结。

👉专栏总索引预告:《嵌入式底层避坑指南 · 全系列导航》


原创文章,转载请注明出处。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询