简述
STM32F4XX的闪存擦除方式分为两种:扇区擦除(最小单元16K)和整片擦除。在实际应用中,为满足重要信息的存储,需将信息存入FLASH中,针对以上两种擦除方式,扇区擦除更符合实际的需要。
参考手册:
写FLASH操作
经过以上五个步,就可以擦除某个扇区。但是实际运用过程中,一个扇区只存储一个信息或标志,会造成资源严重浪费。现采用缓存的方式,先读取当下扇区的数据,将读取的数据和要写入的数据组合,待擦除后再次写入。
代码片
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);
addrx=WriteAddr;
endaddr=WriteAddr+NumToWrite*4;
if(addrx<0X1FFF0000)
{
while(addrx<endaddr)
{
if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)
{
status=FLASH_EraseSector(GetSector(addrx),VoltageRange_3);
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_Lock();
Printf("Flash status :%d\r\n",status);
}
#define SectorLen 128
void SaveDataToFlash( u32 address, u32 data )
{
FLASH_Status status = FLASH_COMPLETE;
u32 site[SectorLen] = {FreeStart}, FlashBuffer[SectorLen] = {0};
for ( u8 i = 0; i < SectorLen; i ++ )
{
{
FlashBuffer[i] = STMFLASH_ReadWord( site[i] );
site[ i + 1 ] = site[i] + 4;
if ( address == site[i] )
FlashBuffer[i] = data;
}
}
FLASH_Unlock();
FLASH_DataCacheCmd(DISABLE);
status = FLASH_EraseSector( GetSector( address ), VoltageRange_3 );
if ( status == FLASH_COMPLETE )
{
for (u8 i = 0; i < SectorLen; i ++)
{
if ( FLASH_ProgramWord( site[i], FlashBuffer[i] ) != FLASH_COMPLETE )
{
break;
}
}
}
FLASH_DataCacheCmd(ENABLE);
FLASH_Lock();
Printf("Save status = %d\r\n",status);
}
读FLASH操作
STM23F4 的 FLASH 读取是很简单的。例如,我们要从地址 addr,读取一个字(字节为 8位, 半字为 16 位,字为 32 位),可以通过如下的语句读取:data=(vu32)addr;
将 addr 强制转换为 vu32 指针,然后取该指针所指向的地址的值,即得到了 addr 地址的值。
代码片
u32 STMFLASH_ReadWord(u32 faddr)
{
return *(vu32*)faddr;
}
void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)
{
u32 i;
for(i=0;i<NumToRead;i++)
{
pBuffer[i]=STMFLASH_ReadWord(ReadAddr);
ReadAddr+=4;
}
}
调试注意事项
- 在FLASH读写操作时,未使用数据类型(u32),致读到的数据一直为:-1(0xFFFF FFFF 默认值,即该地址写数据失败) ;
- 主存储区<0x0800 0000 ~ 0x080F FFFF>,存储数据地址小于0x0800 0000,存储出错,主控无响应。在写操作时,一定要保证其 Address 有效!
小结:借助串口打印调试,分析问题,数据读写问题不大o( ̄︶ ̄)o。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)