STM32F407VET6 FLASH读写 HAL库

本文介绍了STM32F407VET6微控制器的Flash操作,包括如何按扇区进行解锁、擦除、写入和上锁的过程,以及提供了一个简单的示例代码片段来演示这些操作。
摘要由CSDN通过智能技术生成

STM32F103C8T6的flash按页擦除,而STM32F407VET6的flash是按扇区擦除的。

STM32F407VET6的flash分为12个扇区:

每次操作的步骤为:对flash解锁、擦除、写入、上锁。

flash.c:

#include "flash.h"

//根据读取的地址,取出内容
uint32_t STMFLASH_ReadWord(uint32_t faddr)
{
	return *(__IO uint32_t*)faddr; 
}

//返回当前要操作的扇区
uint8_t STMFLASH_GetFlashSector(uint32_t addr)
{
	if(addr<ADDR_FLASH_SECTOR_1)return FLASH_SECTOR_0;
	else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_SECTOR_1;
	else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_SECTOR_2;
	else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_SECTOR_3;
	else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_SECTOR_4;
	else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_SECTOR_5;
	else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_SECTOR_6;
	else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_SECTOR_7;
	else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_SECTOR_8;
	else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_SECTOR_9;
	else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_SECTOR_10;   
	return FLASH_SECTOR_11;	
}

//写入flash
void STMFLASH_Write(uint32_t Addr,uint32_t *pBuffer,uint32_t Num)	
{ 
	FLASH_EraseInitTypeDef FlashEraseInit;
	HAL_StatusTypeDef FlashStatus=HAL_OK;
	uint32_t SectorError=0;
	uint32_t addrx=0;
	uint32_t endaddr=0;	
	uint32_t WriteAddr=Addr;
	if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;	//错误地址
    
	HAL_FLASH_Unlock();         //解锁flash
	addrx=WriteAddr;			//写入起始地址
	endaddr=WriteAddr+Num*4;	//写入结束地址
    
	if(addrx<0X080C1000)
	{
		while(addrx<endaddr)		
		{
			 if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)		
			 {   
				FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //扇区擦除
				FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //擦除的扇区
				FlashEraseInit.NbSectors=1;                             //擦除1个扇区
				FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围2.7-3.6
				if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK) 
				{
					break;//写入错误
				}
			 }
			 else addrx+=4;
			 FLASH_WaitForLastOperation(FLASH_WAITETIME);                //等待操作完成
		}
	}
	FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME);         //等待操作完成
	if(FlashStatus==HAL_OK)
	{
		 while(WriteAddr<endaddr)//写数据
		 {
			if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)
			{ 
				break;
			}
			WriteAddr+=4;
			pBuffer++;
		}  
	}
	HAL_FLASH_Lock();           //flash上锁
} 

void STMFLASH_Read(uint32_t Addr,uint32_t *pBuffer,uint32_t size)   	
{
	uint32_t i;
	uint32_t ReadAddr=Addr;
	for(i=0;i<size;i++)
	{
		pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4字节
		ReadAddr+=4;//地址移动4字节
	}
}

flash.h:

#ifndef __FLASH_H
#define __FLASH_H
#include "main.h"

#define STM32_FLASH_BASE 0x08000000 	//flash起始地址
#define FLASH_WAITETIME  50000          //FLASH等待超时时间

//FLASH 扇区的起始地址
#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) 	//扇区0起始地址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) 	//扇区1起始地址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) 	//扇区2起始地址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) 	//扇区3起始地址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) 	//扇区4起始地址, 64 Kbytes  
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) 	//扇区5起始地址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) 	//扇区6起始地址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) 	//扇区7起始地址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) 	//扇区8起始地址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) 	//扇区9起始地址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) 	//扇区10起始地址,128 Kbytes  
#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) 	//扇区11起始地址,128 Kbytes 

//读取数值
uint32_t STMFLASH_ReadWord(uint32_t faddr);		  	
//flash写入,参数一为写入的地址,参数二为写入的缓冲区,参数三为写入的数据长度
void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite);	
//flash读取	
void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead);   		

#endif

main.c:

#define FLASH_ADDR 0x080C0000 	//定义读写地址

//main函数中需要写入就加入写入代码,需要读取就加入读取代码

        //写入数据
		uint16_t flash_write[7];
        flash_write[0] = data1;
		flash_write[1] = data2;
		flash_write[2] = data3;
		flash_write[3] = data4;
		flash_write[4] = data5;
		flash_write[5] = data6;	
		flash_write[6] = data7;
		STMFLASH_Write(FLASH_ADDR,(uint32_t*)flash_write,7);

        //读取数据
        uint16_t flash_read[7];
		STMFLASH_Read(FLASH_ADDR,(uint32_t*)flash_read,7);
	    data1= flash_read[0];
	    data2= flash_read[1];
		data3= flash_read[2];
 		data4= flash_read[3];
		data5= flash_read[4];
		data6= flash_read[5];
		data7= flash_read[6];

文章为新手个人记录学习

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值