STM32 internal FLASH read and write interface function

Publisher:心动代码Latest update time:2017-02-07 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Because the internal FLASH is used instead of the external EEPROM, the parameters are placed at 0x08000000+320K of the STM32, of which 20K is the bootloader and 300K is the application.


Principle: First move the contents of the entire FLASH page to RAM, then modify it in RAM, then erase the entire FLASH page, and then write the modified contents to the original Flash page. The following program is debugged and passed.

 

/*******************************************************************************

* 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; //Just assign value

         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;


 /*********************The start pointer is not at the beginning of the Flash page*********************/

 if( (tempaddress%PAGE_SIZE) != 0)

 {   printf("startptr  not in Page head \r\n");

  if( ((startaddress%PAGE_SIZE)+NumByteToWrite) > PAGE_SIZE ) /*Out of one page range

  {

      I2C_EE_BufferRead(0,0,(tempaddress-(tempaddress % PAGE_SIZE)),PAGE_SIZE,buf1); /*Read the contents of the page where the start address is located into memory buf1

      memcpy(buf1+(tempaddress % PAGE_SIZE),pRomData,PAGE_SIZE-(tempaddress % PAGE_SIZE)); /*Overwrite the data to be written into 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); The number of bytes to be written minus the number of bytes of data to be overwritten

   tempaddress += PAGE_SIZE-(tempaddress % PAGE_SIZE); /*Set the ptr pointer to the start of the next page


   if((NumByteToWrite % PAGE_SIZE) != 0) /*The end pointer is not at the beginning of the Flash page

   {

       //Read 1 PAGE of data into memory, modify, and then write it in

       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) ) /*Write buf2 to Flash*

    {

        i=PAGE_SIZE/4;

        datasource = (uint32_t)buf2;

        FlashAddress = (tempaddress+NumByteToWrite-(NumByteToWrite % PAGE_SIZE)); /*Head of the last address pointer

        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;

    

   // Erase Flash

    pagenumber = NumByteToWrite/PAGE_SIZE;


     for (EraseCounter = 0; (EraseCounter < pagenumber) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)

   {

         FLASHStatus = FLASH_ErasePage( tempaddress + PAGE_SIZE*EraseCounter );

   }

   //Write 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 /*The content written does not exceed the scope of one page

  {

   printf("FlashWrire --in one page \r\n");

   I2C_EE_BufferRead(0,0,(startaddress-(startaddress % PAGE_SIZE)),PAGE_SIZE,buf1); /*Read the contents of the page where the start address is located into memory buf1   

   memcpy( (buf1+(tempaddress % PAGE_SIZE)),pRomData, NumByteToWrite ); /*Overwrite the data to be written into 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) /*Read the data in the Flash to see if it is written correctly

        {

               printf("I2C_EE_BufferWrite error!\r\n");

               return ;

        }

        datasource += 4;

        FlashAddress += 4;    

    }

    break;

   }

  }

 }

/*******************The starting pointer is at the beginning of the Flash page****************************/

 else

 { printf("startptr  in Page head \r\n");

  if((NumByteToWrite % PAGE_SIZE) != 0)

  {

    //Read 1 PAGE of data into memory, modify, and then write it in

   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

  }

  // Erase 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));

  }



  //Write Flash

  if( pagenumber == 1) /* Only one page

  {   



   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 /*When there are many pages, write the previous page first and buf1 last

  {

   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;

    } 

   }

   //Write the following pages

   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;

   } 

  }    

 } 

}


Keywords:STM32 Reference address:STM32 internal FLASH read and write interface function

Previous article:Use DMA to directly drive GPIO to achieve the highest GPIO output rate
Next article:keil For ARM function absolute definition

Recommended ReadingLatest update time:2024-11-16 20:44

STM32 ILI9341 drives TFTLCD (VII) LCD draws solid triangles, rectangles, circles
The last time we tested the straight line drawing function, we drew a hollow triangle using three straight lines. Today, let’s draw solid ones, namely a solid triangle, a solid rectangle, and a solid circle. 1. Solid triangle For a solid triangle, you can first draw any two sides, then us
[Microcontroller]
STM32 ILI9341 drives TFTLCD (VII) LCD draws solid triangles, rectangles, circles
STM32 serial port burning FLASH external font UCGUI display self-study summary
Recently I have been studying TFT display issues. It is a bit difficult to display multiple Chinese characters. The main reason is that the font library is too large. A few fonts are very difficult. At first, I used an SD card to write to the external FLASH---W25X16, which was completely completed. Later, I felt that
[Microcontroller]
STM32 serial port burning FLASH external font UCGUI display self-study summary
STM32 is set as I2C slave
Hardware platform: STM32F401  Editor: keil 5.18  Operating system: win7 1. I2C Protocol  When transmitting data, the SDA line must remain stable during the high level period of the clock. The high or low level state of SDA can only change when the clock signal of the SCL line is low. Start and Stop Conditions    W
[Microcontroller]
[STM32] Basic principle example of IIC: Common IO port simulates IIC timing to read 24C02
Basic Introduction of IIC Introduction to IIC IIC (Inter-Integrated Circuit) bus is a two-wire serial bus developed by PHILIPS in the 1980s, used to connect microcontrollers and their peripherals. It is a half-duplex communication mode. The main advantages of the IIC bus are its simplicity and effectiveness. Since t
[Microcontroller]
[STM32] Basic principle example of IIC: Common IO port simulates IIC timing to read 24C02
STM32 general timer output PWM function study notes
First of all, if you want to use PWM mode, you have to choose which timer to use to output PWM! Except for the two ordinary timers TIM6 and TIM7, which cannot output PWM, the rest of the timers can output PWM. Each general timer can output 4 channels of PWM, and the advanced timers TIM1 and TIM8 can output 7 channels
[Microcontroller]
STM32 ADC input channel configuration
There are at most 3 ADC modules in STM32, and the channels corresponding to each module do not completely overlap. The figure below is the lower left corner of the general block diagram in the STM32F103CDE data sheet. It can be seen from the figure that 8 external ADC pins are connected to 3 ADC modules, 8 external
[Microcontroller]
STM32 ADC input channel configuration
STM32-based rapid detection system for clenbuterol content
introduction This design is an improvement on the traditional immunoassay, using laser-induced fluorescence technology and fluorescence immunoassay to achieve rapid, quantitative and accurate detection of clenbuterol. It has the advantages of high resolution, rapid response, high sensitivity and strong anti-interfer
[Microcontroller]
STM32-based rapid detection system for clenbuterol content
STM32 CAN filter settings
It seems that many people still don't know how to set filters. It took me a long time to learn it. Let's first look at a register    CAN_TIxR (x=0~2) Send mailbox identification register Standard frame is 31~21 bits,    a total of 11 bits STID Extended frame is 20~3 bits,     a total of 29 bits EXID +STID 0~
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号