好处是写好一次,后面基本不会出问题
我使用的是正点原子的寄存器版本,接口比较清晰,
但也有一个问题STMFLASH_EraseSector 操作内部有延时,会莫名卡在里面
发现HAL_FLASHEx_Erase的操作正常并且很快,
将STMFLASH_Write函数中擦除flash替换为HAL库操作方式,速度瞬间提升。
并且兼容了BANK1,BANK2的操作
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
{ FLASH_EraseInitTypeDef FlashEraseInit;HAL_StatusTypeDef FlashStatus=HAL_OK;u32 SectorError=0;u8 status=0;u32 addrx=0;u32 endaddr=0;if(WriteAddrwhile(addrxif(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区{
#if 1FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS; //擦除类型FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx)%8;//要擦除的扇区FlashEraseInit.Banks=addrx>=BANK2_FLASH_SECTOR_0?FLASH_BANK_2:FLASH_BANK_1; //操作 BANK1FlashEraseInit.NbSectors=1; //一次只擦除一个扇区FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3; //电压范围if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK){break; //发生错误了}SCB_CleanInvalidateDCache(); //清除无效的 D-Cach
#else//status=STMFLASH_EraseSector(STMFLASH_GetFlashSector(addrx));// if(status)break; //发生错误了// SCB_CleanInvalidateDCache(); //清除无效的D-Cache
#endif}else addrx+=4;}}if(status==0){while(WriteAddrif(STMFLASH_Write8Word(WriteAddr,pBuffer))//写入数据{break; //写入异常}WriteAddr+=32;pBuffer+=8;}}STMFLASH_Lock();//上锁
}
#define GP_LENTH sizeof(PARAM_T) //数组长度
#define SAVE_SIZE GP_LENTH/4+((GP_LENTH%4)?1:0) // 必须是4的整数倍PARAM_T gp;void SPIFlash_test(void){memset(&gp,3,sizeof(gp));STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)&gp,SAVE_SIZE);STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)&gp,25);memset(&gp,1,sizeof(gp));STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)&gp,SAVE_SIZE);}
2.通常可以将结构体的首字节,末字节作为验证是否数据已经保存或正确保存的标志