近日,发现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
HAL_FLASH_Unlock(); //解锁
FLASH_WaitForLastOperation(FLASH_WAITETIME); //添加的代码
addrx=WriteAddr; //写入的起始地址
endaddr=WriteAddr+NumToWrite*4; //写入的结束地址
if(addrx<0X1FFF0000)
{
while(addrx
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
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
{
break; //写入异常
}
WriteAddr+=4;
pBuffer++;
}
}
HAL_FLASH_Lock(); //上锁
}