STM32
直播中

小芳

13年用户 927经验值
私信 关注
[问答]

STM32F4数据的存储和读取该如何去实现呢

STM32F4的存储和STM32F1的存储有何区别?
STM32F4数据的存储和读取该如何去实现呢?


回帖(1)

王玮

2021-12-15 11:37:30
  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         {
                pBuffer=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         else if(addr         else if(addr         else if(addr         else if(addr         else if(addr         else if(addr         else if(addr         else if(addr         else if(addr         else if(addr         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     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         {
            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         {
            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);
}
举报

更多回帖

×
20
完善资料,
赚取积分