32FLASH闪存

目录

一.FLASH简介

二.代码实现

(1)读写内部FLASH

(2)读取芯片ID


一.FLASH简介

存储器地址要记得累

系统存储器是原厂写入的Bootloader程序(用于串口下载),是不允许修改的

闪存存储器接口是外设,用于管理FLASH

OTA,程序升级

IAP:自定义一个Bootloader在FLASH中,当需要更新程序时,就从程序代码跳转到Bootloader,接收程序更新数据然后覆盖原程序,重新再跳回到原程序

整个升级过程,都可以自主完成

 

 整块擦除,信息块的内容不受影响

FPEC会自动计算反码

 

 在编程过程中,任何读写闪存的操作都会使CPU暂停,会导致中断函数执行的暂停

当闪存保护选项由“保护”变为“未保护”时,会自动执行整片擦除

二.代码实现

void FLASH_Unlock(void);//解锁
void FLASH_Lock(void);//加锁FLASH_Status FLASH_ErasePage(uint32_t Page_Address);//擦除某一页,返回状态
FLASH_Status FLASH_EraseAllPages(void);//全擦除
FLASH_Status FLASH_EraseOptionBytes(void);//擦除选项字节
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
//选项字节的写入
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);自定义的Data0和1
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);写保护
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);读保护
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);用户选项的配置位操作返回的状态
typedef enum
{ FLASH_BUSY = 1,忙FLASH_ERROR_PG,编程错误FLASH_ERROR_WRP,写保护错误FLASH_COMPLETE,FLASH_TIMEOUT等待超时
}FLASH_Status;uint32_t FLASH_GetUserOptionByte(void);//获取用户选项的3个配置位
uint32_t FLASH_GetWriteProtectionOptionByte(void);//获取写保护状态
FlagStatus FLASH_GetReadOutProtectionStatus(void);//获取读保护状态
FlagStatus FLASH_GetPrefetchBufferStatus(void);//获取预取缓冲区状态
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
FLASH_Status FLASH_GetStatus(void);//获取状态
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);//等待上一次操作,等待BUSY为0

(1)读写内部FLASH

MyFLASH.c

#include "stm32f10x.h"                  // Device header
uint32_t MyFLASH_ReadWord(uint32_t Address)
{return *((__IO uint32_t *)(Address));//这里的括号逻辑要规范
}
uint16_t MyFLASH_ReadHalfWord(uint32_t Address)//在32中地址永远是32位的
{return *((__IO uint16_t *)(Address));
}
uint8_t MyFLASH_ReadByte(uint32_t Address)
{return *((__IO uint8_t *)(Address));
}
void MyFLASH_EraseAllPages(void)
{FLASH_Unlock();FLASH_EraseAllPages();FLASH_Lock();
}
void MyFLASH_ErasePages(uint32_t Address)
{FLASH_Unlock();FLASH_ErasePage(Address);FLASH_Lock();
}
void MyFLASH_ProgramWord(uint32_t Address,uint32_t Data)
{FLASH_Unlock();FLASH_ProgramWord(Address,Data);FLASH_Lock();
}
void MyFLASH_ProgramHalfWord(uint32_t Address,uint16_t Data)
{FLASH_Unlock();FLASH_ProgramHalfWord(Address,Data);FLASH_Lock();}

 Store.c

