STM32F4 Flash数据的保存和读取。

STM32F4 Flash数据的保存和读取。

  STM32 F4的存储和F1的存储稍稍有些区别。F4的最小存储单位是扇区,而F1的最小存储单位是。(那么这样擦除的时候就存在区别,F1系的可以只擦除一页PAGES(最小1K),而F4需要擦除一个扇区SECTORS(最小16K),好处就是F1可以最大程度不影响本扇区非本页的数据,而F4则会影响本扇区数据)
在这里插入图片描述

  STM32的读取比较简单,直接用指针指向对应的空间地址就可以取数据。最小可以写4个字节,即以为存储单位。

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个字节.	
	}
}

  STM32的写入稍微麻烦一点,需要先把扇区的数据擦除成0XFF,然后才可以写入数据。具体做法如地下:
1.禁止中断
2.flash解锁,禁止数据缓存
3.扇区擦除并检验
4.写入数据
5.开启数据缓存,flash上锁
7.开启中断


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;     //开启中断
} 

  所以如果要修改扇区内的数据,则需要先将扇区内的数据取出来,然后修改对应的数据,最后再存入

  以修改一个结构体数据为例,先将数据使用memcpy函数cpy出来,然后使用结构体指向该数据,然后该结构体赋新值,最后再写入数据,这样就不会影响该扇区其他结构体的数据。

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

猜你喜欢

转载自blog.csdn.net/qq_34430371/article/details/107093288