STM32:内部Flash的读写

一、Flash基本知识

1. Flash容量

Flash根据容量大小可以分为以下三种:

  • 1、小容量产品:Flash大小为1-32KB(STM32F10X_LD)
  • 2、中容量产品:Flash大小为64-128KB(STM32F10X_MD)
  • 3、大容量产品:Flash大小为256KB以上(STM32F10X_HD)

2. ST库函数

ST库中对Flash操作主要提供了以下几类操作API函数:

2.1 Flash解锁、锁定函数

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

2.2 Flash写操作函数

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

注:这里需要说明,32 位字节写入实际上是写入的两次 16 位数据,写完第一次后地址+2,这与我们前面讲解的 STM32 闪存的编程每次必须写入 16 位并不矛盾。写入 8位实际也是占用的两个地址了,跟写入 16 位基本上没啥区别。

2.3 Flash擦除函数

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

2.4 获取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.5 等待操作完成函数

FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

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

二、Flash的写入和读取

此次操作Flash使用的MCU是STM32F103C8T6,在数据手册中,可以看到STM32F103C8T6的flash起始地址是0x0800 0000,而STM32F103C8T6的Flash大小为64K,可以计算出STM32F103C8T6的Flash地址范围是:0x0800 0000——0x0800 FFFF。这里选取0x0800 F000作为读写操作的起始地址,对于C8T6这款MCU,操作这个起始地址应该算是很安全的范围了。

1.Flash的写入

根据ST库提供的上述函数,我们可以自己编写Flash的写入操作代码如下:

#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的读取

根据ST库提供的上述函数,我们可以自己编写Flash的读取操作代码如下:

#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);	//读取数据
	}
}

猜你喜欢

转载自blog.csdn.net/MQ0522/article/details/110821265