1 Overview
APM32F103xE Flash can only be written in the form of Halfword. In the driver library, it is only one function to write half-word data and one write word data. In the real application, there are situations where a large amount of bytes and word data are written to Flash, and the debugging code, phenomena, and points to note are recorded below.
2 Reference code and project
#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_t*p_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_num*4/ 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 that the data written in is correct
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;
/*
If the data written in is 0x00010203, then the data read by byte in Flash is 0x03 0x02 0x01 0x00
If the data written in is 0x03020100, then the data read by byte in Flash is 0x00 0x01 0x02 0x03
*/
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=0x00;
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))<< (i*8));
}
for(;i<4;i++)
{
word_data_temp = word_data_temp | ((0xFF)<<(i*8));
}
FLASHStatus = FMC_ProgramWord(addr_temp, word_data_temp);
addr_temp = addr_temp + 4;
while(FLASHStatus!= FMC_STATUS_COMPLETE);
}
FMC_Lock();
// Verify that the data written in is correct
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=i*2;
gByteData=(uint8_t)i*2;
}
//Flash_WriteWord(BANK1_WRITE_START_ADDR,gWordData,5003);
Flash_WriteByte(BANK1_WRITE_START_ADDR,gByteData,5003);
while(1);
}
3 Phenomena
3.1 Results of writing 5000/5003 words of data
Starting from address 0×08008000, write 5000 words of data, the last 1 word of data is at address: 0×0800CE1C
3.2 Results of writing 5000/5003 bytes of data
Starting from address 0×08008000, write 5000 bytes of data, the last 1 byte of data is at address: 0×08009387
4 Points to note
(1) When calculating the number of erased pages:
①If the number of bytes is not a multiple of page, it should be noted that the extra data will be written in the next page, so 1 more page should be erased
②When the data is a word, the number of pages to be erased is calculated by multiplying the number of words by 4
(2) The driver function called in the code is to write word, and when writing byte data, pay attention to:
① Converting 4 bytes of data into 1 word according to the small end pattern
② Not forgeting to write the remaining data to Flash when encountering an integer when the number of data is not an integer of 4.
(3) In the code, “Dead” state is used when waiting to write the Flash state, the writing is not very rigorous, and in practical applications, we can use “timeout wait to exit, and return an error”