当前位置: 首页 > news >正文

深入解析STM32F103 Flash扇区重复擦除失败及FLASH_ERROR_PG错误的解决方案

1. 为什么STM32F103的Flash扇区会擦除失败?

最近在做一个嵌入式项目时,遇到了一个让人头疼的问题:STM32F103芯片的Flash扇区在第一次擦除后,再次尝试擦除就会报FLASH_ERROR_PG错误。这个问题困扰了我好几天,直到发现了一个关键点——标志位没有及时清除。

Flash存储器就像一个小本子,每次擦除就相当于把整页纸擦干净。但在STM32中,这个"擦除"操作会留下一些"痕迹",也就是状态标志位。如果不及时清理这些标志位,下次再想擦除时,芯片就会认为上次操作还没完成或者出错了,于是拒绝执行新的擦除命令。

具体来说,当出现FLASH_ERROR_PG错误时,通常意味着:

  • 编程操作失败(PGERR标志位被置1)
  • 写保护错误(WRPRTERR标志位被置1)
  • 操作结束标志(EOP标志位被置1)

这些标志位就像是芯片内部的"小旗子",每次操作后都需要手动把它们放倒,否则下次操作时芯片就会看到这些还竖着的旗子,以为出了什么问题。

2. FLASH_ERROR_PG错误的深层原因分析

2.1 Flash控制器的内部机制

STM32F103的Flash控制器其实是个相当精密的部件。它内部维护着一组状态寄存器(FLASH_SR),用来记录最近一次操作的状态。当我们执行擦除或写入操作时,控制器会自动更新这些状态位。

常见的几个重要标志位包括:

  • PGERR:编程错误标志
  • WRPRTERR:写保护错误标志
  • EOP:操作结束标志

这些标志位有个特点:它们不会自动清除!也就是说,一旦被置位,就会一直保持,直到我们手动清除它们。这就好比你在厨房做饭,用完的锅碗瓢盆如果不及时清洗,下次想做饭时就会发现没干净的厨具可用了。

2.2 重复擦除失败的具体场景

在实际项目中,这个问题通常出现在需要频繁更新Flash数据的场景,比如:

  • 实时参数保存
  • 运行日志记录
  • 配置信息存储

以我的项目为例,我们需要在系统运行时动态保存一些参数。最初的设计是每次上电时擦除一次Flash,然后写入数据。这样运行没问题,因为每次上电都是一次全新的开始。但当需求变成要在运行时多次保存数据时,问题就出现了——第二次尝试擦除同一个扇区时,必然会失败。

3. 完整的解决方案与代码实现

3.1 关键步骤:清除标志位

解决这个问题的关键就是在每次擦除操作前,先清除所有相关的标志位。这就像每次做饭前先把厨房收拾干净一样重要。

具体实现很简单,只需要在擦除操作前加入这行代码:

FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

这行代码的作用是同时清除三个可能影响后续操作的标志位。在实际项目中,我建议不管这些标志位当前是否被置位,都统一清除一下,这样可以确保万无一失。

3.2 完整的Flash操作流程

结合我的项目经验,一个健壮的Flash操作流程应该如下:

__disable_irq(); // 第一步:关闭总中断,防止操作被打断 FLASH_Unlock(); // 第二步:解锁Flash,获得操作权限 // 第三步:清除所有可能影响操作的标志位 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); // 第四步:执行扇区擦除 FLASH_ErasePage(STM32_FLASH_BASE); // 第五步:写入数据 for(i = 0; i < 12; i++) { FLASH_ProgramHalfWord(STM_IDADDR+i*2, pBuffer[i]); } // 写入结束标志 FLASH_ProgramHalfWord(STM_SETADDR, SET_FLAG); FLASH_Lock(); // 第六步:重新锁定Flash __enable_irq(); // 第七步:恢复中断

这个流程中,清除标志位的操作放在了擦除之前,这是经过多次测试验证的最佳位置。如果放在擦除之后,可能会错过某些在擦除过程中产生的标志位。

4. 实际项目中的注意事项与优化建议

4.1 操作时序的重要性

在操作Flash时,时序非常关键。根据STM32参考手册,Flash控制器需要一定的时间来完成各种操作。如果在操作未完成时就尝试进行下一步,可能会导致不可预料的错误。

