In many applications, we need to save running data. This article We take the APM32F103xE as an example to show how to use its flash to emulate EEPROM saving data.
Reference code as below
#include “main.h”
#if defined (APM32F10X_HD)
#define FLASH_PAGE_SIZE ((uint16_t)0×800)
#else
#define FLASH_PAGE_SIZE ((uint16_t)0×400)
#endif
#define BANK1_WRITE_START_ADDR ((uint32_t)0×08008000)
#define BANK1_WRITE_END_ADDR ((uint32_t)0×0800C000)
enum {FAILED, PASSED};
volatile uint8_t MemoryProgramStatus = PASSED;
/*!
*@brief Main program
*
*@param None
*
*@retval None
*
*/
uint32_t gWordData[5010]={0};
uint8_t gByteData[5010]={0};
void Flash_WriteWord(uint32_t addr_start,uint32_tp_data,uint32_t data_num)
{
FMC_STATUS_TFLASHStatus = FMC_STATUS_COMPLETE;
uint32_tpage_num=0,i=0,addr_temp=0,addr_end;
page_num= data_num4/ FLASH_PAGE_SIZE;
if(data_num*4%FLASH_PAGE_SIZE!=0)
{page_num++;}
FMC_Unlock();
FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE |FMC_FLAG_WPE));
for(i =0; i<page_num; i++)
{
FLASHStatus = FMC_ErasePage(addr_start + (FLASH_PAGE_SIZE * i));
while(FLASHStatus!= FMC_STATUS_COMPLETE);
}
addr_temp= addr_start;
for(i=0;i<data_num;i++)
{
FLASHStatus = FMC_ProgramWord(addr_temp, p_data);
addr_temp = addr_temp + 4;
while(FLASHStatus!= FMC_STATUS_COMPLETE);
}
FMC_Lock();
// Verify the data written in is correct or not
addr_temp = addr_start;
for(i=0;i<data_num;i++)
{
if(((__IOuint32_t) addr_temp) != p_data)
{
break;
}
addr_temp+= 4;
}
}
void Flash_WriteByte(uint32_t addr_start,uint8_t*p_data,uint32_t data_num)
{
FMC_STATUS_TFLASHStatus = FMC_STATUS_COMPLETE;
uint32_tpage_num=0,i=0,addr_temp=0,addr_end;
uint32_tword_data_temp=0,word_num=0,remainder_data_num=0,data_counter=0;
page_num= data_num/FLASH_PAGE_SIZE;
FMC_Unlock();
if(data_num%FLASH_PAGE_SIZE!=0)
{page_num++;}
FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC| FMC_FLAG_PE | FMC_FLAG_WPE));
for(i =0; i<page_num; i++)
{
FLASHStatus = FMC_ErasePage(addr_start + (FLASH_PAGE_SIZE * i));
while(FLASHStatus!= FMC_STATUS_COMPLETE);
}
addr_temp = addr_start;
word_num= data_num/4;
remainder_data_num=data_num%4;
/*
Note: If we write in 0×00010203, the result of what we read will be 0×03 0×02 0×01 0×00
If we write in 0×03020100, the result of what we read will be 0×00 0×01 0×02 0×03
/
data_counter=0;
for(i=0;i<word_num;i++)
{
word_data_temp = (uint32_t)(p_data+data_counter);
word_data_temp = word_data_temp |(((uint32_t)(p_data+data_counter+1))<<8);
word_data_temp = word_data_temp | (((uint32_t)(p_data+data_counter+2))<<16);
word_data_temp = word_data_temp |(((uint32_t)(p_data+data_counter+3))<<24);
data_counter=data_counter+4;
FLASHStatus = FMC_ProgramWord(addr_temp, word_data_temp);
addr_temp = addr_temp + 4;
while(FLASHStatus!= FMC_STATUS_COMPLETE);
}
word_data_temp=0×00;
if(remainder_data_num!=0)
{
for(i=0;i<remainder_data_num;i++)
{
word_data_temp= word_data_temp |( ((uint32_t)(p_data+data_counter+i))<< (i8));
}
for(;i<4;i++)
{
word_data_temp = word_data_temp | ((0xFF)<<(i8));
}
FLASHStatus = FMC_ProgramWord(addr_temp, word_data_temp);
addr_temp = addr_temp + 4;
while(FLASHStatus!= FMC_STATUS_COMPLETE);
}
FMC_Lock();
// Verify the data written in is correct or not
addr_temp = addr_start;
for(i=0;i<data_num;i++)
{
if(((__IOuint8_t) addr_temp) != p_data)
{
break;
}
addr_temp++;
}
}
int main(void)
{
uint32_ti=0;
for(i=0;i<5000;i++)
{
gWordData=i;
gByteData=(uint8_t)i;
}
//Flash_WriteWord(BANK1_WRITE_START_ADDR,gWordData,5000);
Flash_WriteByte(BANK1_WRITE_START_ADDR,gByteData,5000);
for(i=0;i<5003;i++)
{
gWordData=i2;
gByteData=(uint8_t)i2;
}
//Flash_WriteWord(BANK1_WRITE_START_ADDR,gWordData,5003);
Flash_WriteByte(BANK1_WRITE_START_ADDR,gByteData,5003);
while(1);
}
Test writing 5000 and 5003 words data from the starting address 0×08008000, and check the results, we can see all data wrote in correctly.
Test writing 5000 and 5003 words data from the address 0×08008000, and check the results, we can see all data wrote in correctly.
Note:
- The Flash bit can be written from 1 to 0, but cannot be written from 0 to 1. After page data was wrote, if want to write again, you need to erase the page.
- Erase the page size based on your data size you want to write.