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)
	{

		
	}	
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

css4浮动+清除浮动

浮动 一.常见网页布局1.三种布局方式2.布局准则 二.浮动&#xff08;float&#xff09;1.好处2.概念3.三大特性4.使用5.常见网页布局模板6.注意点 三.清除浮动1.why2.本质3.语法4.四种way&#xff08;后三个都是给父级添加&#xff09;清除浮动总结 一.常见网页布局 1.三种布局…

[java基础揉碎]this

引出this: 什么是this: java虚拟机会给每个对象分配 this&#xff0c;代表当前对象。 这里的this就是new出来的这个对象 this的本质: this是个引用在堆中指向它自己: this的细节: 访问成员方法: 访问构造器:

DPDK应该如何入门学习?

01 写在前面 我的读者当中应该有一部分人是做 DPDK 相关的&#xff0c;我自己虽然现在已经不做 DPDK 了&#xff0c;但对这块仍然有兴趣&#xff0c;今天这篇文章就来总结下 DPDK 的技术栈。注意&#xff1a;这篇文章是小白文&#xff0c;不适合大神哦。 文章从 DPDK 的产生背…

实战打靶集锦-025-HackInOS

文章目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查5. 提权5.1 枚举系统信息5.2 探索一下passwd5.3 枚举可执行文件5.4 查看capabilities位5.5 目录探索5.6 枚举定时任务5.7 Linpeas提权 靶机地址&#xff1a;https://download.vulnhub.com/hackinos/HackInOS.ova 1. 主机…

【PyTorch][chapter 17][李宏毅深度学习]【无监督学习][ Auto-encoder]

前言&#xff1a; 本篇重点介绍AE&#xff08;Auto-Encoder&#xff09; 自编码器。这是深度学习的一个核心模型. 自编码网络是一种基于无监督学习方法的生成类模型,自编码最大特征输出等于输入 Yann LeCun&Bengio, Hinton 对无监督学习的看法. 目录&#xff1a; AE 模型原…

华为笔记本原厂系统镜像恢复安装教程方法

1.安装方法有两种&#xff0c;一种是用PE安装&#xff0c;一种是华为工厂包安装&#xff08;安装完成自带F10智能还原&#xff09; 若没有原装系统文件&#xff0c;请在这里远程恢复安装&#xff1a;https://pan.baidu.com/s/166gtt2okmMmuPUL1Fo3Gpg?pwdm64f 提取码:m64f …

跳表是一种什么样的数据结构

跳表是有序集合的底层数据结构&#xff0c;它其实是链表的一种进化体。正常链表是一个接着一个用指针连起来的&#xff0c;但这样查找效率低只有O(n)&#xff0c;为了解决这个问题&#xff0c;提出了跳表&#xff0c;实际上就是增加了高级索引。朴素的跳表指针是单向的并且元素…

关于Linux中使用退格键出现^H的问题解决

关于Linux中使用退格键出现^H的问题解决 今天在Linux下执行脚本和监听端口的输入时候&#xff0c;不小心输错内容想要删除用退格键发现变成了^H&#xff0c;从网上查了资料并且实际应用了一下&#xff08;我的虚拟机是CentOS7&#xff09;。 使用ctrl退格键即可成功删除内容 …

mysql 锁详解

目录 前言 一、全局锁 二、表级锁 三、行锁 前言 为什么要设计锁&#xff0c;锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步&#xff0c;避免因并发造成了数据错误(数据覆盖)。可见锁的重要性&#xff0c;并不是所有的数据库都有锁。比如Redis&a…

CSB ---> (XXE)XML基础

本来今天想更一下CSbeacon上线多层的内网机器的&#xff0c;但是刚好今天是年后的第一节课&#xff0c;讲的是XXE的基础&#xff0c;那就来先盘一下基础&#xff01;&#xff01; 1.XXE XXE全称是XML External Entity即xml外部实体注入攻击&#xff01;其后果会导致用户…

【深入理解设计模式】 工厂设计模式

