STM32 内部Flash读写 程序源码 [已验证]
目录
- STM32 内部Flash带缓存读写 程序源码
- 0 Macro
- 1.Flash_Erase
- 2. Flash_Read_Byte
- 3.Flash_Write_NoBuffer
- 4.Flash_Write_WithBuffer
- 5. Test
- 博主热门文章推荐:
STM32 内部Flash带缓存读写 程序源码
由于STM32 系列Flash的Erase操作很多是按Page擦除,如果往Flash写入的数据或余数不够一个整Page,那么该Page其他数据也会被擦除掉。
所以这种情况想保持其他未操作数据不变的话,就要做缓存读写,既将要擦除Page的数据全读出来,与新写入的数据Merge后,再写入。这一块目前ST没有给出Demo,需要现写。
注意到Programming in the Flash memory performed by word or half-page 所以,Write API使用了按Word写入
测试程序使用的单片机为STM32L0系列,PageSize为128B,
Memory map如下:
下面是我以前写的API,首先是相关宏定义:
0 Macro
读写API内部调用的是STM32xx_hal_flash.c中的HAL_FLASH_Program API,如果使用不一样的Hal库,可以直接替换下方的Flash_WriteOneWord宏定义:
#define TRUE 1
#define FALSE 0typedef unsigned char BOOL; /* boolean data */
typedef unsigned char FLAG; /* boolean data */
typedef unsigned char U8BIT; /* unsigned 8 bit data */
typedef unsigned short U16BIT; /* unsigned 16 bit data */
typedef unsigned long U32BIT; /* unsigned 32 bit data */
typedef unsigned long WORD; /* unsigned 32 bit data */#define PAGE_SIZE FLASH_PAGE_SIZE #define Flash_WriteOneWord(a, b) HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, a, b)
#define Flash_WriteOneHalfWord(a, b) HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, a, b)
1.Flash_Erase
Erase主要负责写入之前清空的操作,由Wirte API判断要Erase多少Page
/*****************************************************************************@Name : Flash_Erase@Brief : Erase the whole page by NumtoErase@Param In : U32BIT StartAddr uint16_t PageNumtoErase @Param Out : @Return : TURE for Success, FALSE for FailedHistory :1.Date : Tuesday, June 04, 2018Author : Howard Xue*****************************************************************************/
BOOL Flash_Erase(uint32_t StartAddr, uint16_t PageNumtoErase)
{if(HAL_FLASH_Unlock() != HAL_OK)return FALSE;uint32_t PageError_Tmp = 0;FLASH_EraseInitTypeDef Eras;Eras.NbPages = PageNumtoErase;Eras.PageAddress = StartAddr;Eras.TypeErase = FLASH_TYPEERASE_PAGES;if(HAL_FLASHEx_Erase(&Eras , &PageError_Tmp) != HAL_OK)return FALSE;if(HAL_FLASH_Lock() != HAL_OK)return FALSE;return TRUE;}
2. Flash_Read_Byte
/*****************************************************************************
@Name : Flash_Read_Byte
@Brief : Read Internal Falsh data by address
@Param In : uint32_t StartAddr uint8_t *ReadBufuint32_t NumToRead
@Param Out : uint8_t *ReadBuf
@Return : TURE for Success, FALSE for FailedHistory :1.Date : Tuesday, June 04, 2018Author : Howard Xue*****************************************************************************/
BOOL Flash_Read_Byte(uint32_t StartAddr, uint8_t *ReadBuf, uint32_t NumToRead)
{if(NumToRead== 0)return FALSE;uint32_t DataNum = 0;uint32_t ReadAddress = StartAddr;while(DataNum < NumToRead){*(ReadBuf + DataNum) = *(__IO uint8_t *)ReadAddress++;DataNum++;}return TRUE;
}
写之前要先Erase,并且Unlock,这种方法是NoBuffer形式,既每次写入都会Erase 一个Page,(因为STM32 Erase都是最低以Page为单位,例如我的芯片是128B,不同的芯片FLASH_PAGE_SIZE 不用,直接copy 不需要修改)
3.Flash_Write_NoBuffer
/*****************************************************************************
@Name : Flash_Write_NoBuffer
@Brief : Write Flash without Buffer
@Param In : uint32_t StartAddr uint32_t *pBufferToWriteuint32_t NumToWrite
@Param Out : uint32_t *pBufferToWrite
@Return : TURE for Success, FALSE for FailedHistory :1.Date : Tuesday, June 04, 2018Author : Howard Xue*****************************************************************************/
BOOL Flash_Write_NoBuffer(uint32_t StartAddr, uint32_t *pBufferToWrite, uint32_t NumToWrite)
{uint32_t PageNumtoErase = 1;//defaultuint32_t i;if(NumToWrite == 0)return FALSE;//GetPageNum to eraseif(NumToWrite > FLASH_PAGE_SIZE){PageNumtoErase = NumToWrite/FLASH_PAGE_SIZE + 1; }//Erase whole pageif(Flash_Erase(StartAddr, PageNumtoErase) != TRUE)return FALSE;//4.Write Buffer to Flash, Unlock -> write -> lockif(HAL_FLASH_Unlock() != HAL_OK)return FALSE;for ( i = 0 ; i < (NumToWrite/4) ; i++ ){if(Flash_WriteOneWord(StartAddr + i * sizeof(uint32_t ), *pBufferToWrite) != HAL_OK)return FALSE;pBufferToWrite++;}if(HAL_FLASH_Lock() != HAL_OK)return FALSE;return TRUE;}
4.Flash_Write_WithBuffer
BufferWrite其实就是先根据要写多少数据,算出相应需Erase的page数,之后将这些Page的数据全读出来,与新要写入的数据合并覆盖后,再写入。 这样就实现除了要写入的地址数据,其他的数据不被Erase更改。
注意Wite传入参数如果是U8的需要强制转换成U32
/*****************************************************************************
@Name : Flash_Write_WithBuffer
@Brief : Read Buffer from Flash ,Then Merge New Data and Write
@Param In : uint32_t StartAddr uint32_t *pBufferToWriteuint32_t NumToWrite
@Param Out : uint32_t *pBufferToWrite
@Return : TURE for Success, FALSE for FailedHistory :1.Date : Tuesday, June 04, 2018Author : Howard Xue*****************************************************************************/
BOOL Flash_Write_WithBuffer(uint32_t StartAddr, uint32_t *pBufferToWrite, uint32_t NumToWrite)
{uint8_t PageNumtoErase = 1;//default is erase 1 page.uint32_t i;uint32_t ReadBuffer_Length = 0;
// uint8_t ReadBuffer[FLASH_PAGE_SIZE] = {0};if(NumToWrite == 0)return FALSE;//GetPageNum to eraseif(NumToWrite > FLASH_PAGE_SIZE){PageNumtoErase = NumToWrite/FLASH_PAGE_SIZE + 1; }ReadBuffer_Length = PageNumtoErase*FLASH_PAGE_SIZE;U32BIT *pReadBuffer = (U32BIT *)calloc(1, ReadBuffer_Length);U32BIT *pReadBufferCount = pReadBuffer;//1.Read orginal data from flashFlash_Read_Byte(StartAddr,(U8BIT *)pReadBuffer,ReadBuffer_Length);//2.Merge New Data for Writememcpy(pReadBufferCount,pBufferToWrite,NumToWrite);//3.Erase whole pageif(Flash_Erase(StartAddr, PageNumtoErase) != TRUE)return FALSE;//4.Write Buffer to Flash, Unlock -> write -> lockif(HAL_FLASH_Unlock() != HAL_OK)return FALSE;for ( i = 0 ; i < (ReadBuffer_Length/4) ; i++ ){if(Flash_WriteOneWord(StartAddr + i * sizeof(uint32_t ), *pReadBufferCount) != HAL_OK)return FALSE;pReadBufferCount++;}if(HAL_FLASH_Lock() != HAL_OK)return FALSE;free(pReadBuffer);return TRUE;}
5. Test
Test程序中,先Flash_Write_NoBuffer将Data全部写入Flash,然后更改几个下次要写入的数值,只写入更改的数据,这样FlashBufferWrite就会仅更新更改的数值,其他数值不变(如果不使用BufferWrite,Flash同一Page其他数据都会被Erase)
注意Wite传入参数如果是U8的需要强制转换成U32
void FlashTest()
{U8BIT Data_W[64] = {0xFA,0xFA,0xFE,0xFE,0xFA,0xFA,0xFE,0xFE,0xFA,0xFA,0xFE,0xFE,0xFA,0xFA,0xFE,0xFE,0xFA,0xFA,0xFE,0xFE,0xFA,0xFA,0xFE,0xFE};U8BIT Data_R[64] = {0};U32BIT FLASH_DATAZONE_BASE_ADDR = 0x08028000; //Address for testFlash_Read_Byte(FLASH_DATAZONE_BASE_ADDR, Data_R,sizeof(Data_R));Flash_Write_NoBuffer(FLASH_DATAZONE_BASE_ADDR,(U32BIT *)&Data_W[0],sizeof(Data_W));Flash_Read_Byte(FLASH_DATAZONE_BASE_ADDR, Data_R,sizeof(Data_R));Data_W[0] = 0;Data_W[1] = 1;//Merge new data and write, ohter data will containedFlash_Write_WithBuffer(FLASH_DATAZONE_BASE_ADDR,(U32BIT *)&Data_W[0],4);Flash_Read_Byte(FLASH_DATAZONE_BASE_ADDR, Data_R,sizeof(Data_R));
}
博主热门文章推荐:
一篇读懂系列:
- 一篇读懂无线充电技术(附方案选型及原理分析)
- 一篇读懂:Android/iOS手机如何通过音频接口(耳机孔)与外设通信
- 一篇读懂:Android手机如何通过USB接口与外设通信(附原理分析及方案选型)
LoRa Mesh系列:
- LoRa学习:LoRa关键参数(扩频因子,编码率,带宽)的设定及解释
- LoRa学习:信道占用检测原理(CAD)
- LoRa/FSK 无线频谱波形分析(频谱分析仪测试LoRa/FSK带宽、功率、频率误差等)
网络安全系列:
- ATECC508A芯片开发笔记(一):初识加密芯片
- SHA/HMAC/AES-CBC/CTR 算法执行效率及RAM消耗 测试结果
- 常见加密/签名/哈希算法性能比较 (多平台 AES/DES, DH, ECDSA, RSA等)
- AES加解密效率测试(纯软件AES128/256)–以嵌入式Cortex-M0与M3 平台为例
嵌入式开发系列:
- 嵌入式学习中较好的练手项目和课题整理(附代码资料、学习视频和嵌入式学习规划)
- IAR调试使用技巧汇总:数据断点、CallStack、设置堆栈、查看栈使用和栈深度、Memory、Set Next Statement等
- Linux内核编译配置(Menuconfig)、制作文件系统 详细步骤
- Android底层调用C代码(JNI实现)
- 树莓派到手第一步:上电启动、安装中文字体、虚拟键盘、开启SSH等
- Android/Linux设备有线&无线 双网共存(同时上内、外网)
AI / 机器学习系列:
- AI: 机器学习必须懂的几个术语:Lable、Feature、Model…
- AI:卷积神经网络CNN 解决过拟合的方法 (Overcome Overfitting)
- AI: 什么是机器学习的数据清洗(Data Cleaning)
- AI: 机器学习的模型是如何训练的?(在试错中学习)
- 数据可视化:TensorboardX安装及使用(安装测试+实例演示)
STM32 内部Flash读写 程序源码 [已验证]相关推荐
- 2022新JI卫云域名防红/防封程序源码+已去除授权
正文: 2022新JI卫云域名防红/防封程序源码+已去除授权,JI卫云防红系统,双重跳转,程序非常稳定,生成短链接均支持在QQ_微信内部直接强行打开,也是支持iOS端的. 功能: 程序: wwau.l ...
- 单片机编程php,STC单片机内部FLASH读写程序(最新整理)
<STC单片机内部FLASH读写程序(最新整理)>由会员分享,可在线阅读,更多相关<STC单片机内部FLASH读写程序(最新整理)(6页珍藏版)>请在人人文库网上搜索. 1.S ...
- 跑腿同学校园小程序源码-已测试
介绍: 跑腿同学校园小程序源码-已测试 1:推荐环境:coenots7+wdcp3.2 coenots7+宝塔 win2008+phpstudty2017 php版本gt;= 5.4推荐5.6 2:把 ...
- 读写STM32内部flash读写代码
读写STM32内部flash读写代码 由于老师的要求,所以写了一份读写STM32内部FLASH的代码,这样的话就可以把STM32里面没有用来保存代码段的部分用来存储数据了. 由于<stm32fl ...
- stm32内部Flash读写
文章目录 1.stm32内部flash介绍 2.读写驱动编写 3.源码 上篇文章讲到了STM32来驱动外部flah的操作,flash真是好东西啊,内存大,能存的东西多,这样我们就可以用它来做一些大点的 ...
- 梦想贩卖机v2版本1.0.69无限制版小程序源码{已修复助力和瀑布流问题}
梦想贩卖机v2版本1.0.69无限制小程序源码,已修复市面上助力和瀑布流不能用的问题. 另带百度网盘转存插件,音频插件,视频插件. 上传即可使用. 经测试一切功能均可使用. 支持挂载小程序跳转.H5跳 ...
- 云开发口袋工具箱微信小程序源码(已更新)
介绍: 这是一款云开发口袋工具箱微信小程序源码,,该版本的口袋工具箱涵盖了13个功能 分别为圣诞帽头像生成.二维码生成.日语50音图.汉字拼音查询.计算器.程序员黄历.娱乐摇骰子. 身材计算.所在地天 ...
- STM32内部Flash读写问题
STM32Flash读写之Flash调试技巧 文章目录 1.先熟悉所用MCU的Flash存储大小以及扇区地址 2.Flsah写之前为什么要先擦除 3.Flash擦除长时间占用CPU 4.实测Flash ...
- 宠物合成网站源码_ThinkPHP区块链宠物养成合成类游戏APP陀螺世界程序源码 已优化...
平台声明:本商品由平台商家发布,如果本商品源码侵犯了您的利益请在上方价格右侧或联系平台客服举报. 运营版全新恐龙有钱app源码/陀螺世界运营版本/旅行世界养成宠物合成/区块链宠物----------- ...
最新文章
- android选择下拉框的默认值,如何在Android中将默认值设置为微调器下拉列表?
- ACM入门之【拓扑排序】
- 常用ms-dos命令
- 在线代码编辑器---codemirror插件
- Servlet笔记2-文件上传
- collection 多态 会自动转型为子类 继承多态需要显示转型
- Windows下运行linux桌面程序
- 基于flask框架的高校舆情分析系统
- 对话机器人技术简介:问答系统、对话系统与聊天机器人
- 统计学 参数估计 之 总体均值的估计
- struct2json API 文档,s2j库(c语言与json互转)
- 动手学深度学习第一次打卡
- 2021年「博客之星」参赛博主:尔嵘
- K8S 多 Maser 集群架构和 Dashboard UI 的二进制部署
- 1--STM32 ADC1与ADC2 16通道DMA采集笔记
- 战双帕弥什登入显示服务器错误,战双帕弥什渠道账号登录失败/安装失败/提示新版本/卡顿闪退FAQ大全[多图]...
- C/C++cmath库常用函数
- uboot-Makefile学习(4)
- 解决在线视频(如b站等)中没有IDM下载浮动条问题
- 王汕7.10期货原油、外汇黄金指导、黄金走势分析及下周操作建议
热门文章
- 原生小程序实现手风琴
- 男人帮所有手机铃声下载|左永邦手机铃声下载,顾小白手机铃声下载,米琪手机铃声下载,艾米手机铃声下载...
- 简单的java文档扫描器
- 2.2 法力池的创建和视觉特效———自制卡牌游戏之旅
- 搞笑新闻联播之老公岗位制度(中)铃声 搞笑新闻联播之老公岗...
- 德州学院大学计算机,德州学院 计算机系 李天志老师简介 联系方式 手机电话 邮箱...
- 神器——写Markdown来画流程图、时序图
- 软考中级 真题 2015年上半年 信息系统管理工程师 应用技术
- J9数字科普:Web3.0世界中的J9NFT:仍在发展但未来可期
- 你对本岗位的认识PHP,本岗位工作认识