stm32 W25Q数据存储
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、cubemx配置
- 二、keil中文件修改与配置
- 三、几个重要函数的说明
- 四、DMA方式传输(待写)
- 总结
前言
W25Q128 容量为128位 128/8 = 16 也就是16M


擦除之前必须写使能


写数据的存储单元必须是被擦除过的也就是必须是0XFF,不过不是则写入无效。

此图来源于
一、cubemx配置
全双工SPI
不使用硬件NSS
w25q虽然数据手册写可以达到30mbit/s但是还是建议用10以下的,高了偶尔会出错。
这里参考b站的视频
视频中用的spi3模式,我用的1模式
spi配置

片选引脚配置
初始化为high 保证上电以后未被片选

二、keil中文件修改与配置
使用到的代码为b站视频中的链接1 链接2
.h文件这里进行了修改


这里注意
前两个 值对任意W25Q都是一样的,不需要修改,4096 也并未用到,目前暂时不修改
//===========Flash存储芯片W25Q128的存储容量参数================
#define FLASH_PAGE_SIZE 256 //一个Page是256字节
#define FLASH_SECTOR_SIZE 4096 //一个Sector是4096字节
#define FLASH_SECTOR_COUNT 4096 //总共4096个 Sector
三、几个重要函数的说明
w25q必须以页为单位来写入,写入前必须要擦除,擦除必须以扇区进行擦除
如果写入前没有擦除,虽然不会报错,但是写入是无效的。
重要函数
Flash_EraseChip();//擦除整个芯片大概20多秒
Flash_EraseBlock64K(globalAddr);//擦除一个块
Flash_EraseSector(memAddress1);//擦除一个扇区 这个是擦除的最单位了
Flash_Addr_byBlockSectorPage(uint8_t BlockNo, uint8_t SubSectorNo, uint8_t SubPageNo) 这个函数是用来得到 块 扇区 页 的那个绝对地址的。
举例
擦除一个扇区
uint32_t memAddress1 = Flash_Addr_byBlockSectorPage(0, 0, 1);Flash_EraseSector(memAddress1);
向两个页分别写数据
void Flash_TestWrite() {uint8_t BlockNo = 0;uint8_t SubSectorNo = 0;uint8_t SubPageNo = 0;uint32_t memAddress = 0;memAddress = Flash_Addr_byBlockSectorPage(BlockNo, SubSectorNo, SubPageNo);uint8_t bufStr1[30] = "Hello222444";Flash_WriteInPage(memAddress, bufStr1, strlen(bufStr1) + 1);printf("Write in Page0:0\n");printf( "%s",bufStr1);uint8_t bufStr2[30] = "Hello111333";Flash_WriteInPage(memAddress + 100, bufStr2, strlen(bufStr2) + 1);printf( "Write in Page0:100\n");printf( "%s", bufStr2);uint8_t bufPage[FLASH_PAGE_SIZE];for (uint16_t i = 0; i < FLASH_PAGE_SIZE; ++i) {bufPage[i] = 0;}SubPageNo = 1;memAddress = Flash_Addr_byBlockSectorPage(BlockNo, SubSectorNo, SubPageNo);Flash_WriteInPage(memAddress, bufPage, FLASH_PAGE_SIZE);printf("Write 0~255 in Page1");
}
向两个页分别读数据
void Flash_TestRead() {uint8_t BlockNo = 0;uint8_t SubSectorNo = 0;uint8_t SubPageNo = 0;uint32_t memAddress = Flash_Addr_byBlockSectorPage(BlockNo, SubSectorNo, SubPageNo);uint8_t bufStr[50];Flash_ReadBytes(memAddress, bufStr, 50);printf( "Read in Page0:0 ");printf( "%s", bufStr);Flash_ReadBytes(memAddress + 100, bufStr, 50);printf( "Read in Page0:100 ");printf( "%s", bufStr);SubPageNo = 1;memAddress = Flash_Addr_byBlockSectorPage(BlockNo, SubSectorNo, SubPageNo);uint8_t randData12 = Flash_ReadOneByte(memAddress + 12);uint8_t randData136 = Flash_ReadOneByte(memAddress + 136);uint8_t randData210 = Flash_ReadOneByte(memAddress + 210);uint8_t tempStrRandData[30];sprintf(tempStrRandData, "Page1[12]=%d,[136]=%d,[210]=%d",randData12, randData136, randData210);printf( "%s", tempStrRandData);
}
有了 上面两个函数我们就可以做一些小实验了。
第一次使用的时候先对芯片进行整体的擦除
让后调用Flash_TestWrite();函数,此时调用Flash_TestRead() ;函数来读取是正常的
修改代码,不对w25q进行任何擦除直接把Flash_TestWrite();中的bufPage[i] = 0;写成bufPage[i] = i;
这时候读取函数读到的值就是上一次的,说明虽然没有报错,但是并未写入成功
如果对芯片进行该扇区的擦除,再写入即可在读取中获取新的写入。记住写入是按照页来写,擦除是按照扇区擦,一个扇区里面有16个页。
在使用 W25Q 系列的 SPI Flash 存储器时,确实存在写入操作以页为单位(通常为256字节),而擦除操作以扇区为单位(通常为4KB)的限制。这意味着如果你只想修改某个页的数据,而不影响同一扇区内的其他数据,必须采取一些策略来避免丢失扇区中其他页的数据。
解决方法
通常有两种常见的解决方案来应对这个问题:
1扇区读出、修改和写回
步骤:
读出整个扇区:在你需要修改某一页的数据时,先读取整个扇区的数据到内存中。
修改页数据:在内存中修改目标页的数据。
擦除扇区:执行扇区擦除操作。
写回数据:将修改后的数据重新写回该扇区,包括未修改的页数据和修改后的页数据
2使用缓存(缓存区)
步骤
在内存中保留一个缓冲区:该缓冲区的大小等同于一个扇区大小。
管理缓存:每次写入时,先更新缓存区中的数据,然后定期或在缓存区满时写回 SPI Flash。
擦除与写回:当要写入到 Flash 时,执行上述 “扇区读出、修改和写回” 的操作。
优点:可以减少对 Flash 的擦写次数,延长 Flash 的寿命。
总结
无论选择哪种方式,主要思想都是避免直接修改 Flash 中的数据,而是通过在内存中暂存整个扇区的数据,再进行更新和写回操作。这种方式能够有效避免因为写入新数据而导致同一扇区内其他数据的丢失问题。
1扇区读出、修改和写回参考代码
#define SECTOR_SIZE 4096 // W25Q扇区大小
#define PAGE_SIZE 256 // W25Q页大小uint8_t sectorBuffer[SECTOR_SIZE];void updatePageInSector(uint32_t sectorAddr, uint16_t pageOffset, uint8_t* data, uint16_t length) {// 1. 读出整个扇区W25Q_Read(sectorBuffer, sectorAddr, SECTOR_SIZE);// 2. 修改指定页的数据memcpy(§orBuffer[pageOffset * PAGE_SIZE], data, length);// 3. 擦除扇区W25Q_EraseSector(sectorAddr);// 4. 将修改后的数据写回整个扇区W25Q_Write(sectorBuffer, sectorAddr, SECTOR_SIZE);
}
注意:W25Q_Read 和 W25Q_Write 是 SPI Flash 的读写函数;W25Q_EraseSector 是擦除扇区的函数。这里假设你要修改的页在 sectorAddr 的偏移量为 pageOffset 页。
四、DMA方式传输(待写)
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
相关文章:
stm32 W25Q数据存储
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、cubemx配置二、keil中文件修改与配置三、几个重要函数的说明四、DMA方式传输(待写)总结 前言 W25Q128 容量为128位 128/8 16 也就…...
深度学习的笔记
1. 从huggingface上仅下载pytorch模型权重和配置文件到服务器 import os import shutil from huggingface_hub import snapshot_download# 直接指定模型和下载路径 model_name openai/clip-vit-base-patch32 download_path /home/xxx/.cache/huggingface/hub/models--anas-a…...
音视频入门基础:AAC专题(8)——FFmpeg源码中计算AAC裸流AVStream的time_base的实现
一、引言 本文讲解FFmpeg源码对AAC裸流行解复用(解封装)时,其AVStream的time_base是怎样被计算出来的。 二、FFmpeg源码中计算AAC裸流AVStream的time_base的实现 FFmpeg对AAC裸流进行解复用(解封装)时,其…...
React 组件的基本使用,useState 状态变量的使用
React 组件 组件是什么 ##### 概念:一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以相互嵌套,也可以多次复用。 在 React,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视…...
空洞骑士 Hollow Knight 攻略
文章目录 Part.I IntroductionPart.II 攻略Chap.I 地图Chap.II 护符Chap.III BOSSChap.IV 魔法 Reference Part.I Introduction 《空洞骑士》是独立团队 Team Cherry 开发的一款 2D 类银河恶魔城动作冒险游戏。本文记录笔者玩此游戏所积累的一些经验。 「在《空洞骑士》中打造…...
CSP-J 算法基础 广度优先搜索BFS
文章目录 前言广度优先搜索是什么广度优先搜索的实现BFS 的具体编程实现举例:广度优先搜索的具体步骤初始状态:步骤 1:加入起点节点 1步骤 2:访问队列中的节点 1,加入其邻居节点 2 和 4步骤 3:访问队列中的…...
What is new in C# 7,8,9,10
目录 Whats new in C# 7 C# 7 in Visual Studio 2017 Out Variables Pattern Matching Tuples (System.ValueTuple) Deconstruct解构 Local Functions Ref Returns and Locals Expression Bodied Members Throw Expressions Generated Async R…...
Sqlserver常用sql
1. 数据库和表操作 创建数据库 CREATE DATABASE DatabaseName; 删除数据库 DROP DATABASE DatabaseName; 创建表 CREATE TABLE TableName ( Column1 DataType1, Column2 DataType2, ... ); 删除表 DROP TABLE TableName; 2. 数据操作 插入数据 INSERT INTO TableNam…...
基于SpringBoot+Vue+MySQL的考研互助交流平台
系统展示 用户前台界面 管理员后台界面 系统背景 本文设计并实现了一个基于SpringBoot、Vue.js和MySQL的考研互助交流平台。该平台旨在为广大考研学子提供一个集资源共享、学习交流、经验分享、心理辅导等功能于一体的综合性在线社区。通过SpringBoot构建高效稳定的后端服务&am…...
chatgpt个人版ssrf漏洞
文章目录 免责申明搜索语法漏洞描述漏洞复现修复建议 免责申明 本文章仅供学习与交流,请勿用于非法用途,均由使用者本人负责,文章作者不为此承担任何责任 搜索语法 fofa title"ChatGPT个人专用版"漏洞描述 该系统是一个开源的…...
如何查看微信聊天记录?四种实用方法查询微信聊天记录,赶快码住!
微信作为我们日常生活中不可或缺的社交工具,记录了大量的聊天内容和重要信息。 当需要查看或恢复微信聊天记录时,很多人可能不知道如何快速、安全地进行操作。 今天,我们就来介绍四种实用的微信聊天记录查询方法,帮助你有效查看微…...
钢材表面缺陷数据集以coco格式做好了数据集的划分,1200张训练集,600张验证集,对应的json文件也在里面
钢材表面缺陷数据集 以coco格式做好了数据集的划分,1200张训练集,600张验证集,对应的json文件也在里面。 钢材表面缺陷检测数据集营销介绍 项目背景: 钢材作为工业生产的重要原材料之一,其表面质量直接影响到成品的性…...
【Lua坑】Lua协程coroutine无法正常完整执行问题
问题:发现Lua协程执行到一半,突然被掐断了一样等到了设定的时间没有正常执行协程后续代码!非必现bug,若发生大概率在高频率使用协程时易触发。 LuaFramework或xLua uLua都自带有协程coroutine,而且基本都使用对象池缓…...
istio中serviceentry结合egressgateway的使用
假设有一个外部服务,外部服务ip为:10.10.102.90,其中32033为v1版本,32034为v2版本。 现在需要把这个服务引入到istio中,并且需要配置所有访问该服务的流量都通过egressgateway转发出去。 serviceentry apiVersion: n…...
使用 Python 实现 Windows 应用图标的便捷生成:一站式 PNG 转 ICO 工具20240918
使用 Python 实现 Windows 应用图标的便捷生成:一站式 PNG 转 ICO 工具 在开发 Windows 桌面应用程序时,图标文件(ICO)的生成是不可忽视的关键步骤。无论是任务栏图标、快捷方式,还是应用程序的主图标,都需…...
编程环境常用命令合集
cmd: python 进入python运行环境 exit()/quit()/ctrlZ 退出环境 rmdir /s venv 删除环境 pip命令: pip list 查看所有库 pip install <库> 安装库 -i <数据源>可指定安装数据源 pip install <库>x.x.x 安装指定版本的库 pip install --upgrade &…...
Qt Creator 集成开发环境 常见问题
1.QtCreator中三种不同编译版本 debug、release、profile 的区别 在 Qt Creator 中,Debug、Release 和 Profile 是三种不同的构建配置,它们主要用于在开发过程中生成不同类型的可执行文件。它们的区别如下: 1.1 Debug(调试版本&…...
使用Faiss进行K-Means聚类
📝 本文需要的前置知识:Faiss的基本使用 目录 1. 源码剖析1.1 参数解释 2. 聚类过程详解2.1 初始化聚类中心2.2 分配步骤(Assignment)2.3 更新步骤(Update)2.4 收敛与终止条件 3. GPU 加速3.1 索引结构与 G…...
通过hosts.allow和hosts.deny限制用户登录
1、Hosts.allow和host.deny说明 两个文件是控制远程访问设置的,通过设置这个文件可以允许或者拒绝某个ip或者ip段的客户访问linux的某项服务。如果请求访问的主机名或IP不包含在/etc/hosts.allow中,那么tcpd进程就检查/etc/hosts.deny。看请求访问的主机…...
PWN College 关于sql盲注
在这个场景中,我们需要利用SQL注入漏洞来泄露flag,但是应用程序并不会直接返回查询结果。相反,我们需要根据应用程序的行为差异(登录成功与否)来推断查询结果。这就是所谓的"布尔盲注"(Boolean-b…...
AI读脸术如何对接API?Flask服务封装部署教程
AI读脸术如何对接API?Flask服务封装部署教程 1. 为什么需要把“读脸术”变成API? 你可能已经试过这个AI读脸术镜像:上传一张照片,几秒内就能看到人脸框、性别和年龄段标签,效果干净利落。但如果你正开发一个用户管理…...
用Python写AI版石头剪刀布:教你用机器学习预测对手出拳(TensorFlow实战)
用Python构建AI驱动的石头剪刀布游戏:从数据收集到模型部署全流程 石头剪刀布这个看似简单的游戏,实际上蕴含着丰富的决策模式和人类行为规律。作为一名长期研究游戏AI的开发者,我发现用机器学习预测玩家出拳模式远比随机选择有趣得多。本文将…...
深入解析Camera-IMU联合标定:从理论到实践
1. 为什么需要Camera-IMU联合标定? 在机器人定位和三维重建领域,相机和IMU(惯性测量单元)是最常用的传感器组合。相机能提供丰富的环境特征信息,但在快速运动或弱光环境下容易失效;IMU可以稳定输出运动数据…...
磁流变半主动悬架Simulink模型创建与策略设计详解
磁流变半主动悬架simulink模型,包含模型创建,模型策略设计磁流变悬架的Simulink建模就像搭积木——你得先搞清楚每块积木该放哪儿。咱们从最基础的四分之一车模型开始,车身质量、悬架刚度这些参数直接在Simulink里拖几个Mass和Spring模块就能…...
从STFT到ISTFT:窗函数、填充与流式处理的实战指南
1. 窗函数一致性:信号重建的隐形守护者 第一次用STFT处理语音信号时,我踩过一个典型坑:用汉宁窗做分析,却忘了在重建时指定相同窗函数。结果重建后的语音像被掐着脖子说话,高频部分全是毛刺。这个教训让我明白…...
内网渗透全流程拆解|从入门到实战,小白也能看懂的步骤
内网渗透不是“盲目尝试”,而是遵循固定流程的系统化操作,核心流程可概括为:信息收集→漏洞利用→权限提升→横向移动→权限维持→痕迹清理,每个环节环环相扣,缺一不可。本文将结合小白易理解的实战场景,详…...
洗衣留香珠市场:其中亚太地区以12.5%的增速领跑全球市场
据权威市场研究机构预测,2024年全球洗衣留香珠市场规模预计突破35亿美元,年复合增长率达8.2%,其中亚太地区以12.5%的增速领跑全球市场。这一功能性香氛产品正从附加型消费向日常洗护必需品转型,其技术迭代与市场渗透呈现出高端化、…...
算法对齐还是实战突围?解构GEO优化中方法论与实践的权重博弈
在生成式人工智能(AIGC)重塑全球信息检索范式的当下,生成式引擎优化(Generative Engine Optimization, GEO)已从一种前沿概念演变为品牌流量增长的底层操作系统。随着大语言模型(LLM)与检索增强…...
cool-admin(midway版)数据权限缓存:基于用户角色的权限数据预加载
cool-admin(midway版)数据权限缓存:基于用户角色的权限数据预加载 【免费下载链接】cool-admin-midway 🔥 cool-admin(midway版)一个很酷的后台权限管理框架,模块化、插件化、CRUD极速开发,永久开源免费,基于midway.js…...
猫抓cat-catch:高效媒体捕获与资源下载全指南
猫抓cat-catch:高效媒体捕获与资源下载全指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓cat-catch是一款专注于网页媒体资源捕…...
