STM32F429VET6的FLASH空间: 基地址=0X8000000 大小=0X80000
擦除时要按扇区擦除,
扇区地址,
//FLASH起始地址
#define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址
//FLASH 扇区的起始地址
#define ADDR_FLASH_SECTOR_0 ((u32)0x08000000) //扇区0起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_1 ((u32)0x08004000) //扇区1起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_2 ((u32)0x08008000) //扇区2起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_3 ((u32)0x0800C000) //扇区3起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_4 ((u32)0x08010000) //扇区4起始地址, 64 Kbytes
#define ADDR_FLASH_SECTOR_5 ((u32)0x08020000) //扇区5起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_6 ((u32)0x08040000) //扇区6起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_7 ((u32)0x08060000) //扇区7起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_8 ((u32)0x08080000) //扇区8起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_9 ((u32)0x080A0000) //扇区9起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_10 ((u32)0x080C0000) //扇区10起始地址,128 Kbytes
#define ADDR_FLASH_SECTOR_11 ((u32)0x080E0000) //扇区11起始地址,128 Kbytes
//获取某个地址所在的flash扇区
//addr:flash地址
//返回值:0~11,即addr所在的扇区
uint16_t STMFLASH_GetFlashSector(u32 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;
//STM32F429VET6下面的空间没有用到
// 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;
}
读写函数,字读写(4字节读写)
//从指定地址开始写入指定长度的数据
//特别注意:因为STM32F4的扇区实在太大,没办法本地保存扇区数据,所以本函数
// 写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
// 写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
// 没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写.
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
{
FLASH_Status status = FLASH_COMPLETE;
u32 addrx=0;
u32 endaddr=0;
if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4) return; //非法地址
FLASH_Unlock(); //解锁
FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存
addrx=WriteAddr; //写入的起始地址
endaddr=WriteAddr+NumToWrite*4; //写入的结束地址
if(addrx<0X1FFF0000) //只有主存储区,才需要执行擦除操作!!
{
while(addrx<endaddr) //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
{
if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
{
status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之间!!
if(status!=FLASH_COMPLETE)break; //发生错误了
}else addrx+=4;
}
}
if(status==FLASH_COMPLETE)
{
while(WriteAddr<endaddr)//写数据
{
if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//写入数据
{
break; //写入异常
}
WriteAddr+=4;
pBuffer++;
}
}
FLASH_DataCacheCmd(ENABLE); //FLASH擦除结束,开启数据缓存
FLASH_Lock();//上锁
}
//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToRead:字(4位)数
void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)
{
u32 i;
for(i=0;i<NumToRead;i++)
{
pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.
ReadAddr+=4;//偏移4个字节.
}
}
MAIN函数(字读写示例)
//要写入到STM32 FLASH的字符串数组
u32 TEXT_Buffer[]={0x5D,0x9e,0xf7,0x7d,0XAA,0XBB,0XCC,0XDD};
#define FLASH_SAVE_ADDR 0X0807C004 //设置FLASH 保存地址(必须为偶数,且所在扇区,要大于本代码所占用到的扇区.
int main(void)
{
u32 datatemp[20];
//写入数据 写入8个字
STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)TEXT_Buffer,8);
Delay(100); //延时100MS
//读出数据 读出8个字
STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)datatemp,8);
Delay(100); //延时100MS
while(1)
{
GPIOB->ODR^=GPIO_Pin_3; //RUN-led指示灯
Delay(1000); //延时1000mS
}
}