关于你STM32F407片内FLASH擦除失败的问题

        近日,发现STM32F407片内FLASH在写入数据时某些情况下会出现扇区擦除不成功的情况,使用正点原子的代码测试也出一样的情况。网上搜索也没找到较为理想的答案。只有一篇文章遇到同样问题,也是使用了一个不太可靠的办法,但是好在可以解决问题。

参见文章:STM32F407片内FLASH擦除失败问题_mob604756f61e6c的技术博客_51CTO博客

        后来我反复测试发现,如果连续写两次数据,第一次写不成功,但是第二次却可以写成功。参考上面的文章,我觉得问题很可能出现在flash解锁和擦除flash之间,很有可能擦除flash之前解锁操作并为完成导致。

        最后我在解锁后加了等待操作完成的语句后,问题解决。完整代码如下:

void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)    
{
    FLASH_EraseInitTypeDef FlashEraseInit;
    HAL_StatusTypeDef FlashStatus=HAL_OK;
    u32 SectorError=0;
    u32 addrx=0;
    u32 endaddr=0;    
    if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;    //非法地址
    
    HAL_FLASH_Unlock();             //解锁    
    FLASH_WaitForLastOperation(FLASH_WAITETIME);    //添加的代码
        
    addrx=WriteAddr;                //写入的起始地址
    endaddr=WriteAddr+NumToWrite*4;    //写入的结束地址
    
    if(addrx<0X1FFF0000)
    {
        while(addrx<endaddr)        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
        {
             if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
            {   
                FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型,扇区擦除
                FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //要擦除的扇区
                FlashEraseInit.NbSectors=1;                             //一次只擦除一个扇区
                FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围,VCC=2.7~3.6V之间!!
                                
                if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)//出错的地方
                {
                    break;//发生错误了    
                }

                }else addrx+=4;
                FLASH_WaitForLastOperation(FLASH_WAITETIME);                //等待上次操作完成
        }
    }
    FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME);            //等待上次操作完成
    if(FlashStatus==HAL_OK)
    {
         while(WriteAddr<endaddr)//写数据
         {
            if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
            {
                break;    //写入异常
            }
            WriteAddr+=4;
            pBuffer++;
        }  
    }
    HAL_FLASH_Lock();           //上锁
}

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值