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];
文章为新手个人记录学习