STM32F412应用开发笔记之六:使用片上Flash存储参数
我们的项目中需要保存一些系统配置参数,这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能。这就需要考虑这些参数保存的问题。将这类数据存在指定的位置,需要修改时直接修改存储位置的数值,需要使用时则直接读取,会是一种方便的做法。考虑到这些数据量比较少,使用专门的存储单元既不经济,也没有必要,恰好有些MCU拥有比较大的FLASH,使用少量来存储这些参数则既方便有经济。STM32F4的Flash架构如下:

这次NUCLEO-F412ZG测试板上的STM32F412ZG拥有1M的Flash,所以我们可以试试将参数保存到其片上Flash中。其Flash的组织模式如下:

根据上面的Flash组织模式,我们可以根据自己的使用方便来作相应的定义。从Sector5到Sector11大小都是128K,所以我们做如下宏定义:
#define SECTOR_SIZE 1024*128 //字节
虽然ST的库函数比较全面,但都是基本操作,为了使用方面,根据我们自己的需要对其进行再次封装。
对于读操作相对比较简单,内置闪存模块可以在通用地址空间直接寻址,就像读取变量一样。
//从指定地址开始读取多个数据
void FLASH_ReadMoreData(uint32_t startAddress,uint16_t *readData,uint16_t countToRead)
{
uint16_t dataIndex;
for(dataIndex=0;dataIndex<countToRead;dataIndex++)
{
readData[dataIndex]=FLASH_ReadHalfWord(startAddress+dataIndex*2);
}
}
//读取指定地址的半字(16位数据)
uint16_t FLASH_ReadHalfWord(uint32_t address)
{
return *(__IO uint16_t*)address;
}
//读取指定地址的全字(32位数据)
uint32_t FLASH_ReadWord(uint32_t address)
{
uint32_t temp1,temp2;
temp1=*(__IO uint16_t*)address;
temp2=*(__IO uint16_t*)(address+2);
return (temp2<<16)+temp1;
}
对于写操作相对来说要复杂得多,写操作包括对用户数据的写入和擦除。为了防止误操作还有写保护锁。但这些基本的操作ST的库函数已经为我们写好了,我们只需要调用即可。
STM32复位后,FPEC模块是被保护的,只有在写保护被解除后,我们才能操作相关寄存器。STM32闪存的编程每次必须写入16位,任何不是半字的操作都会造成错误。如下图是Flash写的过程:

STM32的FLASH在编程的时候,也必须要求其写入地址的FLASH是被擦除了的(也就是其值必须是0XFFFF),否则无法写入。Flash的擦除要求必须整页擦除,所以也必须整页写入,否则可能会丢失数据。如下图是Flash页擦除过程:

如下为Flash全擦除过程,