我的经验是:

  1. 在擦除或编程操作后,最好加入一个简短的延时
  2. 可以通过轮询FLASH_SR寄存器中的BSY位来判断操作是否完成
  3. 对于关键数据,建议实现校验机制,比如CRC校验

4.2 Flash寿命的考量

虽然解决了重复擦除的问题,但还需要注意Flash的寿命问题。STM32F103的Flash通常可以承受约1万次的擦写循环。在需要频繁更新的场景中,建议:

  1. 实现磨损均衡算法,将写操作分散到不同地址
  2. 尽量减少不必要的擦写操作
  3. 对于频繁变更的数据,可以考虑先缓存在RAM中,定期批量写入Flash

4.3 错误处理的最佳实践

在实际项目中,完善的错误处理机制非常重要。我的做法是:

FLASH_Status status = FLASH_ErasePage(STM32_FLASH_BASE); if(status != FLASH_COMPLETE) { // 记录错误日志 // 执行恢复操作 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); // 可能需要重新尝试操作 }

这种处理方式可以大大提高系统的鲁棒性,特别是在工业控制等对可靠性要求高的场景中。

http://www.jsqmd.com/news/586405/

相关文章:

  • 从单周期到多周期:深入对比MIPS CPU设计,看微程序控制器如何成为‘大脑’
  • tao-8k Embedding模型惊艳案例:工业设备维修手册语义检索实战
  • 免费音频转换器fre:ac:3步掌握跨平台音频格式转换完整指南
  • 多边形等距缩放算法:从原理到OpenCV实现
  • 系统优化与性能提升指南:RyTuneX全方位优化方案
  • 抢答器这玩意儿在各种竞赛里简直就是气氛组担当。今天咱们来扒拉一个用单片机搞的智能抢答系统,既有硬件电路又有软件代码,还能自己动手焊板子玩
  • GLM-4.1V-9B-Base模型轻量化探索:适用于移动端的部署策略
  • AgentCPM-Report参数详解:Pixel Epic中‘智力同步率’实时监控原理
  • 告别重复劳动:用Altium Designer脚本一键导入并关联立创EDA的封装与3D库
  • C++条件判断入门:if/else详解
  • 智能高效的定制化风扇控制方案:开源工具Fan Control全解析
  • 保姆级教程:用交大镜像源5分钟安装PyTorch 2.3.0(支持CUDA 12.6)
  • 告别重复劳动:用快马智能生成trea国际版多语言开发提效套件
  • 16. 比热容实验模拟
  • 如何在Linux桌面高效管理笔记:Sticky便签工具的完整指南
  • 亿点意外!龙虾 ClawHub 中国镜像上线,合作方竟然是字节。网友:我腾讯不要面子的吗
  • 实战应用:利用快马平台模拟鸿蒙pc版与手机的笔记跨设备同步功能
  • 结合知识图谱:StructBERT用于实体对齐与关系匹配
  • ControlNet-v1-1 FP16模型深度解析:SD1.5兼容性与性能优化实战指南
  • 如何解决游戏字体兼容性问题:魔兽世界字体合并工具完整指南
  • 告别黑苹果配置难题:OpCore-Simplify智能工具如何让复杂EFI制作变得零门槛
  • 告别Transformer和CNN?手把手教你用ChangeMamba搞定遥感图像变化检测
  • 告别网络依赖:实战指南——将Hugging Face Transformers模型预下载并本地化加载
  • AI辅助开发:借助快马智能模型为华网三百每年cn官网打造咨询聊天机器人
  • 2026年4月市面上钢结构直销厂家,高强度低自重的钢结构优势 - 品牌推荐师
  • AI地质绘图实战:从ChatGPT到Midjourney的流程优化与科学准确性提升
  • WPS-Zotero:跨平台科研写作的终极解决方案
  • 3个实用技巧快速实现Sketch设计稿到HTML代码的智能转换
  • RTX 4090D 24G显存适配方案:PyTorch 2.8镜像GPU利用率提升实测分析
  • AMD GPU本地AI革命:Ollama-for-amd实战部署与性能优化指南