STM32快速复习(十二)FLASH闪存的读写

news2024/11/15 6:56:25

文章目录

  • 一、FLASH是什么?FLASH的结构?
  • 二、使用步骤
    • 1.标准库函数
    • 2.示例函数
  • 总结


一、FLASH是什么?FLASH的结构?

1、FLASH简介

(1)STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程
(2)读写FLASH的用途:
利用程序存储器的剩余空间来保存掉电不丢失的用户数据
通过在程序中编程(IAP),实现程序的自我更新
(3)在线编程(In-Circuit Programming – ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序
(4)在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序

stm32寄存器地址介绍
在这里插入图片描述
闪存模块组织
在这里插入图片描述

在这里插入图片描述
FLASH基本结构
在这里插入图片描述
FLASH解锁

(1)FPEC共有三个键值:
RDPRT键 = 0x000000A5(解除读保护的秘钥)
KEY1 = 0x45670123
KEY2 = 0xCDEF89AB
(2)解锁:
复位后,FPEC被保护,不能写入FLASH_CR
在FLASH_KEYR先写入KEY1,再写入KEY2,解锁
错误的操作序列会在下次复位前锁死FPEC和FLASH_CR
(3)加锁:
设置FLASH_CR中的LOCK位锁住FPEC和FLASH_CR

使用指针访问存储器
(1)使用指针读指定地址下的存储器:
uint16_t Data = *((__IO uint16_t *)(0x08000000));
(2)使用指针写指定地址下的存储器:
*((__IO uint16_t *)(0x08000000)) = 0x1234;
(3)其中:
#define __IO volatile (易变的数据,防止编译器优化)


程序存储器

编程
在这里插入图片描述
在这里插入图片描述
页擦除
在这里插入图片描述
全擦除
在这里插入图片描述
选项字节
(1)选项字节
a.RDP:写入RDPRT键(0x000000A5)后解除读保护
b.USER:配置硬件看门狗和进入停机/待机模式是否产生复位
c.Data0/1:用户可自定义使用
d.WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量)

2)选项字节编程
a.检查FLASH_SR的BSY位,以确认没有其他正在进行的编程操作
b.解锁FLASH_CR的OPTWRE位
c.设置FLASH_CR的OPTPG位为1(即将写入选项字节)
d.写入要编程的半字到指定的地址(指针写入操作)
e.等待BSY位变为0
f.读出写入的地址并验证数据

(3)选项字节擦除
a.检查FLASH_SR的BSY位,以确认没有其他正在进行的闪存操作
b.解锁FLASH_CR的OPTWRE位(选项字节里面有一个单独的解锁)
c.设置FLASH_CR的OPTER位为1(即将擦除选项字节)
d.设置FLASH_CR的STRT位为1(触发芯片,开始干活)
e.等待BSY位变为0
f.读出被擦除的选择字节并做验证

器件电子签名
(1)电子签名(ID号)存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名

(2)闪存容量寄存器:
基地址:0x1FFF F7E0
大小:16位

(3)产品唯一身份标识寄存器:
基地址: 0x1FFF F7E8
大小:96位

二、使用步骤

1.标准库函数

在这里插入图片描述

2.示例函数

代码如下(示例):

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Store.h"
#include "button.h"
 
uint8_t KeyNum;
 
int main(void)
{
	OLED_Init();
	Button_Init();
	Store_Init();//第一次使用时,初始化闪存,把闪存备份的数据加载回SRAM数组,实现SRAM数组上电不丢失
	
	OLED_ShowString(1,1,"Flag:");
	OLED_ShowString(2,1,"Data:");
 
	while(1)
	{
		KeyNum = Button_GetNum();
		
		if(KeyNum ==1)
		{
			Store_Data[1] ++;
			Store_Data[2] +=2;
			Store_Data[3] +=3;
			Store_Data[4] +=4;
			Store_Save();
		}
		if(KeyNum == 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);
	}
}

最底层:MyFLASH层

#include "stm32f10x.h"                  // Device header
 
/*
	读取32位的字
*/
uint32_t MyFLASH_ReadWord(uint32_t Address)//地址必须是32位的
{
	return *((__IO uint32_t *)(Address));
}
	
/*
	读取16位的半字
*/
uint16_t MyFLASH_ReadHalfWord(uint32_t Address)
{
	return *((__IO uint16_t *)(Address));
}
 
/*
	读取8位的字节
*/
uint8_t MyFLASH_ReadByte(uint32_t Address)
{
	return *((__IO uint8_t *)(Address));
}
 
/*
	全擦除
*/
void MyFLASH_EraseAllPages(void)
{
	FLASH_Unlock();//解锁
	FLASH_EraseAllPages();//全擦除
	FLASH_Lock();//锁上
}
 
