STM32 FLASH 循环存储

前言

flash有擦写次数限制,一般为10万次。如果单一地址高频次重复擦写,会严重影响flash的使用寿命。如果一分钟存储一次,10万次也就能够使用不到两年的时间。所以推荐使用循环存储。

使用场景:需要长时间高频次存储的重要数据,flash空间有富余,用空间来换取时间。如:比较频繁刷新又每次都要保存的数据。

优点:代码量低,程序简单,易于理解。能够高频次存取数据,断电复位不丢失,不出错。
缺点:一个扇区存储单一数据;只利于使用最后一次数据,不利用历史数据分析。

变量定义


#define FLASH_START_ADDRESS 0x0803F800
#define FLASH_END_ADDRESS 	0x0803FFFF

typedef struct
{
	uint32_t start_address;
	uint32_t end_address;
	uint32_t puiAddress;

} FLASH_Manage_TypeDef;

FLASH_Manage_TypeDef address;

uint16_t test_count = 0;

初始化函数

void flash_init_data(FLASH_Manage_TypeDef *address)
{
	address->start_address = FLASH_START_ADDRESS;
	address->end_address = FLASH_END_ADDRESS;
}

页擦除

static void sFLASH_PageErase(void)
{
	static FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t SECTORError = 0;
	/* 解锁 */
	HAL_FLASH_Unlock();

	/* 擦除 */
	EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
	EraseInitStruct.NbPages = 1;
	EraseInitStruct.PageAddress = address.start_address;
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
	{
		
	}
}

写函数


void flash_write_data(FLASH_Manage_TypeDef *address, uint16_t *data)
{
	address->puiAddress += 2U;
	if (address->puiAddress >= address->end_address)
	{
		/* 读出,页擦除 */
		//memcpy((uint8_t *)test_read_buf,(uint8_t *)address->start_address,address->end_address - address->start_address);
		sFLASH_PageErase();
		address->puiAddress = address->start_address;
		
	}

	HAL_FLASH_Unlock();
	HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address->puiAddress,
	//*(test_point++));
	*data);
	HAL_FLASH_Lock();

}

读函数


void flash_read_data(FLASH_Manage_TypeDef *address, uint16_t *data)
{
	uint16_t *addr = (void*)(address->end_address-1);
	while(addr)
	{
		/* code */
		if((uint32_t)addr < (uint32_t)address->start_address)
		{
			/* 没有历史数据 */
			*data =0;
			address->puiAddress = (uint32_t)addr;
			break;
		}
		
		if ((*addr) != 0xffff)
		{
			/* 读到历史数据,记录数值和位置 */
			*data = *addr;
			address->puiAddress = (uint32_t)addr;
			break;
		}

		addr--;
	}
}

函数调用

	
	//初始化
	flash_init_data(&address);
	
	//读取flash历史数据
	flash_read_data(&address,&test_count);

	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
		/*stm32f030cc单片机总计256Kbyte flash,每个page大小2Kbyte,所以总计128个page,
		  1Kwork(4Kbyte)为一个sector。
		  先使用127page,地址为0x0803 F800 - 0x0803 FFFF
		*/
		test_count ++;
		flash_write_data( &address, &test_count);
		HAL_Delay(1000);
		
		
	}

结果

STM32 FLASH 循环存储_第1张图片
STM32 FLASH 循环存储_第2张图片

总结

不用担心10万次擦写上限了,如果有多个需要保存的数据,可以多开几个扇区。这种数据太多,也可以打包一个结构体。

你可能感兴趣的:(嵌入式软件开发,stm32,arm,嵌入式硬件,1024程序员节)