You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32G030F6P6写Flash后异常:断电无法识别、中断跳转至0x1fff0000

STM32G030F6P6 Flash操作后异常故障排查与恢复求助

问题现象

  • 基于STM32G030F6P6开发,程序需完成两项Flash操作:将8位数据写入第15页、设置读保护等级为0xBB
  • 执行程序后,断电重启后无法通过SWD接口被编程器识别,程序完全不运行(LED无闪烁);但未断电状态下,可正常连接编程器、擦除或重写程序
  • 调试发现:无中断触发时程序运行正常;触发任意中断(ADC/DMA/TIM)后,程序跳转至0x1fff0000(系统Bootloader地址)并卡死,此时VTOR寄存器值从0变为0x1fff0000,Flash Latency寄存器被设为2
  • 已定位故障根源为写入Flash最后一页的操作,与读保护设置无关;即使擦除全部Flash,仍无法恢复芯片正常状态,已损坏10余片芯片

相关代码

Flash写入代码(第15页)

FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;

while (FLASH->SR & FLASH_SR_BSY1);

FLASH->SR |= FLASH_SR_OPTVERR;
FLASH->SR |= FLASH_SR_FASTERR;
FLASH->SR |= FLASH_SR_MISERR;
FLASH->SR |= FLASH_SR_PGSERR;
FLASH->SR |= FLASH_SR_SIZERR;
FLASH->SR |= FLASH_SR_PGAERR;
FLASH->SR |= FLASH_SR_WRPERR;
FLASH->SR |= FLASH_SR_PROGERR;
FLASH->SR |= FLASH_SR_OPERR;

FLASH->CR |= FLASH_CR_PER; //Page erase enable
FLASH->CR |= (15<<FLASH_CR_PNB_Pos); //Page number selection
FLASH->CR |= FLASH_CR_EOPIE; //End-of-operation interrupt enable
FLASH->CR |= FLASH_CR_STRT; // Start erase operation

while (FLASH->SR & FLASH_SR_BSY1);

if (FLASH->SR & FLASH_SR_EOP)
{
    FLASH->SR |= FLASH_SR_EOP;
}

FLASH->CR &= ~FLASH_CR_PER; //Page erase disabled
//--------------------------------------------------
while (FLASH->SR & FLASH_SR_BSY1);

FLASH->SR |= FLASH_SR_OPTVERR;
FLASH->SR |= FLASH_SR_FASTERR;
FLASH->SR |= FLASH_SR_MISERR;
FLASH->SR |= FLASH_SR_PGSERR;
FLASH->SR |= FLASH_SR_SIZERR;
FLASH->SR |= FLASH_SR_PGAERR;
FLASH->SR |= FLASH_SR_WRPERR;
FLASH->SR |= FLASH_SR_PROGERR;
FLASH->SR |= FLASH_SR_OPERR;

FLASH->CR |= FLASH_CR_PG; //Flash memory programming enable
FLASH->CR |= (15<<FLASH_CR_PNB_Pos); //Page number selection
FLASH->CR |= FLASH_CR_EOPIE; //End-of-operation interrupt enable

*(__IO uint32_t*)0x08007800=(uint32_t)mydata;
*(__IO uint32_t*)0x08007804=0;

while (FLASH->SR & FLASH_SR_BSY1);

if (FLASH->SR & FLASH_SR_EOP)
{
    FLASH->SR |= FLASH_SR_EOP;
}
FLASH->CR &= ~FLASH_CR_PG; //Page programming disabled
FLASH->CR &= ~FLASH_CR_EOPIE; //End-of-operation interrupt disabled

FLASH->CR |= FLASH_CR_LOCK;

读保护设置代码

if ((FLASH->OPTR & FLASH_OPTR_RDP) != 0xBB)
{
  FLASH->KEYR = 0x45670123;
  FLASH->KEYR = 0xCDEF89AB;

  FLASH->OPTKEYR = 0x08192A3B;
  FLASH->OPTKEYR = 0x4C5D6E7F;

  while (FLASH->SR & FLASH_SR_BSY1);

  FLASH->OPTR |= (0xBB << FLASH_OPTR_RDP_Pos);

  while (FLASH->SR & FLASH_SR_BSY1);
  FLASH->CR |= FLASH_CR_OPTSTRT;
  while (FLASH->SR & FLASH_SR_BSY1);
  FLASH->CR |= FLASH_CR_LOCK;
}

故障排查方案

  • 确认Flash页的硬件限制:STM32G030F6P6的Flash总容量32KB,每页2KB,第15页为最后一页(地址范围0x08007800-0x08007FFF)。查阅芯片手册,确认该页是否包含特殊功能区域(如用户选项字节备份、Bootloader相关配置),是否存在写入限制
  • 完善Flash操作的错误检测:当前代码仅清除状态寄存器标志,但未检查擦除/编程操作是否产生错误(如WRPERR写保护错误、PROGERR编程错误)。需在操作后增加错误标志检查,若出错立即终止操作并处理
  • 验证地址与对齐合法性:确认写入地址0x08007800、0x08007804是否完全处于第15页范围内,且符合32位编程的对齐要求;同时检查该页是否被配置为写保护区域(通过选项字节WRP位)
  • 排查向量表异常原因:中断触发后跳转到Bootloader地址,说明主Flash的中断向量表失效。需确认写入最后一页是否破坏了向量表的完整性,或Flash的一致性校验出错导致CPU自动切换到Bootloader向量表
  • 检查电源稳定性:Flash擦除/写入操作对电源电压稳定性要求高,需确保操作过程中VDD电压稳定在芯片手册规定的范围内(典型3.3V),避免电源波动导致Flash损坏
  • 验证Flash操作时序合规性:严格按照芯片手册的Flash操作流程执行,确认解锁、等待忙标志、操作触发、标志清除、锁定的每一步时序是否符合要求

损坏芯片恢复方法

  • 尝试Bootloader模式恢复:设置BOOT引脚进入系统内置Bootloader(STM32G0的BOOT0接高电平、BOOT1接低电平,具体参考芯片数据手册),使用STM32CubeProgrammer通过串口连接芯片,执行全Flash擦除(包括选项字节)操作
  • 复位瞬间SWD连接:部分异常状态下,芯片仅在复位瞬间能被SWD识别。可尝试按住复位键,点击编程器的"连接"按钮后立即松开复位键,尝试擦除Flash
  • 恢复默认选项字节:若能进入Bootloader或SWD连接成功,读取当前选项字节配置,检查RDP、WRP等字段是否异常,将选项字节恢复为出厂默认值后再擦除主Flash
  • 物理损坏判定:若上述方法均无法识别芯片,说明Flash已物理损坏,此类芯片无法恢复,只能更换

内容的提问来源于stack exchange,提问作者red15530

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:35:17