完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
简述
STM32F4XX的闪存擦除方式分为两种:扇区擦除(最小单元16K)和整片擦除。在实际应用中,为满足重要信息的存储,需将信息存入FLASH中,针对以上两种擦除方式,扇区擦除更符合实际的需要。 参考手册: 写FLASH操作 经过以上五个步,就可以擦除某个扇区。但是实际运用过程中,一个扇区只存储一个信息或标志,会造成资源严重浪费。现采用缓存的方式,先读取当下扇区的数据,将读取的数据和要写入的数据组合,待擦除后再次写入。 代码片 写FLASH操作 /* * WriteAddr: 起始地址 (u32)address 是 4 的整数倍, (u32)data * pBuffer: 数据指针 * NumToWrite:字(u32)数 */ 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) //对非0XFFFF FFFF 的地方,先擦除 { if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//对非0XFFFF FFFF 的地方,先擦除 { status=FLASH_EraseSector(GetSector(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();//上锁 Printf(“Flash status :%drn”,status); } 数据流存储 #define SectorLen 128 //数据长度 128 * 4 = 512 结合实际需要长度调整 /* * (u32)address 是 4 的整数倍, (u32)data * FreeStart( 0x08008000 )~FreeEnd( 0x08010000 ) */ 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 ++ )//读取扇区数据,随即擦除 { // if ( STMFLASH_ReadWord( site[i] ) != 0XFFFFFFFF)//0XFFFFFFFF代表无数据 { FlashBuffer[i] = STMFLASH_ReadWord( site[i] ); site[ i + 1 ] = site[i] + 4; if ( address == site[i] ) FlashBuffer[i] = data; } } FLASH_Unlock();//解锁 FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存 status = FLASH_EraseSector( GetSector( address ), VoltageRange_3 );//VCC=2.7~3.6V之间!! 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擦除结束,开启数据缓存 FLASH_Lock();//上锁 Printf(“Save status = %drn”,status); // return addr; } 读FLASH操作 STM23F4 的 FLASH 读取是很简单的。例如,我们要从地址 addr,读取一个字(字节为 8位, 半字为 16 位,字为 32 位),可以通过如下的语句读取:data=(vu32)addr; 将 addr 强制转换为 vu32 指针,然后取该指针所指向的地址的值,即得到了 addr 地址的值。 代码片 /* *faddr :读地址 *return:对应数据 */ u32 STMFLASH_ReadWord(u32 faddr) { return *(vu32*)faddr; } //读FLASH操作 /* * ReadAddr :起始地址 (u32)address 是 4 的整数倍, (u32)data * 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个字节 } } 调试注意事项 在FLASH读写操作时,未使用数据类型(u32),致读到的数据一直为:-1(0xFFFF FFFF 默认值,即该地址写数据失败) ; 主存储区《0x0800 0000 ~ 0x080F FFFF》,存储数据地址小于0x0800 0000,存储出错,主控无响应。在写操作时,一定要保证其 Address 有效! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1649 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1566 浏览 1 评论
994 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
693 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1613 浏览 2 评论
1871浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
656浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
526浏览 3评论
543浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
515浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 13:20 , Processed in 1.998269 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号