使用STM32CubeIde对STM32F413进行FLASH读写操作的详细说明

1. Flash区间介绍

在 stm32f413 中,flash_ex.h 对 flash 页信息的文件描述中,共有
FLASH_SECTOR_0 - FLASH_SECTOR_15,这里面的flash大小为1.5M,容量较大一些,
其中:
FLASH_SECTOR_0 至 FLASH_SECTOR_3 为16K;
FLASH_SECTOR_4 为 64K;
FLASH_SECTOR_0 至 FLASH_SECTOR_4 共计128K;
FLASH_SECTOR_5 至 FLASH_SECTOR_15 每页大小为128K;

在这里插入图片描述

这里所用Flash为1M空间,FLASH_SECTOR范围:
FLASH_SECTOR_0 - FLASH_SECTOR_11 共11页,每页大小与1.5M的相同;
页起始对应地址如下:

在这里插入图片描述

2. 写操作

2.1 按字节写入

头文件:
#include “main.h”
#include “stm32flash.h”
#include “stm32f4xx_hal.h”
#include “stdio.h”

获取页地址代码

uint8_t STMFLASH_GetFlashSector(uint32_t flash_addr)
{
	if(flash_addr < ADDR_FLASH_SERTOR_1)
	{
		return FLASH_SECTOR_0;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_2)
	{
		return FLASH_SECTOR_1;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_3)
	{
		return FLASH_SECTOR_2;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_4)
	{
		return FLASH_SECTOR_3;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_5)
	{
		return FLASH_SECTOR_4;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_6)
	{
		return FLASH_SECTOR_5;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_7)
	{
		return FLASH_SECTOR_6;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_8)
	{
		return FLASH_SECTOR_7;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_9)
	{
		return FLASH_SECTOR_8;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_10)
	{
		return FLASH_SECTOR_9;
	}
	else if(flash_addr < ADDR_FLASH_SERTOR_11)
	{
		return FLASH_SECTOR_10;
	}
	else
	{
		return FLASH_SECTOR_11;
	}
}

单字节写入代码

void STMFLASH_Write_Byte(uint32_t WriteAddr, uint8_t *pBuffer) //写入1个字节
{
	//定义各种变量
	FLASH_EraseInitTypeDef FlashEraseInit;
	HAL_StatusTypeDef FlashStatus=HAL_OK;
	u32 SectorError=0;
	//解锁FLASH
	HAL_FLASH_Unlock();             
	//判断地址合法
	if(WriteAddr<0X1FFF0000)
	{
		//初始化擦除变量
		FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //
		FlashEraseInit.Sector=FLASH_SECTOR_5;   //
		FlashEraseInit.NbSectors=1;                             //
		FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //
		if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)
		{
			printf("Erase failed! \r\n");
		}
		//FLASH操作是否完成
		FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME);            //
		if(FlashStatus==HAL_OK)
		{
				//写操作,按字节写入
				if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, WriteAddr, *pBuffer)!=HAL_OK)//
				{
					printf("write failed! \r\n");
				}
				else
				{
					printf("write successed! \r\n");
				}
		}
		else
		{
			printf("FlashStatus failed! \r\n");
		}
		//FLASH上锁
		HAL_FLASH_Lock();           //
	}
}

写入时发现的问题:写入速度较慢,用了几乎1S,太慢了,不过只写一个标志位的话还是可以接受的。

在这里插入图片描述

写入结果:循环写入到该地址,正常。

在这里插入图片描述

在这里插入图片描述

2.2 多字节写入

头文件:
#include “main.h”
#include “stm32flash.h”
#include “stm32f4xx_hal.h”
#include “stdio.h”

/*多字节写入*/
void STMFLASH_Write_Byte_Long(uint32_t WriteAddr, uint8_t *pBuffer, uint32_t wt_len)
{
	FLASH_EraseInitTypeDef FlashEraseInit;
	HAL_StatusTypeDef FlashStatus=HAL_OK;
	uint32_t  SectorError=0;

	uint32_t flash_addr = WriteAddr;   //要写入的地址
	uint32_t flash_end_addr = WriteAddr + wt_len;  //结束地址

	uint32_t flash_len = wt_len;   			//要写入的长度
	uint8_t    flash_page_num;                //

	flash_page_num = STMFLASH_GetFlashSector(WriteAddr);  //首页地址

	HAL_FLASH_Unlock();             //

	/*判断当前地址是否超出范围*/
	while(flash_addr < flash_end_addr)
	{
		FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;             //
		FlashEraseInit.Sector=STMFLASH_GetFlashSector(flash_addr);   //
		FlashEraseInit.NbSectors=1;   //
		FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;         //
		if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)
		{
			printf("Erase failed! \r\n");
		}
		FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME);            //
		if(FlashStatus==HAL_OK)
		{
			/*只要长度存在,循环写入*/
			while(flash_len--)
			{
				if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, flash_addr, *pBuffer)!=HAL_OK)
				{
					printf("write failed!\r\n");
				}
				pBuffer++;
				flash_addr++;
				/*判断当前写入地址是否超出当前页*/
				if(flash_page_num < STMFLASH_GetFlashSector(flash_addr))  			//超出
				{
					flash_page_num = STMFLASH_GetFlashSector(flash_addr);
					break;
				}
			}
		}
	}
	printf("write successed!\r\n");
	HAL_FLASH_Lock();           //
}

测试

在这里插入图片描述
在这里插入图片描述

写入结果

在这里插入图片描述

测试在页边缘写入

在这里插入图片描述

写入结果,写入时间不到1.5S

在这里插入图片描述

3. 读取代码

按字节读取

/*
 * 读取字节  8位
 * faddr - 地址
 * */
uint8_t STMFLASH_ReadByte(uint32_t faddr)
{
	return *(__IO uint8_t*)faddr;
}

按半字16位读取

/*
 * 读取  16位
 * faddr - 地址
 * */
uint16_t STMFLASH_ReadByte(uint32_t faddr)
{
	return *(__IO uint16_t*)faddr;
}
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuDvei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值