文章目录

  • 《STM32F103的flash读写操作》
  • 一、背景知识
  • 二、ST官方固件提供的API接口函数
  • 2-1解锁上锁函数
  • 2-2获取flash状态函数
  • 2-3擦除函数
  • 2-4写操作函数
  • 2-5等待操作完成函数
  • 2-6读操作
  • 三、操作步骤
  • 3-1流程
  • 四、注意事项


《STM32F103的flash读写操作》


一、背景知识


1、MCU的flash是存储芯片的一种,通过特定的程序可以修改里面的数据。FLASH在电子以及半导体领域内往往表示Flash Memory的意思,即平时所说的“闪存”,全名叫Flash EEPROM Memory。 flash存储器又称闪存,它结合了ROM和RAM的长处,不仅具备电子可擦除可编程(EEPROM)的性能,还可以快速读取数据(NVRAM的优势),使数据不会因为断电而丢失 ;

二、ST官方固件提供的API接口函数

2-1解锁上锁函数

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

2-2获取flash状态函数

FLASH_Status FLASH_GetStatus(void);
通过获取Flash状态函数,获取Flash的状态,以便于根据状态对Flash进行操作。该函数返回值是通过枚举类型定义的,在代码中可以看到FLASH_Status类型定义如下(具体含义看注释即可):
typedef enum {
    FLASH_BUSY = 1,       //忙
    FLASH_ERROR_PG,       //编程错误
    FLASH_ERROR_WRP,      //写保护错误
    FLASH_COMPLETE,       //操作完成
    FLASH_TIMEOUT         //操作超时
}FLASH_Status;

2-3擦除函数

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

2-4写操作函数

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);    //用户选择字节写入函数

2-5等待操作完成函数

FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

注:在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。所以在每次操作之前,我们都要等待上一次操作完成这次操作才能开始。

2-6读操作

该操作没有相对应的API函数,而是直接从地址处把地址的内容通过指针赋予数组或者变量来保存使用。

三、操作步骤

注:任何有关于flash的操作都必须通过解锁操作来进行接下来的步骤

3-1流程

MCUxpresso flash 大小_单片机

写入数据程序
#define STARTADDR 0x0801F000 //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
}
读出数据程序
#define STARTADDR 0x0801F000 //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);	//读取数据
	}
}

四、注意事项

1、每一次的读写操作都需要解锁和上锁,否则可能会造成MCU内地址的读写错乱。
2、写入数据之前需要擦除地址上的数据(每次擦除以整页擦除为单位)