当前位置: 首页 > 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…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...