STM32 对内部FLASH读写接口函数

来源:本站
导读:目前正在解读《STM32 对内部FLASH读写接口函数》的相关信息,《STM32 对内部FLASH读写接口函数》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《STM32 对内部FLASH读写接口函数》的详细说明。
简介:因为要用内部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 rn");  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!rn");          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!rn");                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!rn");               return ;           }           datasource += 4;           FlashAddress += 4;    }   }  }  else /*写的内容没有超出一页范围  {   printf("FlashWrire --in one page rn");   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!rn");               return ;        }        datasource += 4;        FlashAddress += 4;        }    break;   }  } }/*******************起始指针在Flash页的开始端****************************/ else { printf("startptr  in Page head rn");  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 rn");   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!rn");            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!rn");                  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!rn");             return ;       }       datasource += 4;       FlashAddress += 4;   }   }     } }

提醒:《STM32 对内部FLASH读写接口函数》最后刷新时间 2024-03-14 01:08:18,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《STM32 对内部FLASH读写接口函数》该内容的真实性请自行鉴别。