/*
	页擦除
*/
void MyFLASH_ErasePage(uint32_t PageAddress)
{
	FLASH_Unlock();//解锁
	FLASH_ErasePage(PageAddress);//页擦除
	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
 
uint16_t Store_Data[STORE_COUNT];
 
void Store_Init(void)
{
	if(MyFLASH_ReadHalfWord(STORE_START_ADDRESS) !=0xA5A5)
	{
		MyFLASH_ErasePage(STORE_START_ADDRESS);//擦除最后一页
		MyFLASH_ProgramHalfWord(STORE_START_ADDRESS,0xA5A5);//写入规定的标志位0xA5A5
		for(uint16_t i=1;i<STORE_COUNT;i++)
		{
			MyFLASH_ProgramHalfWord(STORE_START_ADDRESS +i*2,0x0000);//写0
		}
	}
	
	for(uint16_t i=0;i<STORE_COUNT;i++)//在上电的时候,把闪存备份的地址的数据,恢复到SRAM数组里
	{
		Store_Data[i] = MyFLASH_ReadHalfWord(STORE_START_ADDRESS +i*2);//读闪存数据并存到SRAM数组里
	}
 
}
 
/*
	把SRAM的所有内容备份到闪存
*/
void Store_Save(void)
{
	MyFLASH_ErasePage(STORE_START_ADDRESS);//擦除最后一页
	for(uint16_t i=0;i<STORE_COUNT;i++)//在上电的时候,把闪存备份的地址的数据,恢复到SRAM数组里
	{
		MyFLASH_ProgramHalfWord(STORE_START_ADDRESS +i*2,Store_Data[i]);//把SRAM的所有内容备份到闪存的最后一页
	}
}	
 
/*
	把SRAM的所有内容备份到闪存
*/
void Store_Clear(void)
{
	for(uint16_t i=1;i<STORE_COUNT;i++)
	{
		Store_Data[i] = 0x0000;
	}
	Store_Save();//把这个更改更新到闪存里
}

偷个懒,用了别人的图片,还是要自己敲一下代码。才算学会


总结

偷个懒。。。。。。
存在问题
(1)目前闪存的前面部分存储的是程序文件,最后一页存储的是用户数据,如果程序较大,触及到了最后一页,那程序和用户数据存储的位置就冲突了,这时就可以给程序文件限定一个存储范围,不让它分配到后面我们用户数据的空间来
在这里插入图片描述
(2)配置下载选项,擦除扇区,用到多少就擦除多少,下载速度更快
在这里插入图片描述
(3)想知道目前程序编译后占多大空间
全部编译一下
在这里插入图片描述
or
或者双击Target1查看.map文件
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【无标题】Java_Se 数据变量与运算符

标识符、变量、常量、数据类型、运算符、基本数据类型的类型转换等。这些是编程中的“砖块”&#xff0c;是编程的基础。要想开始正式编程&#xff0c;还需要再学“控制语句”&#xff0c;控制语句就像“水泥”&#xff0c;可以把“砖块”粘到一起&#xff0c;最终形成“一座大…

react学习笔记一:react介绍

将view规划成一个个的组件&#xff0c;是一个响应式的声明式的设计。 虚拟dom&#xff0c;减少dom操作。vue的虚拟dom是在react的基础上拓展来的。 单向数据流&#xff1a;是一种数据流动的模式。数据流的方向是有上到下的&#xff0c;在react中主要是从父组件流向子组件。 …

Django后台管理复杂模型

【图书介绍】《Django 5企业级Web应用开发实战&#xff08;视频教学版&#xff09;》_django 5企业级web应用开发实战(视频教学版)-CSDN博客 《Django 5企业级Web应用开发实战&#xff08;视频教学版&#xff09;》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com) Django框架…

C#学习(四)C#连接Mysql实现增删改查

博主刚开始接触C#&#xff0c;本系列为学习记录&#xff0c;如有错误欢迎各位大佬指正&#xff01;期待互相交流&#xff01; 文章目录 一、安装Mysql1.1 启用Mysql1.2 登录Mysql 二、安装Navicat2.1 建立连接2.2 新建数据库2.3 新建表 三、创建Winform实现增、删、改、查3.1 下…

医学数据分析实训 项目七 集成学习--空气质量指标--天气质量分析和预测

项目七&#xff1a;集成学习 实践目的 理解集成学习算法原理&#xff1b;熟悉并掌握常用集成学习算法的使用方法&#xff1b;熟悉模型性能评估的方法&#xff1b;掌握模型优化的方法。 实践平台 操作系统&#xff1a;Windows7及以上Python版本&#xff1a;3.8.x及以上集成开…

ubuntu安装wordpress(基于LNMP环境)

参考链接 Ubuntu安装LNMP 安装步骤 环境需要LNMP环境&#xff0c;如果没有安装可以参考ZATA—LNMP简单安装 在mysql中设置wordpress所用的用户名和密码 #1. 登录mysql mysql -uroot -p #2. 创建wordpress数据库 create database wordpress; #3. 创建新用户user&#xff0c;…

【有啥问啥】深入解析 OpenAI o1 模型家族:推理能力的跃升与应用场景

深入解析 OpenAI o1 模型家族&#xff1a;推理能力的跃升与应用场景 随着人工智能的不断发展&#xff0c;推理能力已经成为影响 AI 系统性能的关键因素。2024 年 9 月 12 日【好家伙&#xff0c;在笔者生日当天&#xff8d;(ー&#xff40;&#xff8d;)搞事情】&#xff0c;O…

腾讯百度阿里华为常见算法面试题TOP100(5):子串、堆

之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 子串 560.和为K的子数组

谷歌云推出全新区块链RPC服务:简化Web3开发

2024年9月&#xff0c;谷歌云&#xff08;Google Cloud&#xff09;宣布推出区块链RPC&#xff08;远程过程调用&#xff09;服务的预览版&#xff0c;进一步表明其支持Web3开发者的承诺。此次发布旨在简化开发者与区块链数据的交互&#xff0c;降低Web3应用开发的技术门槛。这…

制作U盘安装操作系统(启动盘、系统盘、Windows、Linux)

第一种&#xff08;Windows&#xff09; 官网windows制作启动盘 1. 打开Win11下载官网 下载 Windows 11https://www.microsoft.com/zh-cn/software-download/windows11 2. 下载制作操作系统工具 这里不要下载错了 3. 启动工具 选择U盘&#xff0c;选择你的U盘即可&#xf…

[Redis][环境配置]详细讲解

目录 1.安装 && 简单配置2.文件目录说明3.客户端 1.安装 && 简单配置 Ubuntu下&#xff0c;直接使用sudo apt install redis -y即可支持远程连接&#xff1a;修改/etc/redis/redis.conf 将bind 127.0.0.1改为bing 0.0.0.0作为学习用途&#xff0c;可以将prote…

vue3前端开发-小兔鲜超市-本地购物车列表页面的统计计算

vue3前端开发-小兔鲜超市-本地购物车列表页面的统计计算&#xff01;这一次&#xff0c;实现了一些本地购物车列表页面的&#xff0c;简单的计算。 代码如下所示&#xff1a; import { computed, ref } from vue import { defineStore } from pinia export const useCartStor…

新升级|优化航拍/倾斜摄影模型好消息,支持处理多套贴图模型!

【天元轻量化软件】一直在不断地追求进步和完善&#xff0c;以满足更多用户的各种需求。 电脑登录天元官网免费体验&#xff1a;天元轻量化软件官网 本次我们对“智能PBR”功能进行了更新。更新后的“智能PBR”支持带多套贴图的模型进行使用。 本轮更新后&#xff0c;主要受益…

统信服务器操作系统【1050e版】安装手册

统信服务器操作系统1050e版本的安装 文章目录 功能概述一、准备环境二、安装方式介绍安装步骤步骤一:制作启动盘步骤二:系统的安装步骤三:安装引导界面步骤四:图形化界面安装步骤五:选择安装引导程序语言步骤六:进入安装界面步骤七:设置键盘步骤八:设置系统语言步骤九:…

音视频入门基础:AAC专题(8)——FFmpeg源码中计算AAC裸流AVStream的time_base的实现

一、引言 本文讲解FFmpeg源码对AAC裸流行解复用&#xff08;解封装&#xff09;时&#xff0c;其AVStream的time_base是怎样被计算出来的。 二、FFmpeg源码中计算AAC裸流AVStream的time_base的实现 FFmpeg对AAC裸流进行解复用&#xff08;解封装&#xff09;时&#xff0c;其…

Docker 镜像制作(Dockerfile)

1 Dockerfile 概念 Dockerfile 是什么&#xff1f; 镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本&#xff0c;用这个脚本来构建、定制镜像,这个脚本就是 Dockerfile。 Dockerfile 是一个文本文件&a…

CVE-2024-2389 未经身份验证的命令注入

什么是 Progress Flowmon? Progress Flowmon 是一种网络监控和分析工具,可提供对网络流量、性能和安全性的全面洞察。Flowmon 将 Nette PHP 框架用于其 Web 应用程序。 未经身份验证的路由 我们开始在“AllowedModulesDecider.php”文件中枚举未经身份验证的端点,这是一个描…

superset 解决在 mac 电脑上发送 slack 通知的问题

参考文档: https://superset.apache.org/docs/configuration/alerts-reports/ 核心配置: FROM apache/superset:3.1.0USER rootRUN apt-get update && \apt-get install --no-install-recommends -y firefox-esrENV GECKODRIVER_VERSION0.29.0 RUN wget -q https://g…

边缘智能-大模型架构初探

R2Cloud接口 机器人注册 请求和应答 注册是一个简单的 HTTP 接口&#xff0c;根据机器人/用户信息注册&#xff0c;创建一个新机器人。 请求 URL URLhttp://ip/robot/regTypePOSTHTTP Version1.1Content-Typeapplication/json 请求参数 Param含义Rule是否必须缺省roboti…

活动系统开发之采用设计模式与非设计模式的区别-后台功能总结

1、数据库ER图 2、后台功能字段 题目功能字段 数据列表 编号题目名称选项数量状态 1启用0禁用创建时间修改时间保存 题目名称选项集 选项内容是否正确答案 1正确0错误启禁用删除素材图库功能字段 数据列表 编号原文件名称文件类型文件大小加密后文件名文件具体路径上传类型状态…