#include "stm32f10x.h"                  // Device header
#include "MyFLASH.h"   
#define STORE_START_ADDRESS     0x0800FC00
#define STORE_COUNT             512
//利用SRAM缓存数组来管理FLASH的最后一页
uint16_t Store_Data[STORE_COUNT];//512个数据每个数据16位,2个字节,对应闪存的一页1024字节
void Store_Init(void)
{uint16_t  i;//下面的地址一定要写对,查了半天if(MyFLASH_ReadHalfWord(STORE_START_ADDRESS) != 0xA5A5)//规定标志位,判断是否第一次读写该页{MyFLASH_ErasePages(STORE_START_ADDRESS);MyFLASH_ProgramHalfWord(STORE_START_ADDRESS,0xA5A5);for(i = 1;i<STORE_COUNT;i++){MyFLASH_ProgramHalfWord(STORE_START_ADDRESS + i*2,0x0000);}}for(i = 0;i<STORE_COUNT;i++){Store_Data[i] = MyFLASH_ReadHalfWord(STORE_START_ADDRESS + i*2);}}
void Store_Save(void)
{uint16_t  i;MyFLASH_ErasePages(STORE_START_ADDRESS);for(i = 0;i<STORE_COUNT;i++){MyFLASH_ProgramHalfWord(STORE_START_ADDRESS + i*2,Store_Data[i]);}	
}
void Store_Clear(void)
{uint16_t  i;for(i = 1;i<STORE_COUNT;i++)//这里不要将标志位清零{Store_Data[i] = 0x0000;}Store_Save();//保证数组和闪存数据一样
}

 main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"  
#include "OLED.h" 
#include "Store.h" 
#include "Key.h" 
uint8_t Num;
int main()
{Key_Init();OLED_Init();Store_Init();OLED_ShowString(1,1,"Flag:");OLED_ShowString(2,1,"Data:");Store_Save();while(1){Num = Keynum();if(Num == 1){Store_Data[1] ++;Store_Data[2] +=2;Store_Data[3] +=3;Store_Data[4] +=4;Store_Save();}else if (Num == 2){Store_Clear();}OLED_ShowHexNum(1,6,Store_Data[0],4);OLED_ShowHexNum(3,1,Store_Data[1],4);OLED_ShowHexNum(3,6,Store_Data[2],4);OLED_ShowHexNum(4,1,Store_Data[3],4);OLED_ShowHexNum(4,6,Store_Data[4],4);}	
}

注:

使用完

要记得断开连接,避免STM32被占用,keil无法下载程序

小端模式存储:低位字节存储在低位地址

OLED有显存,可以保存最后一次显示的内容

页擦除后,程序损坏,也没有办法自动运行

 

前3个数相加得到的就是程序占用闪存的大小

后两个数相加得到的就是占用SRAM的大小

(2)读取芯片ID

#include "stm32f10x.h"                  // Device header
#include "Delay.h"  
#include "OLED.h" 
int main()
{OLED_Init();OLED_ShowString(1,1,"FSIZE:");OLED_ShowHexNum(1,7,*((__IO uint16_t *)(0x1FFFF7E0)),4);//存储器时16位的OLED_ShowString(2,1,"UID:");OLED_ShowHexNum(2,5,*((__IO uint16_t *)(0x1FFFF7E8)),4);//存储器可以以半字,字,字节读取OLED_ShowHexNum(2,11,*((__IO uint16_t *)(0x1FFFF7E8+0x02)),4);//要加上地址偏移OLED_ShowHexNum(3,1,*((__IO uint32_t *)(0x1FFFF7E8+0x04)),8);//OLED_ShowHexNum(4,1,*((__IO uint32_t *)(0x1FFFF7E8+0x08)),8);//while(1){}	
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/261336.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BOSS直聘招聘经验

招聘低端兼职岗位。流量很大&#xff0c;来的人通常实力也不足。 招聘高端兼职岗位。流量不多。来的人通常具备一定实力。 招聘高薪职位&#xff0c;流量一般&#xff0c;会有有实力的勾搭。 招聘低薪职位&#xff0c;流量一般。通常没什么实力。

C#的 Settings.Settings配置文件的使用方法

1、定义 在Settings.settings文件中定义配置字段。把作用范围定义为&#xff1a;User则运行时可更改(用户范围的字段数据更改存储在用户信息中&#xff0c;不在该程序文件中)&#xff0c;Applicatiion则运行时不可更改。可以使用数据网格视图(VS软件的Properties 下面的Setting…

PyCharm - Project Interpreter (项目解释器)

PyCharm - Project Interpreter [项目解释器] References File -> Settings… -> Project: -> Project Interpreter References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

力扣45. 跳跃游戏 II

Problem: 45. 跳跃游戏 II 文章目录 题目描述思路复杂度Code 题目描述 思路 Problem: 55.跳跃游戏 该题在上述的基础上&#xff0c;我们每次先求取当前可跳区间内的最远距离farthest;每当走到当前的区间胃部时&#xff08;end i&#xff09;&#xff1a;跳跃步数加一(jumps)&a…

数据库管理-第153期 Oracle Vector DB AI-05(20240221)

数据库管理153期 2024-02-21 数据库管理-第153期 Oracle Vector DB & AI-05&#xff08;20240221&#xff09;1 Oracle Vector的其他特性示例1&#xff1a;示例2 2 简单使用Oracle Vector环境创建包含Vector数据类型的表插入向量数据 总结 数据库管理-第153期 Oracle Vecto…

2024.2.21 C++QT 作业

思维导图 练习题 1>使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数&#xff0c;将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"…

Ubuntu22部署MySQL5.7详细教程

Ubuntu22部署MySQL5.7详细教程 一、下载MySQL安装包二、安装MySQL三、启动MySQL检查状态登录MySQL 四、开启远程访问功能1、允许其他主机通过root访问数据库2、修改配置文件&#xff0c;允许其他IP通过自定义端口访问 五、使用Navicat连接数据库 默认情况下&#xff0c;Ubuntu2…

星河做市基金会全球DAO社区启动,为数字货币市场注入新活力

2024年的数字货币市场即将迎来一次重要的历史性时刻 — 比特币减半&#xff0c;这四年一次的事件将成为全球数字资产市场的焦点&#xff0c;预示着新一轮的牛市浪潮即将到来。在这个关键时刻&#xff0c;星河做市基金会展现出其作为区块链行业领先市值管理公司的独特魅力。 GA…

解决docker中运行的jar包连不上前端程序

目录 检查端口映射 查看容器的 IP 地址 检查容器网络设置 防火墙和网络策略 前端程序配置 跨域资源共享 (CORS) 日志查看 连接问题通常涉及到网络配置和端口映射。确保你在 Docker 中运行的 JAR 包可以被前端程序访问&#xff0c;可以采取以下步骤来解决问题&#xff1a…

基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022

基于机器学习的青藏高原高寒沼泽湿地蒸散发插补研究_王秀英_2022 摘要关键词 1 材料和方法1.1 研究区概况与数据来源1.2 研究方法 2 结果和分析2.1 蒸散发通量观测数据缺省状况2.2 蒸散发与气象因子的相关性分析2.3 不同气象因子输入组合下各模型算法精度对比2.4 随机森林回归模…

使用Nginx或者Fiddler快速代理调试

1 背景问题 在分析业务系统程序问题时,存在服务系统环境是其它部门或者其它小组搭建或运维的,并且现在微服务时代,服务多且复杂,在个人机器上搭建起如此环境,要么费事费力,要么不具备充足条件。 急需有一种方法或者工具可以快速辅助调试定位分析问题。本文下面介绍代理方…

用于扫描机密的开源解决方案

TruffleHog 最初是在 2016 年独立创作的一个研究工具。当发布它时&#xff0c;没有工具扫描 Git 修订历史记录以获取秘密。我的预感是旧版本的代码中隐藏着很多秘密&#xff0c;但没有工具可以查找它们。 我的预感是对的。该工具迅速流行并变得非常流行。如今&#xff0c;它在…

git使用过的命令记录

目录 git add .git commit --amendgit push -f origin HEAD:mastergit checkout .git stash想把某个pr的修改应用到本地git 撤销&#xff0c;放弃本地修改参考文档 git add . 将本地修改提交到暂存区 git commit --amend 如果本地有修改 就是将修改的东西 追加到上一个pr 如…

喀秋莎画中画怎么设置 喀秋莎画中画视频怎么导出 喀秋莎什么意思 camtasia studio下载

画中画视频&#xff0c;顾名思义&#xff0c;就是在一个视频中有两个画面&#xff0c;游戏解说、微课等类型的视频常常就以画中画的形式出现。作为一款专业的视频编辑软件&#xff0c;使用camtasia可以轻松地制作画中画视频并导出。接下来我将为大家介绍&#xff1a;喀秋莎画中…

使用Templ进行Go模板化

使用Templ在Go项目中高效生成动态内容的指南 动态内容生成是Web开发的一个基本方面。无论您是在构建网站、Web应用程序还是API&#xff0c;根据数据和模板生成动态内容的能力都至关重要。在Go编程世界中&#xff0c;一个名为“Templ”的强大工具简化了这一过程。在这份全面的指…

详细设计文档模版

背景 描述为什么要做这个技术改造&#xff0c;改造后收益是什么。可以是业务背景或者技术背景。 业务需求类此处可以将产品需求文档中的内容放到此处。技术改造类项目记录发起改造的原因&#xff0c;如系统问题、架构升级、bug修复、性能优化等。 现状 描述当前的技术实现的…

MyBatis---初阶

一、MyBatis作用 是一种更简单的操作和读取数据库的工具。 二、MyBatis准备工作 1、引入依赖 2、配置Mybatis(数据库连接信息) 3、定义接口 Mapper注解是MyBatis中用来标识接口为Mapper接口的注解。在MyBatis中&#xff0c;Mapper接口是用来定义SQL映射的接口&#xff0c;通…

phar反序列化原理及利用

phar是什么&#xff1f; phar 是 PHP 的一种归档文件格式&#xff0c;类似于 ZIP 或 TAR 文件&#xff0c;它可以包含多个文件和目录&#xff0c;并且可以像访问普通文件系统一样在 PHP 中进行访问。在php 5.3 或更高版本中默认开启 在php.ini中配置如下时&#xff0c;才能生成…

2024.4.21

多进程实现拷贝 #include <myhead.h> //定义结构体 typedef struct INFO {const char *src_file;const char *dest_file;int mv;int size;}info_t;//获取源文件的大小并且创建目标文件 int size_creat(const char *src_file,const char *dest_file) {//获取源文件的大小…

opengl 学习着色器

一.GLSL 着色器是使用一种叫GLSL的类C语言写成的。GLSL着色器编码顺序&#xff1a;声明版本》定义输入输出》uniform》main函数。每个着色器的入口点是main函数&#xff0c;在main函数中我们处理所有的输入变量&#xff0c;并将结果输出到输出变量中。如下图&#xff1a; #ver…