Saving and reading of STM32F4 Flash data.

Saving and reading of STM32F4 Flash data.

  The storage of STM32 F4 is slightly different from the storage of F1. The smallest storage unit of F4 is a sector , and the smallest storage unit of F1 is a page . (Then there is a difference when erasing in this way, F1 can only erase a page of PAGES (minimum 1K), while F4 needs to erase a sector SECTORS (minimum 16K), the advantage is that F1 can not affect the fan to the greatest extent The area is not the data of this page, and F4 will affect the data of this sector)
Insert picture description here

  The reading of STM32 is relatively simple, and the data can be fetched by directly pointing to the corresponding space address with the pointer . At least 4 bytes can be written , that is, words are the storage unit.

u32 STMFLASH_ReadWord(u32 faddr)
{
    
    
	return *(vu32*)faddr; 
}  

void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)   	
{
    
    
	u32 i;
	for(i=0;i<NumToRead;i++)
	{
    
    
		pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.
		ReadAddr+=4;//偏移4个字节.	
	}
}

  The writing of STM32 is a bit more troublesome, you need to erase the data of the sector to 0XFF before writing the data. The specific methods are as follows:
1. Prohibit interruption
2. Flash unlock, prohibit data cache
3. Sector erase and verify
4. Write data
5. Turn on data cache, flash lock
7. Turn on interrupt


uint16_t STMFLASH_GetFlashSector(u32 addr)
{
    
    
	if(addr<ADDR_FLASH_SECTOR_1)return FLASH_Sector_0;
	else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_Sector_1;
	else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_Sector_2;
	else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_Sector_3;
	else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_Sector_4;
	else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_Sector_5;
	else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_Sector_6;
	else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_Sector_7;
	else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_Sector_8;
	else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_Sector_9;
	else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_Sector_10; 
	return FLASH_Sector_11;	
}

void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)	
{
    
     
    FLASH_Status status = FLASH_COMPLETE;
    u32 addrx=0;
    u32 endaddr=0;	
    if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)
    return;	//非法地址

    IntsStorage;
    StoreDisableInts;         //禁止中断
    FLASH_Unlock();		//解锁 
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 
    FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
    FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存

    addrx=WriteAddr;				//写入的起始地址
    endaddr=WriteAddr+NumToWrite*4;	//写入的结束地址
    if(addrx<0X1FFF0000)			//只有主存储区,才需要执行擦除操作!!
    {
    
    
        while(addrx<endaddr)		//扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
        {
    
    
            if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
            {
    
       
                status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之间!!
                if(status!=FLASH_COMPLETE)break;	//发生错误了
            }else addrx+=4;
        } 
    }
    if(status==FLASH_COMPLETE)
    {
    
    
        while(WriteAddr<endaddr)//写数据
        {
    
    
            if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//写入数据
            {
    
     
                break;	//写入异常
            }
            WriteAddr+=4;
            pBuffer++;
        } 
    }
    FLASH_DataCacheCmd(ENABLE);	//FLASH擦除结束,开启数据缓存
    FLASH_Lock();//上锁
    RestoreInts;     //开启中断
} 

  So if you want to modify the data in the sector, you need to take out the data in the sector first , then modify the corresponding data , and finally save it .

  Take the modification of a structure data as an example, first use the memcpy function cpy to output the data, then use the structure to point to the data, then assign a new value to the structure, and finally write the data, so that it will not affect the other structures of the sector Body data.

void UpdateSystemFuncParaData(struct ElevatorFuncPara  *elevator_func_parameter)
{
    
    
  memcpy(ParaBuffer,(u8*)LiftSystemaComParaAddr,520);
  struct ElevatorFuncPara   *temp_elevator_func_parameter = (struct ElevatorFuncPara*)&ParaBuffer[40];
  
  temp_elevator_func_parameter->AccXBaseCount        = elevator_func_parameter->AccXBaseCount;
  temp_elevator_func_parameter->CloseLimitOffset     = elevator_func_parameter->CloseLimitOffset;
  temp_elevator_func_parameter->CloseStartTimeLimit  = elevator_func_parameter->CloseStartTimeLimit;
  temp_elevator_func_parameter->CloseStopTimeLimit   = elevator_func_parameter->CloseStopTimeLimit;
  temp_elevator_func_parameter->OpenLimitOffset      = elevator_func_parameter->OpenLimitOffset;
  temp_elevator_func_parameter->OpenStartTimeLimit   = elevator_func_parameter->OpenStartTimeLimit;
  temp_elevator_func_parameter->OpenStopTimeLimit    = elevator_func_parameter->OpenStopTimeLimit;
  temp_elevator_func_parameter->QuitCheckTime        = elevator_func_parameter->QuitCheckTime;
  
  STMFLASH_Write(LiftSystemaComParaAddr,(u32*)ParaBuffer,130);
}

Guess you like

Origin blog.csdn.net/qq_34430371/article/details/107093288