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
相关产品推荐
相关产品推荐

