完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近尝试了一下对32的内置flash进行读写,众所周知,芯片的flash是用来存放代码指令和变量的,其中的数据即使掉电也不会丢失。而stm32的flash之大,对于初学者的小打小闹完全不用担心不够用的情况。
因此,在需要保存一些芯片掉电之后依旧需要保存的数据(数据量不是特别大)时,运用内置flash的空闲部分可以为我们省去一颗eeprom或外置flash的花销。 知识总结: 1.flash的写入之前需要先擦除,且擦除是直接擦除一页(2KBytes),整个流程为 (1)解锁flash(2)擦除一页或多页(3)写数据(4)锁定flash 2.flash正常写入一次是16bit 3.flash的地址从0x08000000开始,存储代码指令与变量。所以在用户自己写flash时,要注意不要把代码指令与变量给覆盖了。查看编译过的代码使用了多少内存,可在Keil中双击工程名查看*.map文件 基地址加上Size就是代码指令与变量占用的空间。在写入用户数据时,要避开这些地方。 以下是基于正点原子库函数的flash读写代码。在STM32F103RCT6测试通过。可以直接复制使用,好用请为博客点个赞! flash.h: #ifndef _FLASH_H #define _FLASH_H #include "stm32f10x.h" extern uint32_t Flash_EraseWriteOnePage(uint32_t WRITE_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress); extern void Flash_ReadOnePage(uint32_t READ_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress); #endif flash.c / //Author: Read Air //Version: 1.0 //Date:2019/4/18 / #include "flash.h" #include "stm32f10x.h" /// //WRITE_START_ADDR -- 开始写的地址 //SizeOf_u32 -- 要写入的32位(双字)的数量 //DataAddress -- 等待被写入的数据数组(32位的) //返回值 -- 出现擦除失败故障返回写入地址,正常返回0 /// uint32_t Flash_EraseWriteOnePage(uint32_t WRITE_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress) { char EraseCounter = 0; static FLASH_Status FLASHStatus; uint32_t Address; u16 Remain_u32 = SizeOf_u32; u8 err_time=0; /* 解锁 */ FLASH_Unlock(); /* 清空所有标志位 */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); /* 擦除一页*/ FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR); /* 尝试擦除*/ while((FLASHStatus != FLASH_COMPLETE)&&(err_time<5)) { FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR); err_time++; } /* 擦除失败*/ if (err_time >= 5) return WRITE_START_ADDR; /* 向内部 FLASH 写入数据 */ Address = WRITE_START_ADDR; while ((Remain_u32 > 0) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramWord(Address, DataAddress[SizeOf_u32-Remain_u32]); Address = Address + 4; Remain_u32--; } /* 锁定*/ FLASH_Lock(); return 0; } /// //READ_START_ADDR -- 开始写的地址 //SizeOf_u32 -- 要读出的32位(双字)的数量 //DataAddress -- 等待被读出的数据数组(32位的) /// void Flash_ReadOnePage(uint32_t READ_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress) { uint32_t Address; u16 Remain_u32 = SizeOf_u32; /* 检查写入的数据是否正确 */ Address = READ_START_ADDR; while ((Remain_u32 > 0)) { DataAddress[SizeOf_u32-Remain_u32] = (*(__IO uint32_t*) Address); Address += 4; Remain_u32--; } } //注意事项: //1、对flash进行写入操作,一定要遵循“先擦除,后写入”的原则 //2、注意到stm32内置flash的擦除操作都是以页为单位进行,而写入操作则必须以16位半字宽度数据为单位,允许跨页写,尝试写入非16位半字数据将导致stm32内部总线错误。 //3、进行stm32的内置flash编程操作时(写或擦除),必须打开内部的RC振荡器(HSI) //4、注意stm32的内置flash最多只有10万次重复擦写的生命周期,谨记切勿在程序中放任死循环对flash进行持续地重复擦写。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1758 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1053 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1931浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
721浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
563浏览 3评论
588浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
548浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 21:07 , Processed in 0.812915 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号