文章
博客 网店

 STM32F0 FLASH模拟EEPROM应用


本程序使用一flash 中一页作为数据存储,为了提高写入可写入次数采用循环使用的方法,敬请参考。

//FLASH 32K空间中的最后一页(1024字节)
#define EEPROM_START_ADDR 0X8007C00   //模拟EEPROM在FLASH中的开始地址
#define EEPROM_END_ADDR   0X8008000    //结束地址
#define EEPROM_BLOCK_SIZE 32    //要存储的参数长度(此值必须能够整除1024

static void EepInit(void)
{
  uint8_t i;
  uint32_t addr=EEPROM_START_ADDR;
  FLASH_Unlock();
  FLASH_ErasePage(EEPROM_START_ADDR);  
  //...此处写入默认数据(参数)
  for(i=0;i<EEPROM_BLOCK_SIZE;i+=2)
  {
    FLASH_ProgramHalfWord(addr,0xAABB);
    addr+=2;
  }
  FLASH_Lock();
}
//向模拟EEPROM写入数据
void EepWrite(uint8_t *buf,uint8_t size)
{
  uint8_t i,*p;
  uint32_t addr=EEPROM_START_ADDR;
  uint16_t val;
  
  FLASH_Unlock();
  
  //查找最后存储地址
  while(addr < EEPROM_END_ADDR)
  {
    p=(uint8_t *)addr;
    for(i=0;i<EEPROM_BLOCK_SIZE;i++)
    {  
      if(p[i]!=0xff) //不空
        break;
    }
    
    if(i==EEPROM_BLOCK_SIZE) //全部为空
      break;
    
    addr+=EEPROM_BLOCK_SIZE;  
  }
  
  //用完空间
  if(addr >= EEPROM_END_ADDR)
  {
    FLASH_ErasePage(EEPROM_START_ADDR);  
    addr=EEPROM_START_ADDR;
  }

  for(i=0;i<EEPROM_BLOCK_SIZE;i+=2)
  {
    if(i>=size) break;
    //STM32F0为小端模式(一般mcu都是小端),高字节在后
    val=buf[i+1];
    val<<=8;
    val+=buf[i];
    FLASH_ProgramHalfWord(addr,val);
    addr+=2;
  }
  
  FLASH_Lock();
}

//从模拟EEPROM读入数据
void EepRead(uint8_t *buf,uint8_t size)
{
  uint32_t addr=EEPROM_START_ADDR;
  uint8_t i,*p=(uint8_t *)addr;
  
  //查找最后存储地址
  while(addr < EEPROM_END_ADDR)
  {
    p=(uint8_t *)addr;
    for(i=0;i<EEPROM_BLOCK_SIZE;i++)
    {  
      if(p[i]!=0xff) //不空
        break;
    }
    
    if(i==EEPROM_BLOCK_SIZE) //找到一个空位置
      break;
    
    addr+=EEPROM_BLOCK_SIZE;  
  }
  
  if(addr == EEPROM_START_ADDR) //未初始化
  {
    EepInit();
    addr=EEPROM_START_ADDR;
  }
  else
  {
    addr-=EEPROM_BLOCK_SIZE; //调整到最后有效地址处
  }
  
  p=(uint8_t *)addr;
  size=size<EEPROM_BLOCK_SIZE?size:EEPROM_BLOCK_SIZE;
  for(i=0;i<size;i++)
    buf[i]=p[i];
}



芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved