当前位置: 首页 > news >正文

初学stm32 --- flash模仿eeprom

目录

STM32内部FLASH简介

 内部FLASH构成(F1)

FLASH读写过程(F1)

闪存的读取

闪存的写入

内部FLASH构成(F4 / F7 / H7)

 FLASH读写过程(F4 / F7 / H7)

闪存的读取 

闪存的写入

FLASH接口寄存器(写入 & 擦除相关)

FLASH相关HAL库函数简介(F1 / F4 / F7 / H7)

FLASH相关结构体:FLASH_EraseInitTypeDef

F103ZET6 stmflash_write思路

可操作的地址怎么确定?


STM32内部FLASH简介

        在STM32芯片内部有一个FLASH存储器,主要用于存储代码。

 内部FLASH构成(F1)

        内部FLASH主要由三部分组成:主存储器、信息块、闪存存储器接口寄存器。

主存储器:

        地址范围为0x0800 0000 ~ 0x0807 FFFF,分为256页,每页2KB(小/中容量为1K)。

        当BOOT0接地,系统将从0x0800 0000地址处开始读取代码(从主存储器启动)

信息块:

        系统存储大小为2KB,用来存储ST自带的启动程序,用来串口下载代码。

        选项字节大小为16B,一般用于设置内存的写保护、读保护

        当BOOT0VCCBOOT1GND (串口下载程序) ,系统运行的就是这部分代码

FLASH读写过程(F1)

  FLASH的核心操作就是

          FLASH的物理特性:只能写0,不能写1,写1擦除

闪存的读取

        直接在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容并得到相对应的数据。

        CPU运行速度比FLASH快得多,STM32F103FLASH最快访问速度≤24MHzCPU频率超过这个速度,得加入等待时间,否则读写FLASH可能出错,导致死机等情况。

        正确设置好等待周期后,利用指针读取数据。

        从地址addr,读取数据(字节为8位,半字为16位,字为32位)

                data = *(volatile uint8_t *)addr;  /* 读取一个字节数据 */

                data = *(volatile uint16_t *)addr;  /* 读取一个半字数据 */

                data = *(volatile uint32_t *)addr;  /* 读取一个字数据 */

        将addr强制转换为uintx_t指针,然后取该指针所指向地址的值,即可获得addr地址的数据。

        注意: 在进行写或擦除操作时,不能进行代码或数据的读取操作。

     

闪存的写入

        闪存编程是由FPEC(闪存编程和擦除控制器)模块处理的。

        写操作有四步:解锁 à 擦除 à 写数据 à 上锁