工厂设计模式 工厂设计模式是一种创建型设计模式&#xff0c;它提供了一种在不指定具体类的情况下创建对象的接口。在工厂设计模式中&#xff0c;我们定义一个创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 工厂设计模式的目…

锗化硅(SiGe)和硅(Si)之间的各向同性和选择性蚀刻机制

引言 目前&#xff0c;硅的电气和热性能在微电子技术领域中应用广泛。锗化硅&#xff08;SiGe&#xff09;合金的使用频率越来越高&#xff0c;在互补金属氧化物半导体技术中&#xff0c;英思特通过使用SON结构以及进行各向同性刻蚀&#xff0c;将该工艺扩展到对Si进行Si选择性…

angular-引用本地json文件

angular-引用json文件&#xff0c;本地模拟数据时使用 在assets目录下存放json文件 大佬们的说法是&#xff1a;angular配置限定了资源文件的所在地&#xff08;就是assets的路径&#xff09;&#xff0c;放在其他文件夹中&#xff0c;angular在编译过程中会忽略&#xff0c;会…

Spring Security学习(六)——配置多个Provider(存在两种认证规则)

前言 《Spring Security学习&#xff08;五&#xff09;——账号密码的存取》一文已经能满足一般应用的情况。但实际商业应用也会存在如下的情况&#xff1a;用户提交的账号密码&#xff0c;能在本地的保存的账号密码匹配上&#xff0c;或者能在远端服务认证中匹配上&#xff…

ubuntu22.04@Jetson Orin Nano之CSI IMX219安装

ubuntu22.04Jetson Orin Nano之CSI IMX219安装 1. 源由2. 安装2.1 硬件安装2.2 软件配置2.3 新增摄像头 3. 效果4. 参考资料 1. 源由 折腾半天时间&#xff0c;捣鼓这个套装摄像头(IMX219)的安装&#xff0c;死活就是没有这个设备。世界总是这么小&#xff0c;看看遇到问题的大…

SpringCloud-Gateway网关的使用

本文介绍如何再 SpringCloud 项目中引入 Gateway 网关并完成网关服务的调用。Gateway 网关是一个在微服务架构中起到入口和路由控制的关键组件。它负责处理客户端请求&#xff0c;进行路由决策&#xff0c;并将请求转发到相应的微服务。Gateway 网关还可以实现负载均衡、安全认…

代码随想录Leetcode 343. 整数拆分

题目&#xff1a; 代码(首刷看解析 2024年2月21日&#xff09;&#xff1a; dp[i]表示i所能拆分的最大乘积&#xff0c;则dp[i] 与dp[i - 1]的递推公式是&#xff1a; max( 1~n * dp[n ~ 1]) class Solution { public:int integerBreak(int n) {vector<int> dp(n 1);dp…

[ai笔记11] 论ai韭菜的自我修养

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵学习ai以及观点分享的第11篇内容&#xff01; 上班之后时间确实少了许多&#xff0c;但是最近也没闲着&#xff0c;关于ai的学习一直在探索两个部分&#xff0c;一个是看那本有名的书《这就是ChatGPT》&#xff0c;另外一个则…

YOLOv5代码解读[02] models/yolov5l.yaml文件解析

文章目录 YOLOv5代码解读[02] models/yolov5l.yaml文件解析yolov5l.yaml文件检测头1--->耦合头检测头2--->解耦头检测头3--->ASFF检测头Model类解析parse_model函数 YOLOv5代码解读[02] models/yolov5l.yaml文件解析 yolov5l.yaml文件 # YOLOv5 &#x1f680; by Ult…

PotPlayer+Alist挂载并播放网盘视频

文章目录 说明技术WebDAVPotPlayer 操作步骤一&#xff1a;Alist开启WebDAV代理二&#xff1a;PotPlayer连接Alist 说明 Alist网页端播放视频受限&#xff0c;主要是文件大于20MB&#xff0c;由于官方限制&#xff0c;无法播放需要使用user-agent修改插件&#xff0c;设置百度…