【问题标题】:Erasing page on stm32 fails with FLASH_ERROR_WRP在 stm32 上擦除页面失败并显示 FLASH_ERROR_WRP
【发布时间】:2013-11-01 09:49:30
【问题描述】:

我正在尝试像这样在 STM32F103RB 上擦除闪存中的一页:

FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_OPTERR);
FLASHStatus = FLASH_ErasePage(Page);

但是,FLASH_ErasePage 无法生成 FLASH_ERROR_WRP

在 stm32-linker 工具中手动启用/禁用写保护并不能解决问题。

【问题讨论】:

    标签: stm32


    【解决方案1】:

    如果状态寄存器中存在先前的 WRP 错误,基本上 FLASH_ErasePage 会因 WRP 错误而失败,而不会尝试执行任何操作。

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

    #define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFC0FD) == 0x00000000) && ((FLAG) != 0x00000000))
    

    【讨论】:

      【解决方案2】:

      你的网页地址是什么?您要访问哪个地址? 例如,此示例在 STM32F100C8 上进行了测试,不仅可以正确擦除数据,还可以正确写入数据。 http://www.ozturkibrahim.com/TR/eeprom-emulation-on-stm32/

      【讨论】:

        【解决方案3】:

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

        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);
        }
        

        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;
        }
        

        第二件事要检查。是否启用了中断,解锁调用和擦除调用之间是否有任何硬件访问?

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2022-08-16
          • 2010-12-28
          • 1970-01-01
          • 2011-08-25
          • 1970-01-01
          • 2016-09-27
          • 2013-11-05
          • 1970-01-01
          • 2012-03-19
          相关资源
          最近更新 更多