根据以上图示我们便写数据写入函数如下:
//从指定地址开始写入多个数据
void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite)
{
if(startAddress<FLASH_BASE||((startAddress+countToWrite*2)>=(FLASH_BASE+1024*FLASH_SIZE)))
{
return;//非法地址
}
FLASH_Unlock(); //解锁写保护
uint32_t offsetAddress=startAddress-FLASH_BASE; //计算去掉0X08000000后的实际偏移地址
uint32_t sectorPosition=offsetAddress/SECTOR_SIZE; //计算扇区地址,
uint32_t sectorStartAddress=sectorPosition*SECTOR_SIZE+FLASH_BASE; //对应扇区的首地址
FLASH_ErasePage(sectorStartAddress);//擦除这个扇区
uint16_t dataIndex;
for(dataIndex=0;dataIndex<countToWrite;dataIndex++)
{
FLASH_ProgramHalfWord(startAddress+dataIndex*2,writeData[dataIndex]);
}
FLASH_Lock();//上锁写保护
}
在擦除之前应该将页面上的数据读取出来与要写入的数据合并,待擦除后再写入,但这样数据量很大,所以考虑到是少量数据存储,所以每次都将全部数据同时写入,简化操作,也减少数据处理量。经测试以上程序写入和读出数据均正确,可以实现内部Flash的读写操作。
参考了ST的编程手册PM0081——STM32F40xxx 和 STM32F41xxx Flash编程手册。
STM32F412应用开发笔记之六:使用片上Flash存储参数的更多相关文章
- STM32F412应用开发笔记之七:片上ADC的应用测试
在我们的应用项目中需要采集一些模拟量,这些量使用MCU自带的ADC就可以满足要求.在NUCLEO-F412ZG实验板上的STM32F412ZG有一个16通道的ADC,我们试验用它采集几个数据. 在NU ...
- wechat开发笔记之1.线上环境搭建与测试
Wechat开发笔记 线上环境搭建: 申请一个wechat公众平台. 手机个人微信可以用webwechat来测试. Website:https://web.weixin.qq.com/ 手机客户端扫一 ...
- STM32F412应用开发笔记之十:多组分气体分析仪设计验证
本次将NUCLEO-F412ZG应用于我们的多组分气体分析仪的实现试验,从整体上测试实际项目的应用情况. 一.项目概述 多组分气体分析仪是我公司近期研发的三个主要产品之一.采用模块化设计,可增减配置, ...
- STM32F412应用开发笔记之一:初识NUCLEO-F412ZG
今天终于收到了期待已久的NUCLEO-F412ZG,感谢电子发烧友论坛! 近几年来基本都是在STM32平台上做一些设计开发工作.STM32F103.STM32F107.STM32F429等都应用过,但 ...
- STM32F412应用开发笔记之五:结合W5500实现以太网通讯
因实际使用需求我们测试一下网络通讯,在NUCLEO-F412ZG测试板上没有以太网部分,我们选择外接一个W5500的实验板.W5500支持SPI接口通讯,DC3.3V供源.而NUCLEO-F412ZG ...
- STM32F412应用开发笔记之三:SPI总线通讯与AD采集
本次我们在NUCLEO-F412ZG试验模拟量输入采集.我们的模拟量输入采用ADI公司的AD7705,是一片16位两路差分输入的AD采集芯片.具有SPI接口,我们将采用SPI接口与AD7705通讯.两 ...
- STM32F412应用开发笔记之二:基本GPIO控制
NUCLEO-F412ZG板子上的元器件并没有完全焊接,除去ST-LINK部分和电源部分后,还有用一个USB主机接口,三个LED灯和两个按钮,不过很多功能引脚都已经引到了插针.查看原理图可发现,由原理 ...
- STM32F412应用开发笔记之九:移植FreeRTOS到F412ZG平台
在开发实际应用系统时,我们经常需要考虑数据的实时性和多任务,嵌入式实时操作系统的出现为实现这一目的提供了很好的助力.FreeRTOS是近年来比较流行的嵌入式实时操作系统,而且是开源免费的,STM32C ...
- STM32F412应用开发笔记之四:与远红外炭氢传感器通讯
远红外炭氢传感器是在多组分气体传感器中用来检测甲烷和丙烷浓度的,采用单总线串行通讯,TTL电平.所以我们需要用到UART口来实现与远红外炭氢传感器的通讯. 远红外传感器就是这个样子的: 再来一张进气和 ...
随机推荐
- HTML学习笔记——标签
最近开始学习前端的一些知识,了解了一下Html和CSS. HTML:是网页内容的载体,它负责的是网页的内涵,也就是网页要呈现的内容,包括了图片,视频还有文字.是网页要加载的东西: CSS:是样式表现, ...
- 【白话设计模式四】单例模式(Singleton)
转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...
- SpringCloud: 服务发现
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #e4af0a } sp ...
- GStreamer 记录
GStreamer 是一个新的多媒体框架,大大简化了多媒体工具的开发流程,比如,这里有一个 IBM 的文档,介绍了一个 MP3 播放器. http://www.ibm.com/developerwor ...
- AngularJs ng-repeat限制循环次数
重复数组:<ul ng-init='name=[1,2,3,3]'> <li ng-repeat="name in name track by $index"&g ...
- mysql表单输入数据出现中文乱码解决方法
MySQL会出现中文乱码的原因在于1.server本身设定问题,一般来说是latin1 2.建库建表时没有制定编码格式. 解决方法: 1.建库的时候 CREATE DATABASE test CHAR ...
- PHP优化小建议
PHP优化小建议 1 .. foreach 效率更高,尽量用 foreach 代替 while 和 for 循环 2 ..循环内部不要声明变量,尤其是对象这样的变量 3 ..在多重嵌套循环中,如有可能 ...
- MyBatis Cache配置
@(MyBatis)[Cache] MyBatis Cache配置 MyBatis提供了一级缓存和二级缓存 配置 全局配置 配置 说明 默认值 可选值 cacheEnabled 全局缓存的开关 tru ...
- 简单的RPC原型与实现原理
存在的问题 客户端硬编码服务端的地址 引入注册中心,方便服务的注册与发现 注册中心记录的信息:服务地址列表&服务节点权重 Zookeeper节点类型 临时节点:客户端.. 服务注销: tomc ...
- Excel—分离中英文字符
1.如下图: 2.提取中文字符为: 3.提取应为字符为: 4.说明: 该方法的原理利用了LENB和LEN计算方法的不同,LEN计算字符数,中英文都算作一个字符:LENB计算字节数,中文算两个字节,英文 ...