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

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(&sectorBuffer[pageOffset * PAGE_SIZE], data, length);// 3. 擦除扇区W25Q_EraseSector(sectorAddr);// 4. 将修改后的数据写回整个扇区W25Q_Write(sectorBuffer, sectorAddr, SECTOR_SIZE);
}

注意:W25Q_ReadW25Q_Write 是 SPI Flash 的读写函数;W25Q_EraseSector 是擦除扇区的函数。这里假设你要修改的页在 sectorAddr 的偏移量为 pageOffset 页。

四、DMA方式传输(待写)


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

相关文章:

stm32 W25Q数据存储

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、cubemx配置二、keil中文件修改与配置三、几个重要函数的说明四、DMA方式传输&#xff08;待写&#xff09;总结 前言 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裸流行解复用&#xff08;解封装&#xff09;时&#xff0c;其AVStream的time_base是怎样被计算出来的。 二、FFmpeg源码中计算AAC裸流AVStream的time_base的实现 FFmpeg对AAC裸流进行解复用&#xff08;解封装&#xff09;时&#xff0c;其…...

React 组件的基本使用,useState 状态变量的使用

React 组件 组件是什么 ##### 概念&#xff1a;一个组件就是用户界面的一部分&#xff0c;它可以有自己的逻辑和外观&#xff0c;组件之间可以相互嵌套&#xff0c;也可以多次复用。 在 React&#xff0c;一个组件就是首字母大写的函数&#xff0c;内部存放了组件的逻辑和视…...

空洞骑士 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 的具体编程实现举例&#xff1a;广度优先搜索的具体步骤初始状态&#xff1a;步骤 1&#xff1a;加入起点节点 1步骤 2&#xff1a;访问队列中的节点 1&#xff0c;加入其邻居节点 2 和 4步骤 3&#xff1a;访问队列中的…...

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 &#xff08;System.ValueTuple&#xff09; 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漏洞

文章目录 免责申明搜索语法漏洞描述漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 搜索语法 fofa title"ChatGPT个人专用版"漏洞描述 该系统是一个开源的…...

如何查看微信聊天记录?四种实用方法查询微信聊天记录,赶快码住!

微信作为我们日常生活中不可或缺的社交工具&#xff0c;记录了大量的聊天内容和重要信息。 当需要查看或恢复微信聊天记录时&#xff0c;很多人可能不知道如何快速、安全地进行操作。 今天&#xff0c;我们就来介绍四种实用的微信聊天记录查询方法&#xff0c;帮助你有效查看微…...

钢材表面缺陷数据集以coco格式做好了数据集的划分,1200张训练集,600张验证集,对应的json文件也在里面

钢材表面缺陷数据集 以coco格式做好了数据集的划分&#xff0c;1200张训练集&#xff0c;600张验证集&#xff0c;对应的json文件也在里面。 钢材表面缺陷检测数据集营销介绍 项目背景&#xff1a; 钢材作为工业生产的重要原材料之一&#xff0c;其表面质量直接影响到成品的性…...

【Lua坑】Lua协程coroutine无法正常完整执行问题

问题&#xff1a;发现Lua协程执行到一半&#xff0c;突然被掐断了一样等到了设定的时间没有正常执行协程后续代码&#xff01;非必现bug&#xff0c;若发生大概率在高频率使用协程时易触发。 LuaFramework或xLua uLua都自带有协程coroutine&#xff0c;而且基本都使用对象池缓…...

istio中serviceentry结合egressgateway的使用

假设有一个外部服务&#xff0c;外部服务ip为&#xff1a;10.10.102.90&#xff0c;其中32033为v1版本&#xff0c;32034为v2版本。 现在需要把这个服务引入到istio中&#xff0c;并且需要配置所有访问该服务的流量都通过egressgateway转发出去。 serviceentry apiVersion: n…...

使用 Python 实现 Windows 应用图标的便捷生成:一站式 PNG 转 ICO 工具20240918

使用 Python 实现 Windows 应用图标的便捷生成&#xff1a;一站式 PNG 转 ICO 工具 在开发 Windows 桌面应用程序时&#xff0c;图标文件&#xff08;ICO&#xff09;的生成是不可忽视的关键步骤。无论是任务栏图标、快捷方式&#xff0c;还是应用程序的主图标&#xff0c;都需…...

编程环境常用命令合集

cmd: python 进入python运行环境 exit()/quit()/ctrlZ 退出环境 rmdir /s venv 删除环境 pip命令&#xff1a; pip list 查看所有库 pip install <库> 安装库 -i <数据源>可指定安装数据源 pip install <库>x.x.x 安装指定版本的库 pip install --upgrade &…...

Qt Creator 集成开发环境 常见问题

1.QtCreator中三种不同编译版本 debug、release、profile 的区别 在 Qt Creator 中&#xff0c;Debug、Release 和 Profile 是三种不同的构建配置&#xff0c;它们主要用于在开发过程中生成不同类型的可执行文件。它们的区别如下&#xff1a; 1.1 Debug&#xff08;调试版本&…...

使用Faiss进行K-Means聚类

&#x1f4dd; 本文需要的前置知识&#xff1a;Faiss的基本使用 目录 1. 源码剖析1.1 参数解释 2. 聚类过程详解2.1 初始化聚类中心2.2 分配步骤&#xff08;Assignment&#xff09;2.3 更新步骤&#xff08;Update&#xff09;2.4 收敛与终止条件 3. GPU 加速3.1 索引结构与 G…...

通过hosts.allow和hosts.deny限制用户登录

1、Hosts.allow和host.deny说明 两个文件是控制远程访问设置的&#xff0c;通过设置这个文件可以允许或者拒绝某个ip或者ip段的客户访问linux的某项服务。如果请求访问的主机名或IP不包含在/etc/hosts.allow中&#xff0c;那么tcpd进程就检查/etc/hosts.deny。看请求访问的主机…...

PWN College 关于sql盲注

在这个场景中&#xff0c;我们需要利用SQL注入漏洞来泄露flag&#xff0c;但是应用程序并不会直接返回查询结果。相反&#xff0c;我们需要根据应用程序的行为差异&#xff08;登录成功与否&#xff09;来推断查询结果。这就是所谓的"布尔盲注"&#xff08;Boolean-b…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

aurora与pcie的数据高速传输

设备&#xff1a;zynq7100&#xff1b; 开发环境&#xff1a;window&#xff1b; vivado版本&#xff1a;2021.1&#xff1b; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程&#xff0c;pc通过pcie传输给fpga&#xff0c;fpga再通过aur…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除

目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作&#xf…...