删除stm32上的页面失败,出现闪存错误\u WRP

删除stm32上的页面失败,出现闪存错误\u WRP,stm32,Stm32,我试图在STM32F103RB上擦除flash中的一页,如下所示: FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_OPTERR); FLASHStatus = FLASH_ErasePage(Page); 但是,FLASH_擦除页面无法生成FLASH_ERROR_WRP 在stm32链接器工具中手动启用/禁

我试图在STM32F103RB上擦除flash中的一页,如下所示:

FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_OPTERR);
FLASHStatus = FLASH_ErasePage(Page);
但是,FLASH_擦除页面无法生成FLASH_ERROR_WRP


在stm32链接器工具中手动启用/禁用写保护并不能解决此问题。

基本上,如果状态寄存器中存在以前的WRP错误,FLASH\u擦除页面将失败并出现WRP错误,而不尝试执行任何操作

对于FLASH_clearfag调用,至少FLASH_FLAG_BSY将导致assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG));失败(尽管我不确定在这种情况下会发生什么)


你的网页地址是什么?您正在尝试访问哪个地址? 例如,该示例在STM32F100C8上进行了测试,测试内容不仅包括擦除,还包括正确写入数据。

如果使用HAL驱动程序,代码可能如下所示(从实际项目中剪切粘贴)

HAL驱动程序中实际执行工作的内部函数

void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
{
  uint32_t tmp_psize = 0U;

  /* Check the parameters */
  assert_param(IS_FLASH_SECTOR(Sector));
  assert_param(IS_VOLTAGERANGE(VoltageRange));

  if(VoltageRange == FLASH_VOLTAGE_RANGE_1)
  {
     tmp_psize = FLASH_PSIZE_BYTE;
  }
  else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)
  {
    tmp_psize = FLASH_PSIZE_HALF_WORD;
  }
  else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)
  {
    tmp_psize = FLASH_PSIZE_WORD;
  }
  else
  {
    tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  }

  /* If the previous operation is completed, proceed to erase the sector */
  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  FLASH->CR |= tmp_psize;
  CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
  FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB));
  FLASH->CR |= FLASH_CR_STRT;
}
void FLASH\u Erase\u扇区(uint32\u t扇区,uint8\u t电压范围)
{
uint32_t tmp_psize=0U;
/*检查参数*/
断言参数(是闪存扇区(扇区));
assert_param(IS_VOLTAGERANGE(VOLTAGERANGE));
如果(电压范围==闪光电压范围1)
{
tmp_psize=闪存_psize_字节;
}
否则如果(电压范围==闪光电压范围2)
{
tmp_psize=闪光_psize_半个字;
}
否则如果(电压范围==闪光电压范围3)
{
tmp_psize=闪光_psize_单词;
}
其他的
{
tmp_psize=闪光_psize_双字;
}
/*如果上一个操作完成,则继续擦除扇区*/
清除位(闪存->CR,闪存锁定);
FLASH->CR |=tmp|psize;
清除位(闪存->CR,闪存\U CR\U SNB);
闪存->CR |=闪存| CR | SER |(扇区CR |=闪存| CR | STRT;
}
第二件事要检查。中断是否启用,解锁呼叫和擦除呼叫之间是否有任何硬件访问

我希望这有帮助

static HAL_StatusTypeDef Erase_Main_Program ()
{
    FLASH_EraseInitTypeDef ins;
    uint32_t sectorerror;

    ins.TypeErase = FLASH_TYPEERASE_SECTORS;
    ins.Banks = FLASH_BANK_1; /* Do not care, used for mass-erase */
#warning We currently erase from sector 2 (only keep 64KB of flash for boot))
    ins.Sector = FLASH_SECTOR_4;
    ins.NbSectors = 4;
    ins.VoltageRange = FLASH_VOLTAGE_RANGE_3; /* voltage-range defines how big blocks can be erased at the same time */
    return HAL_FLASHEx_Erase (&ins, &sectorerror);
}
void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
{
  uint32_t tmp_psize = 0U;

  /* Check the parameters */
  assert_param(IS_FLASH_SECTOR(Sector));
  assert_param(IS_VOLTAGERANGE(VoltageRange));

  if(VoltageRange == FLASH_VOLTAGE_RANGE_1)
  {
     tmp_psize = FLASH_PSIZE_BYTE;
  }
  else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)
  {
    tmp_psize = FLASH_PSIZE_HALF_WORD;
  }
  else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)
  {
    tmp_psize = FLASH_PSIZE_WORD;
  }
  else
  {
    tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  }

  /* If the previous operation is completed, proceed to erase the sector */
  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  FLASH->CR |= tmp_psize;
  CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
  FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB));
  FLASH->CR |= FLASH_CR_STRT;
}