解锁:将两个特定的解锁序列号(KEY1:0x45670123 KEY2:0xCDEF89AB依次写入FLASH_KEYR

擦除:FLASH物理特性(只能写0,不能写1),所以写FLASH之前需要擦除,将要写入的区域变为0xFFFF。擦除操作分为:页擦除和批量擦除

写数据:擦除完成,可以向FLASH写数据,每次只能16位方式写入

上锁:写入数据完成,需要设置FLASH_CR[LOCK]1,重新上锁,以防数据不小心被修改。

 

内部FLASH构成(F4 / F7 / H7)

        内部FLASH主要由四部分组成:主存储器、系统存储器、OPT区域和选项字节。

        闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制机构。

         注意:对于H7来说,在Bank1内部有2KB大小的用户选项字节,不过没有映射到内存地址上,可通过FLASH相关寄存器访问。

        STM32F7的FLASH访问路径有两条:AXIMITCM,对应不同的地址映射。

F767 Bank1M闪存组织结构(默认)双Bank详看《STM32F7xx参考手册

 

 FLASH读写过程(F4 / F7 / H7)

        对FLASH的核心操作就是

        FLASH的物理特性:只能写0,不能写1,写1擦除

闪存的读取 

        正确设置好等待周期后,利用指针读取数据。

        从地址addr,读取数据(字节为8位,半字为16位,字为32位)

                data = *(volatile uint8_t *)addr;  /* 读取一个字节数据 */

                data = *(volatile uint16_t *)addr;  /* 读取一个半字数据 */

                data = *(volatile uint32_t *)addr;  /* 读取一个字数据 */

        将addr强制转换为uintx_t指针,然后取该指针所指向地址的值,即可获得addr地址的数据。

        注意: 在进行写或擦除操作时,不能进行代码或数据的读取操作。

        

闪存的写入

        STM32F4/F7/H7 FLASH进行写操作或擦除,电源电压会影响数据的最大操作位数

        最大操作位数会影响擦除和写入的速度。 

        开发板使用的电压是3.3VPSIZE设置10,即32并行位数。擦除或者写入都以32位为单位。

        写操作有四步:解锁 à 擦除 à 写数据 à 上锁

解锁:将两个特定的解锁序列号(KEY1:0x45670123 KEY2:0xCDEF89AB依次写入FLASH_KEYR

擦除:FLASH物理特性(只能写0,不能写1),所以写FLASH之前需要擦除,将要写入的区域变为0xFFFF。擦除操作分为:页扇区擦除和整片擦除

写数据:擦除完成,可以向FLASH写数据,根据PSIZE设置写入数据的单位

PSZIE:00 字节、PSIZE:01 半字、PSIZE:10 字、PSIZE:11 双字

上锁:写入数据完成,需要设置FLASH_CR[LOCK]1,重新上锁,以防数据不小心被修改。

      注意:对于STM32H7 FLASH写入的规则:写入首地址必须是32的倍数,写入数据长度必须是32字节的倍数。  

FLASH接口寄存器(写入 & 擦除相关)

FLASH_CR

LOCK:指示FLASH_CR寄存器是否被锁住(10未锁)

STRT:用于开始一次擦除操作(1开始)

PSIZE:用于设置编程宽度(3.3V PSIZE2

SNB:用于选择要擦除的扇区编号

SER:用于选择扇区擦除操作(页擦除置1

PG:用于选择编程操作,往FLASH写数据需置1

         对于H7还有FLASH_CCR 清除与控制寄存器用于清除相关错误。

FLASH相关HAL库函数简介(F1 / F4 / F7 / H7)

FLASH相关结构体:FLASH_EraseInitTypeDef

F1:

uint32_t	TypeErase	 	/* 擦除类型 */
uint32_t	Banks		/* 擦除的bank编号(整片擦除) */
uint32_t 	PageAddress	/* 擦除页面地址 */
uint32_t 	NbPages		/* 擦除的页面数 */

F4/F7/H7

uint32_t	TypeErase	 	
uint32_t	Banks		
uint32_t 	Sector	
uint32_t 	NbSectors
uint32_t	VoltageRange	

F103ZET6 stmflash_write思路

        每个扇区()2KB,也就是2048个地址,写任何一个地址前,如果该地址的值并不是0xFF,需先擦除再写入

根据w_addr,确定No.sector号以及w_addr在该sector的偏移

根据w_addrlength,确定写入的内容是否跨sector

确定好要操作的sector以及sector的地址范围

遍历要写的地址区域数据是否都是0xFF,如果都是不用擦除,否则需要先读出保存在buf后擦除

把该sector要操作的数据,也写到buf,最后一次性把buf写入到这个对应的sector即可

        跨扇区:需要注意偏移(扇区地址 / 扇区中的偏移 / 写入数据的偏移 / 写地址偏移 / 写入长度)

可操作的地址怎么确定?

        不能影响原有已存放有用数据的FLASH区域,通过MDK编译完成提示或者map文件可得占用flash大小。

        占用FLASH大小 4058827360 + 12868 + 360

        占用SRAM大小 4496360 + 4136

Code段:表示程序代码占用FLASH的大小(FLASH 

RO-data段,即Read Only-Data,程序定义的所有常量(FLASH 

RW-data段,即Read Write-Data,已经初始化的所有静态变量,占用FLASH空间(存储初值)和RAM(读写操作)

ZI-data(Zero initialized)段:未初始化的静态变量

RO(Read Only)段:指代码Code以及只读数据RO-data的统称,占用FLASH空间 

相关文章:

初学stm32 --- flash模仿eeprom

目录 STM32内部FLASH简介 内部FLASH构成(F1) FLASH读写过程(F1) 闪存的读取 闪存的写入 内部FLASH构成(F4 / F7 / H7) FLASH读写过程(F4 / F7 / H7) 闪存的读取 闪存的写入 …...

使用C语言实现栈的插入、删除和排序操作

栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...

C语言程序环境和预处理详解

本章重点: 程序的翻译环境 程序的执行环境 详解:C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...

基于机器学习随机森林算法的个人职业预测研究

1.背景调研 随着信息技术的飞速发展,特别是大数据和云计算技术的广泛应用,各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式,为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步,如深度学习、强化学习等…...

三种文本相似计算方法:规则、向量与大模型裁判

文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度:  比如,RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数,返回前TopK个候选文本。  在评估大模型生成的文本阶段,也需要评估…...

Python语言的计算机基础

Python语言的计算机基础 绪论 在当今信息技术飞速发展的时代,编程已经成为了一种必备技能。Python凭借其简洁、易读和强大的功能,逐渐成为初学者学习编程的首选语言。本文将以Python语言为基础,探讨计算机科学的基本概念,并帮助…...

Dify应用-工作流

目录 DIFY 工作流参考 DIFY 工作流 2025-1-15 老规矩感谢参考文章的作者,避免走弯路。 2025-1-15 方便容易上手 在dify的一个桌面上,添加多个节点来完成一个任务。 每个工作流必须有一个开始和结束节点。 节点之间用线连接即可。 每个节点可以有输入和输出 输出类型有,字符串,…...

02.02、返回倒数第 k 个节点

02.02、[简单] 返回倒数第 k 个节点 1、题目描述 实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。 2、题解思路 本题的关键在于使用双指针法,通过两个指针(fast 和 slow),让 fast 指针比 slow 指针…...

Linux手写FrameBuffer任意引脚驱动spi屏幕

一、硬件设备 开发板:香橙派 5Plus,cpu:RK3588,带有 40pin 外接引脚。 屏幕:SPI 协议 0.96 寸 OLED。 二、需求 主要是想给板子增加一个可视化的监视器,并且主页面可调。 平时跑个模型或者服务,…...

怎么修复损坏的U盘?而且不用格式化的方式!

当你插入U盘时,若电脑弹出“需要格式化才能使用”提示,且无法打开或读取其中的数据,说明U盘极有可能已经损坏。除此之外,若电脑在连接U盘后显示以下信息,也可能意味着U盘出现问题,需要修复损坏的U盘&#x…...

语音技术在播客领域的应用(2)

播客是以语音为主,各种基于AI 的语音技术在播客领域十分重要。 语音转文本 Whisper Whisper 是OpenAI 推出的开源语音辨识工具,可以把音档转成文字,支援超过50 种语言。这款工具是基于68 万小时的训练资料,其中包含11.7 万小时的…...

【Linux】应用层自定义协议与序列化

🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 应用层 🦋 再谈 "协议"🦋 网络版计算器🦋 序列化 和 反序列化 二:🔥 重新理解 read、…...

深度学习中的张量 - 使用PyTorch进行广播和元素级操作

深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思? 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作,它作用于各自张量中的相应元素…...

gitignore忽略已经提交过的

已经在.gitignore文件中添加了过滤规则来忽略bin和obj等文件夹,但这些文件夹仍然出现在提交中,可能是因为这些文件夹在添加.gitignore规则之前已经被提交到Git仓库中了。要解决这个问题,您需要从Git的索引中移除这些文件夹,并确保…...

h5使用video播放时关掉vant弹窗视频声音还在后台播放

现象&#xff1a; 1、点击遮罩弹窗关闭&#xff0c;弹窗的视频已经用v-if销毁&#xff0c;但是后台会自己从头开始播放视频声音。但是此时已经没有视频dom 2、定时器在打开弹窗后3秒自动关闭弹窗&#xff0c;则正常没有问题。 原来的代码&#xff1a; //页面 <a click&quo…...

Widows搭建sqli-labs

使用ms17_010渗透win7 ms17_010针对windows445端口(共享文件), 现有一台win7虚拟机IP 192.168.80.129, 开放445端口, 使用msf渗透该虚拟机 auxiliary 使用auxiliary判断目标主机是否适用smb17_010漏洞 这里发现80网段, 有一台主机适用 exploit 使用search ms17_010 type:expl…...

为AI聊天工具添加一个知识系统 之46 蒙板程序设计(第一版):Facet六边形【意识形态:操纵】

本文要点 要点 (原先标题冒号后只有 “Facet”后改为“Face六边形【意识形态】” &#xff0c;是 事后想到的&#xff0c;本文并未明确提出。备忘在这里作为后续的“后期制作”的备忘) 前面讨论的&#xff08;“之41 纯粹的思维”&#xff09;中 说到&#xff0c;“意识”三…...

ASP.NET Core WebApi接口IP限流实践技术指南

在当今的Web开发中&#xff0c;接口的安全性和稳定性至关重要。面对恶意请求或频繁访问&#xff0c;我们需要采取有效的措施来保护我们的WebApi接口。IP限流是一种常见的技术手段&#xff0c;通过对来自同一IP地址的请求进行频率控制&#xff0c;可以有效地防止恶意攻击和过度消…...

文件移动工具 (File Mover)

这是一个简单但功能强大的Python脚本&#xff0c;用于递归遍历目录并将指定格式的文件移动到目标目录。默认支持移动PDF文件&#xff0c;但也可以通过参数指定其他文件格式。 功能特点 递归遍历源目录及其所有子目录支持移动任意指定格式的文件自动处理目标目录中的文件重名情…...

PTA L1-039 古风排版

中国的古人写文字&#xff0c;是从右向左竖向排版的。本题就请你编写程序&#xff0c;把一段文字按古风排版。 输入格式&#xff1a; 输入在第一行给出一个正整数N&#xff08;<100&#xff09;&#xff0c;是每一列的字符数。第二行给出一个长度不超过1000的非空字符串&a…...

MusePublic Art Studio实际效果:UI设计稿生成中组件一致性保障

MusePublic Art Studio实际效果&#xff1a;UI设计稿生成中组件一致性保障 1. 引言&#xff1a;当AI成为你的UI设计搭档 想象一下这个场景&#xff1a;你正在为一个新的移动应用设计UI界面。你已经画好了登录页的草图&#xff0c;上面有圆角按钮、卡片式布局和一套清爽的配色…...

Spring AI + DeepSeek 实战:5分钟搞定一个能听懂人话的数据库查询工具

Spring AI DeepSeek 实战&#xff1a;5分钟搞定一个能听懂人话的数据库查询工具 在数据驱动的时代&#xff0c;数据库查询是每个开发者绕不开的日常任务。但当你面对产品经理频繁变更的需求&#xff0c;或是运营同事临时提出的数据提取请求时&#xff0c;反复编写和调试SQL语句…...

一键召唤AI画师!次元画室让角色设计变得如此简单

一键召唤AI画师&#xff01;次元画室让角色设计变得如此简单 你是否曾经有过这样的经历&#xff1f;脑海中浮现出一个绝妙的角色形象&#xff0c;却苦于无法将它完美呈现&#xff1b;或者为了设计游戏角色&#xff0c;不得不花费重金聘请专业画师&#xff1b;又或者作为小说作…...

WikiJS全文搜索实战:用ElasticSearch+IK分词器提升内容检索效率(Docker版)

WikiJS全文搜索实战&#xff1a;ElasticSearch与IK分词器的深度优化指南 引言&#xff1a;为什么需要专业级全文搜索解决方案&#xff1f; 想象一下&#xff0c;当你面对一个包含数千篇技术文档的Wiki系统时&#xff0c;传统的关键词匹配就像在黑暗房间里寻找一根针。WikiJS自带…...

告别Electron臃肿!用Tauri 2.0 + Rust打造你的第一个轻量级桌面应用(附完整项目结构解析)

从Electron到Tauri 2.0&#xff1a;用Rust重构现代桌面应用开发范式 当Electron应用体积膨胀到200MB起步时&#xff0c;我们不得不重新思考桌面开发的未来。Tauri 2.0的出现绝非偶然——这是前端开发者对性能与体验的集体觉醒。本文将带你深入这个基于Rust的轻量级框架&#xf…...

提升开放平台开发效率,快马AI工具链自动化集成与测试

在企业级开放平台的开发过程中&#xff0c;效率往往是决定项目成败的关键因素之一。传统的开发流程中&#xff0c;开发者需要花费大量时间在重复性工作上&#xff0c;比如编写API客户端代码、配置测试环境、维护文档等。这些工作不仅耗时&#xff0c;还容易出错。今天我想分享一…...

DevExpress GridControl动态添加行的两种高效实现方式

1. 两种动态添加行的核心方法对比 刚接触DevExpress GridControl时&#xff0c;最让我头疼的就是动态添加行这个基础操作。网上教程要么太零散&#xff0c;要么直接贴代码不解释原理。经过多个项目实战&#xff0c;我总结出最高效的两种实现方式&#xff0c;就像给表格数据&quo…...

技术驱动B端拓客升级:号码核验行业的痛点突围与发展新路径,氪迹科技核验筛选算法系统,法人股东核验,阶梯式价格

在B端市场竞争愈发精细化的当下&#xff0c;拓客工作的核心竞争力已从“广撒网”转向“精准触达”&#xff0c;而企业核心决策人的有效联系方式&#xff0c;正是精准拓客的关键载体。号码核验作为拓客流程的前置核心环节&#xff0c;直接决定着拓客投入的回报效率&#xff0c;更…...

别啃书了!用这款70块的Steam游戏《Turing Complete》,手把手带你从逻辑门拼出CPU

从逻辑门到CPU&#xff1a;用《Turing Complete》重构计算机组成原理学习体验 当我在大学第一次翻开《计算机组成原理》教材时&#xff0c;那些密密麻麻的逻辑门符号和抽象的数据通路图让我头皮发麻。直到在Steam上发现标价70元的《Turing Complete》——这款看似简单的电路模拟…...

天津专业的阀门厂排名

在天津&#xff0c;阀门行业发展态势良好&#xff0c;众多阀门厂各有特色与优势。中国通用机械工业协会最新发布的《2026年阀门行业高质量发展白皮书》显示&#xff0c;天津的阀门产业在技术创新、产品质量和市场份额等方面都有不错的表现。下面为大家介绍几家天津比较知名的阀…...