因为要用内部FLASH代替外部EEPROM,把参数放在STM32的0x08000000+320K处,其中20K是bootloader,300K是应用程序。

原理:先要把整页FLASH的内容搬到RAM中,然后在RAM中改动,然后擦除整页FLASH,再把改动后的内容写入原Flash页。下面程序调试通过。

/*******************************************************************************
* Function Name  : I2C_EE_BufferRead
* Description    : Reads a block of data from the EEPROM.
* Input          :
*                  -RomAddr
*                  -NumByteToRead
*                  -pRomData
* Output         : None
* Return         : None
*******************************************************************************

void I2C_EE_BufferRead(u16 RomAddr,u16 NumByteToRead,u8 *pRomData)
{

u32 param_flashbase;
    u8* ptr;

param_flashbase = 0x8000000+(300+20)*1024;
    ptr = (u8*)(param_flashbase + RomAddr);

while( NumByteToRead-- >0)
    {
        *pRomData = *ptr;            //直接赋值即可
         printf("0x%x ",*pRomData); 
         pRomData++;
         ptr++;
    }
    return;
}

/*******************************************************************************
* Function Name  : I2C_EE_BufferWrite

* Description    : Write a block of data to the EEPROM.
* Input          :
*                  -RomAddr
*                  -NumByteToRead
*                  -pRomData
* Output         : None
* Return         : None
*******************************************************************************

void I2C_EE_BufferWrite(u8 DeviceType,u8 SlaveAddr,u16 RomAddr,u16 NumByteToWrite,u8 *pRomData)
{

uint32_t param_flashbase;
  uint32_t  tempaddress;
  uint32_t  startaddress;
  uint32_t FlashAddress;
  uint32_t datasource;
  u8 buf1[PAGE_SIZE];
  u8 buf2[PAGE_SIZE];
  u32 pagenumber = 0x0;
  u32 EraseCounter = 0x0;
  u32 i = 0;
  FLASH_Status FLASHStatus = FLASH_COMPLETE;

param_flashbase = 0x8000000+(300+20)*1024;
  startaddress=tempaddress = param_flashbase+RomAddr;

/*********************起始指针不在Flash页的开始端*********************
 if( (tempaddress%PAGE_SIZE) != 0)
 {   printf("startptr  not in Page head \r\n");
  if(  ((startaddress%PAGE_SIZE)+NumByteToWrite) >  PAGE_SIZE   ) /*超出一页范围
  {
      I2C_EE_BufferRead(0,0,(tempaddress-(tempaddress % PAGE_SIZE)),PAGE_SIZE,buf1);  /*把起始地址所在页的内容读到内存buf1中
      memcpy(buf1+(tempaddress % PAGE_SIZE),pRomData,PAGE_SIZE-(tempaddress % PAGE_SIZE));  /*把需要写入的数据覆盖到buf1中

while(  FLASHStatus == FLASH_ErasePage(tempaddress)   )       /*buf1写入到Flash
     {
         i=PAGE_SIZE/4;
         datasource = (uint32_t)buf1;
    
         FlashAddress = tempaddress-(tempaddress % PAGE_SIZE);
         while(i-- >0)
         {
             FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
             if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)           
         {
          printf("I2C_EE_BufferWrite error!\r\n");
          return ;
          }
          datasource += 4;
          FlashAddress += 4;    
    }
    break;
   }
      
   NumByteToWrite -= PAGE_SIZE-(startaddress % PAGE_SIZE); 需要写入字节数减去,上面覆盖上去的数据的字节数
   tempaddress +=  PAGE_SIZE-(tempaddress % PAGE_SIZE);        /*把ptr指针指向下一个页起始位置

if((NumByteToWrite % PAGE_SIZE) != 0) /*末指针不在Flash页的开始端
   {
       //读取1 PAGE 数据到内存,修改,然后写进去
       I2C_EE_BufferRead(0,0,tempaddress,PAGE_SIZE,buf2);
       memcpy(buf2,pRomData+PAGE_SIZE-startaddress%PAGE_SIZE+NumByteToWrite-NumByteToWrite%PAGE_SIZE,(NumByteToWrite%PAGE_SIZE));

while(  FLASHStatus == FLASH_ErasePage( tempaddress+NumByteToWrite) )   /*把buf2写入到Flash中*
    {
        i=PAGE_SIZE/4;
        datasource = (uint32_t)buf2;
        FlashAddress = (tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE));  /*末地址指针的页首
        while(i-- >0)
       {
           FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
           if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)            
           {
                printf("I2C_EE_BufferWrite error!\r\n");
                return ;
            }
            datasource += 4;
            FlashAddress += 4;

}
     break;
    }      
   }
  
   NumByteToWrite -= NumByteToWrite % PAGE_SIZE;
    
   //擦除Flash
    pagenumber =  NumByteToWrite/PAGE_SIZE;

for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
   {
         FLASHStatus = FLASH_ErasePage( tempaddress + PAGE_SIZE*EraseCounter );
   }
   //写Flash
   datasource = *(uint32_t *)(pRomData+ PAGE_SIZE-(startaddress % PAGE_SIZE)  );
   FlashAddress = tempaddress;
 
   while( pagenumber-- > 0 )
   {
    i=PAGE_SIZE/4;
    while(i -- >0)
    {
            FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
            if (*(uint32_t*)FlashAddress != *(uint32_t*)datasource)
           {
               printf("I2C_EE_BufferWrite error!\r\n");
               return ;
           }
           datasource += 4;
           FlashAddress += 4;
    }
   }
  }
  else /*写的内容没有超出一页范围
  {
   printf("FlashWrire --in one page \r\n");
   I2C_EE_BufferRead(0,0,(startaddress-(startaddress % PAGE_SIZE)),PAGE_SIZE,buf1);     /*把起始地址所在页的内容读到内存buf1中   
   memcpy( (buf1+(tempaddress % PAGE_SIZE)),pRomData, NumByteToWrite );  /*把需要写入的数据覆盖到buf1中
   while(  FLASHStatus == FLASH_ErasePage(tempaddress)   )
   {
      i=PAGE_SIZE/4;
      datasource = (uint32_t)buf1;
      FlashAddress = tempaddress-(tempaddress % PAGE_SIZE);
      while(i-- >0)
      {
        FLASH_ProgramWord(FlashAddress,*(uint32_t*)datasource);
        if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource) /*读取Flash中的数据,看是否写入正确
        {
               printf("I2C_EE_BufferWrite error!\r\n");
               return ;
        }
        datasource += 4;
        FlashAddress += 4;    
    }
    break;
   }
  }
 }
/*******************起始指针在Flash页的开始端****************************
 else
 { printf("startptr  in Page head \r\n");
  if((NumByteToWrite % PAGE_SIZE) != 0)
  {
    //读取1 PAGE 数据到内存,修改,然后写进去
   I2C_EE_BufferRead(0,0,(u16)(tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE)),PAGE_SIZE,buf1);
   printf("already copy to bug1 \r\n");
   memcpy(buf1,pRomData+NumByteToWrite-(NumByteToWrite % PAGE_SIZE),(NumByteToWrite % PAGE_SIZE));

//end of debug
  }
  //擦除Flash
  if( (NumByteToWrite%PAGE_SIZE) == 0 )
  {
       pagenumber = NumByteToWrite/PAGE_SIZE;
  }
  else
  {
       pagenumber = NumByteToWrite/PAGE_SIZE + 1;
  }
   for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  {
        FLASHStatus = FLASH_ErasePage(startaddress + (PAGE_SIZE * EraseCounter));
  }

//写Flash
  if( pagenumber == 1)   /*只有一页
  {

i=PAGE_SIZE/4;
   datasource = (uint32_t)buf1;
   FlashAddress = startaddress;
   while(i-- >0)
   {
        FLASH_ProgramWord(FlashAddress,*(uint32_t *)datasource);
        if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
        {
            printf("I2C_EE_BufferWrite error!\r\n");
            return ;
        }
        datasource +=4;
        FlashAddress +=4;
   }  
  }
  else /*很多页时,先写前面页,最后写buf1
  {
   while( pagenumber-- > 1 )
   {
    datasource = (u32)pRomData;
    FlashAddress = startaddress;
    i=PAGE_SIZE/4;
    while(i -- >0)
    {
            FLASH_ProgramWord( FlashAddress, *(uint32_t *)datasource );
            if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
            {
                  printf("I2C_EE_BufferWrite error!\r\n");
                  return ;
            }
            datasource += 4;
            FlashAddress += 4;
    } 
   }
   //写后面的页
   datasource = (uint32_t)buf1;
   FlashAddress = startaddress+(pagenumber-1)*PAGE_SIZE;
   i=PAGE_SIZE/4;
   while(i -- >0)
   {
       FLASH_ProgramWord( FlashAddress, *(uint32_t *)datasource );
       if (*(uint32_t *)FlashAddress != *(uint32_t *)datasource)
       {
             printf("I2C_EE_BufferWrite error!\r\n");
             return ;
       }
       datasource += 4;
       FlashAddress += 4;
   } 
  }    
 } 
}

STM32 对内部FLASH读写接口函数的更多相关文章

  1. STM32 对内部FLASH读写接口函数(转)

    源:STM32 对内部FLASH读写接口函数 因为要用内部FLASH代替外部EEPROM,把参数放在STM32的0x08000000+320K处,其中20K是bootloader,300K是应用程序. ...

  2. 【转】STM32擦除内部FLASH时间过长导致IWDG复位分析

    @20119-01-29 [小记] STM32擦除内部FLASH时间过长导致IWDG复位分析

  3. stm32 Flash读写独立函数[库函数]

    一. stm32的FLASH分为 1.主存储块:用于保存具体的程序代码和用户数据,主存储块是以页为单位划分的, 一页大小为1KB.范围为从地址0x08000000开始的128KB内. 2.信息块   ...

  4. [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写

     一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...

  5. STM32 实现内部Flash的读写(HAL库版)

    Flash 中文名字叫闪存,是一种长寿命的非易失性(断电数据不丢失)的存储器.可以对称为块的存储器单元块进行擦写和再编程,在进行写入操作之前必须先执行擦除.一个Nand Flash由多个块(Block ...

  6. 第50章 读写内部FLASH—零死角玩转STM32-F429系列

    第50章     读写内部FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  7. STM32学习笔记:读写内部Flash(介绍+附代码)

    一.介绍 首先我们需要了解一个内存映射: stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同. RAM起 ...

  8. STM32 内部flash的读写程序

    ​ /* Base address of the Flash sectors */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base ...

  9. stm32——Flash读写

    stm32——Flash读写 一.Flash简介 通过对stm32内部的flash的读写可以实现对stm32的编程操作. stm32的内置可编程Flash在许多场合具有十分重要的意义.如其支持ICP( ...

随机推荐

  1. 转:OK6410内存及启动流程

    一.内存 只是从大体上介绍,并没有涉及寄存器的操作 6410的系统资源为:256MB DDR .2GB NANDFlash 如下图所示: ROM是只读存储器,RAM是随机存储器. 区别: 1.ROM( ...

  2. xdebug

    必须的有4个(remote_enable 默认没开,所以必要),其它默认值一般可以xdebug.remote_enable=On; //这个是必须xdebug.remote_host=192.168. ...

  3. linux命令行下的ftp 多文件下载和目录下载(转)

    目标ftp服务器是一个非标准端口的ftp   1.通过shell登录 #ftp    //shell下输入ftp命令,进入到ftp提示符 >open IP  PORT   //IP ,PORT对 ...

  4. linux kernel 0.11 bootsect

    bootsect作用 ①将自己移动到0x90000处 ②将setup从磁盘读到0x90200处 ③将system从磁盘读到0x10000处 寄存器 汇编代码中存在:数据段data seg 栈段 sta ...

  5. 引用类型a=b

    List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); Cache["Key ...

  6. 48.Warning: (vsim-3534) [FOFIR] - Failed to open file "sp_rom_8x256_sr.mif" for reading.

    当在仿真ROM IP核文件时,会出现这种警告,而这种警告的结果是ROM不能输出数据,原因是mif文件要放在modelsim工程文件目录下.类似的,有时候会报错,Failed to open file& ...

  7. 谈谈C#中的 Dispose 和 Finalize

    主要有一下几点需要知道: 1. Dispose需要实现IDisposable接口. Finalize就是c#中的析构方法,方法名以~开始. 2. Dispose由开发人员代码调用,而Finalize由 ...

  8. [shell基础]——awk命令

    关于awk awk是一个强大的文本分析工具,相对于grep的查找.sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大. 简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开 ...

  9. ##常用效果css##

    1    绝对定位的元素的位置相对于最近的已定位祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块.元素被设置成,absolute,原有的位置会被占用,设为 relative原位置 ...

  10. VBS基础篇 - 常用函数

    Option Explicit '*********************************Date/Time函数******************************* 'CDate函 ...