STM32: Reading and writing of internal Flash

1. Basic knowledge of Flash

1. Flash capacity

Flash can be divided into the following three types according to capacity:

  • 1. Small capacity products: Flash size is 1-32KB (STM32F10X_LD)
  • 2. Medium-capacity products: Flash size is 64-128KB (STM32F10X_MD)
  • 3. Large-capacity products: Flash size is above 256KB (STM32F10X_HD)

2. ST library functions

The ST library mainly provides the following types of operation API functions for Flash operations:

2.1 Flash unlock and lock functions

void FLASH_Unlock(void);    //解锁函数:在对Flash操作之前必须解锁
void FLASH_Lock(void);      //锁定函数:同理,操作完Flash之后必须重新上锁

2.2 Flash write operation function

FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);             //32位字写入函数
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);         //16位半字写入函数
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);    //用户选择字节写入函数

Note: It needs to be explained here that the 32-bit byte write is actually two 16-bit data written, and the address +2 after the first time is written. This is the same as the STM32 flash memory programming we explained earlier. Bit is not contradictory. Writing 8 bits actually takes up two addresses, which is basically the same as writing 16 bits.

2.3 Flash erase function

FLASH_Status FLASH_ErasePage(uint32_t Page_Address);	//擦除一页
FLASH_Status FLASH_EraseAllPages(void);					//擦除所有页

2.4 Get Flash status

FLASH_Status FLASH_GetStatus(void);

The function of obtaining the Flash state is mainly to obtain the state of the Flash, so as to operate the Flash according to the state. The return value of this function is defined by the enumeration type. In the code, you can see that the FLASH_Status type is defined as follows (see the comments for the specific meaning):

typedef enum {
    
    
    FLASH_BUSY = 1,       //忙
    FLASH_ERROR_PG,       //编程错误
    FLASH_ERROR_WRP,      //写保护错误
    FLASH_COMPLETE,       //操作完成
    FLASH_TIMEOUT         //操作超时
}FLASH_Status;

2.5 Waiting for the operation to complete function

FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

Note: When the flash memory write operation is performed, any read operation to the flash memory will lock the bus, and the read operation can be performed correctly after the write operation is completed; the code or data cannot be read during the write or erase operation operating. So before each operation, we have to wait for the last operation to complete this operation before starting.

2. Flash writing and reading

The MCU used in this operation Flash is STM32F103C8T6. In the data sheet, you can see that the flash start address of STM32F103C8T6 is 0x0800 0000, and the Flash size of STM32F103C8T6 is 64K. It can be calculated that the Flash address range of STM32F103C8T6 is: 0x0800 0000—— 0x0800 FFFF. Here, 0x0800 F000 is selected as the starting address for read and write operations. For the C8T6 MCU, operating this starting address should be considered a safe range.

1. Flash writing

According to the above functions provided by the ST library, we can write the Flash write operation code ourselves as follows:

#define STARTADDR 0x0800F000 //STM32F103C8T6适用

/*
 * Name:	    WriteFlashData
 * Function:	向内部Flash写入数据
 * Input:	    WriteAddress:数据要写入的目标地址(偏移地址)
 *             data[]:      写入的数据首地址
 *             num:         写入数据的个数
 */
void WriteFlashData(uint32_t WriteAddress, uint16_t data, uint32_t num)
{
    
    
	uint16_t sign =	0;	//标志位
	
	FLASH_Unlock();     //解锁Flash
	FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);  // 清除所有标志
	sign = FLASH_ErasePage(STARTADDR);	//擦除整页
	if(sign == FLASH_COMPLETE)	//Flash操作完成
	{
    
    
		for(uint32_t i=0;i<num;i++)
		{
    
    
			FLASH_ProgramHalfWord(STARTADDR+WriteAddress+i*2, data[i]);	//写入数据
		}
	}
	FLASH_Lock();	//重新锁定Flash
}

2. Flash reading

According to the above functions provided by the ST library, we can write the Flash read operation code by ourselves as follows:

#define STARTADDR 0x0800F000 //STM32F103C8T6适用
/*
 * Name:	    ReadFlashData
 * Function:	从内部Flash读取num字节数据
 * Input:	    ReadAddress:数据地址(偏移地址)
 *              dest_Data:  读取到的数据存放位置指针
 *              num:        读取字节个数
 */
void ReadFlashData(uint32_t ReadAddress, uint8_t *dest_Data, uint32_t num)
{
    
    
	for(uint32_t i=0;i<num;i++)
	{
    
    
		dest_Data[i]=*(uint8_t*)(STARTADDR+ReadAddress+i);	//读取数据
	}
}

Guess you like

Origin blog.csdn.net/MQ0522/article/details/110821265