单片机/MCUwilliam hill官网
直播中

lee_st

12年用户 45163经验值
擅长:可编程逻辑 嵌入式技术 处理器/DSP RF/无线
私信 关注
[资料]

转: stm32f4 关于内部flash存储数据问题

昨天调试我们新的rtu的时候用外部spi flash的时候出现的一些小问题,因为赶工赶的急,所以想到用f4内置1m的flash作为数据存储器来使用。
首先在网上搜集了一些资料,也就有一篇资料比较好,我这里吧我看的连接的地址挂上,谢谢这位同学的无私,通过他的代码和STM32的数据
手册我,吧函数做一下几个函数,希望对各位同学有帮助,http://www.cnblogs.com/zyqgold/archive/2013/11/09/3416108.html

STM32F4Discovery开发帮使用的STM32F407VGT6芯片,内部FLASH有1M之多。平时写的代码,烧写完之后还有大量的剩余。有效利用这剩余的FLASH能存储不少数据。因此研究了一下STM32F4读写内部FLASH的一些操作。

【STM32F4 内部Flash的一些信息】

STM32F407VG的内部FLASH的地址是:0x08000000,大小是0x00100000。

写FLASH的时候,如果发现写入地址的FLASH没有被擦出,数据将不会写入。FLASH的擦除操作,只能按Sector进行。不能单独擦除一个地址上的数据。因此在写数据之前需要将地址所在Sector的所有数据擦除。

在STM32F4的编程手册上可找到FLASH的Sector划分,我们现在只操作Main memory:

参考Demo中的例子,将FLASH的页的其实地址(基地址)可定义如下:


回帖(4)

lee_st

2016-7-14 09:42:28
这里的flash的在编程钱如果这一个地址已经写过了请先擦除这个地址,因为现在stm32f4的的flash分为11个部分,每个擦除是按照每个部分一起擦除,因为这你的对每个快的做一个缓冲区才行。
我的代码如下:
void get_from_flash(void)
{
delay_ms(2);
OwnFlashReady(0x08008000,getflashdata_buf,100);
// SPI_FLASH_BufferRead(getflashdata_buf, 0x000000, 100);        //??????
// SPI_FLASH_ChipErase();//????flash????????
memmove(&RTU_Basedata_Only,&getflashdata_buf[0],18);
memmove(&BaseData01,&getflashdata_buf[18],21);
memmove(&gx_options01[0],&getflashdata_buf[39],60);
}


void OwnFlashSave(uint32_t save_addr,uint8_t *p,uint16_t number)
{
uint32_t StartSector,EndSector,i, save_addr_temp;
StartSector = GetSector(save_addr);
  EndSector = GetSector(save_addr+number);
save_addr_temp = save_addr;
FLASH_Unlock();
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                  FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
举报

lee_st

2016-7-14 09:43:09
//????flash
for (i = StartSector; i<=EndSector; i += 8)
  {
      while (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE)
      {
      }
  }        //????????????×÷?????????????????????í?ó??
   while (save_addr < number+save_addr_temp)
  {
    if (FLASH_ProgramByte(save_addr, *p++) == FLASH_COMPLETE)  
    {
      save_addr = save_addr + 1;
    }
    else
    {
      while (1)
      {
      }
    }
  }
   FLASH_Lock();
}
举报

lee_st

2016-7-14 09:43:26

// void OwnFlashErasure()


void OwnFlashReady(uint32_t read_addr,uint8_t * read_buf,uint16_t read_number)
{
uint32_t Address_ready;
Address_ready = read_addr;
   while (Address_ready < read_addr+read_number)
  {
    *read_buf++ = (*(__IO uint8_t*)Address_ready);
    Address_ready = Address_ready + 1;
  }  
}


uint32_t GetSector(uint32_t Address)
{
  uint32_t sector = 0;
  
  if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  {
    sector = FLASH_Sector_0;  
  }
  else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  {
    sector = FLASH_Sector_1;  
  }
  else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  {
    sector = FLASH_Sector_2;  
  }
  else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  {
    sector = FLASH_Sector_3;  
  }
  else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  {
    sector = FLASH_Sector_4;  
  }
  else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  {
    sector = FLASH_Sector_5;  
  }
  else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  {
    sector = FLASH_Sector_6;  
  }
  else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  {
    sector = FLASH_Sector_7;  
  }
  else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  {
    sector = FLASH_Sector_8;  
  }
  else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  {
    sector = FLASH_Sector_9;  
  }
  else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  {
    sector = FLASH_Sector_10;  
  }
  else
  {
    sector = FLASH_Sector_11;  
  }


  return sector;
}


代码不是很复杂,但是如果没有弄懂的话还是要费些时间的,希望各位同学多多指教。
举报

lee_st

2016-7-14 09:43:43
分享完成,,,,,,,,,,,
举报

更多回帖

发帖
×
20
完善资料,
赚取积分