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

STM32F103RET6 FLASH擦除失败问题

[复制链接]
oh1 提问时间:2025-6-19 15:48 / 未解决

MCU是STM32F103RET6,512K大容量型,我现在程序内进行掉电存储,用到的地址是第224页到254页,共60kb,芯片上电后第一次擦除是成功的,然后写入一次数据,再读出数据是对的,之后芯片不掉电,再进行擦除会出现擦不掉的情况,但是FLASH->SR寄存器未起任何异常状态,只有一个EOP置位。如果只是擦除->写入->擦除,中间不进行读的操作就可以正常擦除。

擦除代码如下

/ 状态寄存器标志位 /

define FLASH_FLAG_BSY ((uint32_t)0x00000001) // 忙标志

define FLASH_FLAG_PGERR ((uint32_t)0x00000004) // 编程错误

define FLASH_FLAG_WRPERR ((uint32_t)0x00000010) // 写保护错误

define FLASH_FLAG_EOP ((uint32_t)0x00000020) // 操作结束

void Flash_ErasePage( u32 Address ) { u8 rRetry = 0; u32 rDat = 0; __disable_irq(); // 禁止中断 rFlashRetry: FLASH->KEYR.FlashProgramAndEraseControllerKey_W = FLASH_KEY1; FLASH->KEYR.FlashProgramAndEraseControllerKey_W = FLASH_KEY2; // 解锁

FLASH->SR.All = FLASH_FLAG_WRPERR|FLASH_FLAG_PGERR|FLASH_FLAG_EOP;
while( FLASH->SR.Busy_R == TRUE );  // 忙时卡住
    FLASH->CR.PageErase_RW = ENABLE;
    FLASH->AR.Address_W = (u32)Address;
FLASH->CR.Strat = ENABLE;
    while( FLASH->SR.Busy_R == TRUE );  // 忙时卡住
    FLASH->CR.Strat = DISABLE;
    FLASH->CR.PageErase_RW = DISABLE;   //禁能操作,恢复现场
    FLASH->CR.LockOnlyCanWriteOne_RW = 1;  // 锁定操作
rDat = *((volatile u32 *)Address);
if(rDat != 0xffffffff)
    {
        if(++rRetry < 10)
    {
        goto rFlashRetry;
    }
  }

__enable_irq();

}

写入代码如下

FLASH->KEYR.FlashProgramAndEraseControllerKey_W = FLASH_KEY1; FLASH->KEYR.FlashProgramAndEraseControllerKey_W = FLASH_KEY2; // 解锁 FLASH->CR.Programming_RW = ENABLE; // 编程使能

while (FLASH->SR.Busy_R);

for( u8 tmp = 0;tmp<8;tmp++) { if ((uint32_t)&HighDensity_FlashPage(PreFlashPageStart)->IndexLen16[pWriteToFlash] % 2 != 0) { my_log("地址未对齐!\n");//回复错误 break; } HighDensity_FlashPage(PreFlashPageStart)->IndexLen16[pWriteToFlash] = cflashBuffer1[tmp]; pWriteToFlash ++; while( FLASH->SR.Busy_R == 1 ); }

FLASH->CR.Programming_RW = DISABLE; // 编程禁能 FLASH->CR.LockOnlyCanWriteOne_RW = 1; // 锁定操作

读取代码如下

typedef union { u8 IndexLen8[2048]; // 可正常读出,不可写入 u16 IndexLen16[1024]; // 1024个16位 u32 IndexLen32[512]; }_Flash_High_Density_TypeDef;

define HighDensity_FlashPage(x) ((_Flash_High_Density_TypeDef ) (0x08000000+x0x800))

void Flash_Read(u8* pBuffer,u16 ReadPag,u16 NumByteToRead) { u16 i = 0;

if(ReadPag>255)return;
    if(NumByteToRead>2048)return;
for(i=0;i<NumByteToRead;i++)
    {
        pBuffer[i] = HighDensity_FlashPage(ReadPag)->IndexLen8[i];
    }

}

收藏 评论3 发布时间:2025-6-19 15:48

举报

3个回答
xmshao 回答时间:6 天前
给些提醒供参考:
1、保证擦除过程中供电稳定;
2、保证基本地址、页码参数正确,你现在共擦除的是31页吧;
3、严格按照擦除流程来,以SR_BSY位为0时表示擦除结束;


● Check that no Flash memory operation is ongoing by checking the BSY bit in the
FLASH_CR register
● Set the PER bit in the FLASH_CR register
● Program the FLASH_AR register to select a page to erase
● Set the STRT bit in the FLASH_CR register
● Wait for the BSY bit to be reset
● Read the erased page and verify



原则上要求将所有擦除区域再检查一遍,


即确认是否每个位置都成功擦除了。如果发现有未成功擦除的,得重新擦除。


至于EOP,每次成功编程或擦除完成后它都会被置1.


其实,你可以简化下,就针对某一页进行擦除来检验是否代码实现上有问题。
oh1 回答时间:5 天前

xmshao 发表于 2025-6-19 17:07
给些提醒供参考:
1、保证擦除过程中供电稳定;
2、保证基本地址、页码参数正确,你现在共擦除的是31页吧; ...

我做了检测确实有时候擦除不成功,并且做了重试,擦除步骤是:解锁->清除标志->查询busy->执行擦除->查询busy->上锁->读出校验->不成功重新擦除(重试100次)

xmshao 回答时间:5 天前

oh1 发表于 2025-6-20 10:32
我做了检测确实有时候擦除不成功,并且做了重试,擦除步骤是:解锁-&gt;清除标志-&gt;查询busy-&gt;执行擦除-&gt; ...

[md]ok

一般来讲,读操作是不会影响编程或擦除结果的。注意,擦除时供电足 且 稳定。

所属标签

相似问题

官网相关资源

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