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

SPI协议——对外部SPI Flash操作

目录

1. W25Q32JVSSIQ背景知识

1.1 64个可擦除块

1.2 1024个扇区(每个块有16个扇区)

1.3 页


1. W25Q32JVSSIQ背景知识

        

W25Q32JV阵列被组织成16,384个可编程页,每页有256字节。一次最多可以编程256个字节。页面可分为16组(4KB扇区清除)、128组(32KB块删除)、256组(64KB块删除)或整个芯片(芯片清除)。W25Q32JV分别有1,024个可擦除扇区和64个可擦除块。小型的4KB扇区允许在需要数据和参数存储的应用程序中具有更大的灵活性。

1.1 64个可擦除块

8M的空间被切割成128块,每块64kb

  

1.2 1024个扇区(每个块有16个扇区)

每块64kb又每切割成16个扇区,每扇区4kb(16*4=64kb)

1.3 页

一扇区是4KB,划分成16份每份256字节这就是页,而且擦除数据也只能按照扇区或者块来擦除,下图的00FF00H-00FFFFH刚好256字节,000000h-0000ff之间也是256字节

2. Flash操作注意事项

2.1 写入操作

1. 写入操作之前必须先进行写使能;

2. 每个数据只能由1改写为0,不能由0改写为1是因为FLASH芯片自身的限制决定,它没有完全任意修改的能力,所以芯片内部无数据的时候默认为0XFF,表示为空。;

3. 写入数据之前必须先进行擦除,擦除后所有的数据位为1;

4. 进行擦除时必须按照最小擦除单元进行擦除(最小擦除单位为扇区);

5.连续写入多字节数据时,最多写入一页的数据,如果超过一页则会覆盖前面写的内容;

6. 写入操作结束后, 芯片进入忙状态(寄存器中有一个busy位),不影响新的读写操作;

2.2 读操作

进行读操作时,直接调用读取操作时序,无需使能,但是别忘了拉低电平,没有页的限制,读取之后也不会进入到忙状态,但是不能在忙状态时读取数据;

3.代码编写

此次对SPI Flash进行读写操作还是采用SPI1,具体的配置请见上篇文章,在这里不做详细概述。

3.1 spi_flash.c添加代码

/* Flash 写使能 */
static void SPI1_FLASH_WriteEnable(void)
{cs_low();SPI_FLASH_SendByte( 0x06 ); //需要查芯片的datasheet来看具体的cs_high();
}/* Flash 等待写结束 */
static void SPI1_FLASH_WaitEnd(void)
{uint8_t	state = 0;cs_low();SPI_FLASH_SendByte(0x05); //需要查芯片的datasheet来看具体的do{state = SPI1_FLASH_ReadByte();}while( (state & 0x01) == SET );cs_high();
}// 扇区擦除验证函数
int SPI_FLASH_VerifyErase(uint32_t addr, uint32_t length)
{uint8_t buffer[16];uint32_t bytesRead;for (bytesRead = 0; bytesRead < length; bytesRead += sizeof(buffer)){uint32_t toRead = sizeof(buffer);if (bytesRead + toRead > length) {toRead = length - bytesRead;}// 读取地址开始的若干字节数据SPI_FLASH_BufferRead(addr + bytesRead, buffer, toRead);// 检查读取的数据是否为0xFFfor (uint32_t i = 0; i < toRead; i++){if (buffer[i] != 0xFF){return -1; // 如果不是0xFF,返回false,表示擦除失败}}}return 0; // 如果所有数据都是0xFF,返回true,表示擦除成功
}/*清空扇区*/
int SPI_FLASH_SectorErase(uint32_t addr)
{cs_low();/* 开始的时候要先发送写使能信号 */SPI1_FLASH_WriteEnable();/* 发送扇区擦除命令 */SPI_FLASH_SendByte(0x20);/* 发送扇区地址,高位先行 */SPI_FLASH_SendByte( (addr & 0xff0000) >> 16 );SPI_FLASH_SendByte( (addr & 0xff00) >> 8 );SPI_FLASH_SendByte( addr & 0xff );cs_high();/* 最后等待Flash 处理完这次信号之后退出 */SPI1_FLASH_WaitEnd();if (!SPI_FLASH_VerifyErase(addr, 4096)) // 通常扇区大小为4KB{printf("Sector erase failed at address 0x%06X\n", addr);}else{printf("Sector erase successful at address 0x%06X\n", addr);}return 0;}/* 按页写数据,在写数据之前要先擦除 */void SPI_FLASH_PageWrite(uint32_t addr, uint8_t *pBuffer, uint8_t size)
{/* 发送使能信号 */SPI1_FLASH_WriteEnable();cs_low();/* 发送页写入命令 */SPI_FLASH_SendByte(0x02);/* 发送要写入的地址,高位先行 */SPI_FLASH_SendByte( (addr & 0xff0000) >> 16 );SPI_FLASH_SendByte( ( addr & 0xff00) >> 8 );SPI_FLASH_SendByte(addr & 0xff );printf("Writing to address 0x%06X: ", addr);for (uint8_t i = 0; i < size; i++){SPI_FLASH_SendByte(pBuffer[i]); // 发送数据printf("%02X ", pBuffer[i]);}printf("\n");cs_high();SPI1_FLASH_WaitEnd();
}/* 读取数据,读取指定地址制定长度的数据 */
void SPI_FLASH_BufferRead(uint32_t addr, uint8_t *pBuffer, uint16_t size)
{cs_low();/* 发送读取命令 */SPI_FLASH_SendByte(0x03);/* 发送要读取的地址,高位先行*/SPI_FLASH_SendByte( (addr & 0xff0000) >> 16 );SPI_FLASH_SendByte( (addr & 0xff00 ) >> 8 );SPI_FLASH_SendByte(addr & 0xff );printf("Reading to address 0x%06X: ", addr);/* 逐位读取数据到指针上 */for (uint8_t i = 0; i < size; i++){pBuffer[i] = SPI_FLASH_SendByte(Dummy_Byte); // 发送数据}cs_high();}

3.2 详细分析

1. 地址分解

假设 addr 是一个24位的地址(0xFFFFFF范围内)。发送前需要将addr分解成三个8位字节,因为SPI通常以字节为单位发送数据。

SPI_SendData((addr & 0xff0000) >> 16);
  • addr & 0xff0000:使用位与操作(&)保留 addr 的高8位,其余位清零。
  • >> 16:将结果右移16位,使得高8位移到最低8位的位置。
  • SPI_SendData():将移位后的结果发送出去,这发送的是 addr 的高8位。
  • 例如:如果 addr = 0x123456,那么 (addr & 0xff0000) = 0x120000,右移16位得到 0x12,即发送的第一个字节是 0x12。

 其他同理

2. SPI1_FLASH_WaitEnd(void)函数

读取寄存器最低位BUSY的状态,如果为1表示忙,0表示空闲;

3.3 main.c函数

uint8_t Rx[100];
uint8_t Tx[] = "Hello!", n;
SPI_FLASH_SectorErase(0x00000);
n=sizeof(Tx) -1 ;
SPI_FLASH_PageWrite(0x00000 ,Tx ,n);
SPI_FLASH_BufferRead(0x00000 ,Rx ,n);
printf("the data is %s\n", Rx);

3.4 运行结果

 

相关文章:

SPI协议——对外部SPI Flash操作

目录 1. W25Q32JVSSIQ背景知识 1.1 64个可擦除块 1.2 1024个扇区&#xff08;每个块有16个扇区&#xff09; 1.3 页 1. W25Q32JVSSIQ背景知识 W25Q32JV阵列被组织成16,384个可编程页&#xff0c;每页有256字节。一次最多可以编程256个字节。页面可分为16组(4KB扇区清除&…...

kotlin类型检测与类型转换

一、is与!is操作符 1、使用 is 操作符或其否定形式 !is 在运行时检测对象是否符合给定类型。 fun main() {var a "1"if(a is String) {println("a是字符串类型:${a.length}")}// 或val b a is Stringprintln(b) } 二、"不安全的"转换操作符…...

【JDBC】Oracle数据库连接问题记录

Failed to load driver class oracle.jdbc.driver.OracleDriver in either of HikariConfig class oracle驱动包未正确加载&#xff0c;可以先尝试使用下面方式加载检查类是否存在&#xff0c;如果不存在需要手动下载odbc包 try {Class.forName("oracle.jdbc.driver.Ora…...

leetcode45 跳跃游戏II

题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1]…...

【数学】什么是方法矩估计?和最大似然估计是什么关系?

背景 方法矩估计&#xff08;Method of Moments Estimation&#xff09;和最大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是两种常用的参数估计方法。方法矩估计基于样本矩与总体矩的关系&#xff0c;通过样本数据计算样本矩来估计总体参数。最大似…...

C++初学者指南第一步---10.内存(基础)

C初学者指南第一步—10.内存&#xff08;基础&#xff09; 文章目录 C初学者指南第一步---10.内存&#xff08;基础&#xff09;1.内存模型1.1 纸上谈兵&#xff1a;C的抽象内存模型1.2 实践&#xff1a;内存的实际处理 2. 自动存储3.动态存储&#xff1a;std::vector3.1 动态内…...

扩散模型详细推导过程——编码与解码

符号表 符号含义 x ( i ) z 0 ( i ) \boldsymbol{x}^{(i)}\boldsymbol{z}_0^{(i)} x(i)z0(i)​第 i i i个训练数据&#xff0c;其为长度为 d d d的向量 z t ( i ) \boldsymbol{z}_t^{(i)} zt(i)​第 i i i个训练数据在第 t t t时刻的加噪版本 ϵ t ( i ) \boldsymbol{\epsilo…...

js如何实现开屏弹窗

开屏弹窗是什么&#xff0c;其实就是第一次登录后进入页面给你的一种公告提示&#xff0c;此后再回到当前这个页面时弹窗是不会再出现的。也就是说这个弹窗只会出现一次。 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>…...

C#——文件读取Directory类详情

文件读取Directory类 Durectory提供了目录以及子目录进行创建移动和列举操作方法 Directory和Directorylnfo类(主要操作文件目录属性列如文件是否隐藏的 或者只读等这些属性) Directory对目录进行复制、移动、重命名、创建和删除等操作DirectoryInfo用于对目录属性执行操作 …...

Ruby on Rails Post项目设置网站初始界面

在构建了Ruby的Web服务器后&#xff0c;第三步就可以去掉框架的官方页面&#xff0c;设置自己的网页初始页了。 Linux系统安装Ruby语言-CSDN博客 、在Ubuntu中创建Ruby on Rails项目并搭建数据库-CSDN博客、 Ruby语言建立Web服务器-CSDN博客 了解Ruby onRails项目中的主要文件…...

03-QTWebEngine中使用qtvirtualkeyboard

qt提供了 virtualKeyboard 虚拟键盘模块&#xff0c;只需要在在main函数中最开始加入这样一句就可以了 qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); 但是在使用的时候遇到了一些问题&#xff1a; 1、中文输入的时候没有输入提示 Qvirt…...

leetcode3无重复字符的最长字串(重点讲滑动窗口)

本文主要讲解无重复字符的最长字串的要点与细节&#xff0c;根据步骤一步步走更方便理解 c与java代码如下&#xff0c;末尾 具体要点&#xff1a; 1. 区分一下子串和子序列 子串&#xff1a;要求元素在母串中是连续地出现 子序列&#xff1a;不要求连续 2. 题目中有两个核心…...

Gobject tutorial 八

The GObject base class Object memory management Gobject的内存管理相关的API很复杂&#xff0c;但其目标是提供一个基于引用计数的灵活的内存管理模式。 下面我们来介绍一下&#xff0c;与管理引用计数相关的函数。 Reference Count 函数g_object_ref和g_object_unref的…...

DDMA信号处理以及数据处理的流程---cfar检测

Hello,大家好,我是Xiaojie,好久不见,欢迎大家能够和Xiaojie一起学习毫米波雷达知识,Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程,本系列文章将从目标生成、信号仿真、测距、测速、cfar检测、测角、目标聚类、目标跟踪这几个模块逐步介绍,这个系列的…...

【机器学习】从理论到实践:决策树算法在机器学习中的应用与实现

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f4d5;引言 ⛓决策树的基本原理 1. 决策树的结构 2. 信息增益 熵的计算公式 信息增益的计算公式 3. 基尼指数 4. 决策树的构建 &#x1f916;决策树的代码实现 1. 数据准备 2. 决策树模型训练 3.…...

Zookeeper 集群节点故障剔除、切换、恢复原理

Zookeeper 集群节点故障剔除、切换、恢复原理 zookeeper 集群节点故障时,如何剔除节点,如果为领导节点如何处理,如何进行故障恢 复的,实现原理? 在 Zookeeper 集群中,当节点故障时,集群需要自动剔除故障节点并进行故障恢复,确保集群的高 可用性和一致性。具体来说,…...

解决帝国cms栏目管理拼音乱码的问题

帝国CMS7.5版本utf-8版网站后台增加栏目生成乱码的问题怎么解决 1、需要改一个函数&#xff0c;并且增加一个处理文件&#xff0c;方法如下&#xff1a; 修改e/class/connect.php文件&#xff0c;找到ReturnPinyinFun函数&#xff0c;如未修改文件在4533-4547行&#xff0c;将…...

Git快速入门

一 快速使用 1.1 初始化 什么是版本库呢&#xff1f;版本库又名仓库&#xff0c;可以简单理解成一个目录&#xff0c;这个目录里面的所有文件都可以被Git管理起来&#xff0c;每个文件的修改、删除&#xff0c;Git都能跟踪&#xff0c;以便任何时刻都可以追踪历史&#xff0…...

【18.0】JavaScript---事件案例

【18.0】JavaScript—事件案例 【一】开关灯事件 【介绍】设置一个按钮&#xff0c;按下按钮触发事件&#xff0c;来回切换圆形图片的颜色 【分析】 图片设置&#xff1a;设置成圆形的图片背景颜色&#xff1a;设置红绿两个颜色&#xff0c;来回切换按钮设置&#xff1a;点击…...

推荐系统三十六式学习笔记:原理篇.矩阵分解12|如果关注排序效果,那么这个模型可以帮到你

目录 矩阵分解的不足贝叶斯个性化排序AUC构造样本目标函数训练方法 总结 矩阵分解在推荐系统中的地位非常崇高。它既有协同过滤的血统&#xff0c;又有机器学习的基因&#xff0c;可以说是非常优秀了&#xff1b;但即便如此&#xff0c;传统的矩阵分解无论是在处理显式反馈&…...

Kafka之ISR机制的理解

文章目录 Kafka的基本概念什么是ISRISR的维护机制ISR的作用ISR相关配置参数同步过程示例代码总结 Kafka中的ISR&#xff08;In-Sync Replicas同步副本&#xff09;机制是确保数据高可用性和一致性的核心组件。 Kafka的基本概念 在Kafka中&#xff0c;数据被组织成主题&#xf…...

如何设计一个点赞系统

首先我们定义出一个点赞系统需要对外提供哪些接口&#xff1a; 1.用户对特定的消息进行点赞&#xff1b; 2.用户查看自己发布的某条消息点赞数量以及被哪些人赞过&#xff1b; 3.用户查看自己给哪些消息点赞过&#xff1b; 这里假设每条消息都有一个message_id, 每一个用户都…...

对象存储测试工具-s3cmd

一、环境安装 官网&#xff1a;https://s3tools.org/s3cmd 下载安装包&#xff1a;https://s3tools.org/download GitHub&#xff1a;https://github.com/s3tools/s3cmd/releases 本文安装包&#xff1a;https://github.com/s3tools/s3cmd/releases/download/v2.0.2/s3cmd-2.0…...

OpenCV--图像色彩空间及转换

图像色彩空间及转换 python代码和笔记 python代码和笔记 import cv2 色彩空间&#xff0c;基础&#xff1a;RGB或BGR OpenCV中&#xff1a; 一、HSV(HSB)&#xff1a;用的最多&#xff0c; Hue&#xff1a;色相-色彩(0-360)&#xff0c;红色&#xff1a;0&#xff0c;绿色&…...

RIP解决不连续子网问题

#交换设备 RIP解决不连续子网问题 一、不连续子网的概念 相同主网下的子网&#xff0c;被另一个主网分割&#xff0c;例如下面实验拓扑在某公司的网络整改项目中&#xff0c;原先R1 和RS 属于同一主网络 10.0.0.0/8&#xff0c;现被 R2、R3、R4 分离&#xff0c;整网采用了 …...

动态轮换代理IP是什么?有什么用?

如果您要处理多个在线帐户&#xff0c;选择正确的代理类型对于实现流畅的性能至关重要。但最适合这项工作的代理类型是什么&#xff1f; 为了更好地管理不同平台上的多个账户并优化成本&#xff0c;动态住宅代理IP通常作用在此。 一、什么是轮换代理&#xff1f; 轮换代理充当…...

MAC配置VScode中C++项目debug环境

文章目录 配置步骤问题解决Unable to start debugging. LLDB exited unexpectedly with exit code 137 (0x89). 配置步骤 在Mac上配置VS Code以进行C调试涉及几个步骤&#xff1a; 安装必要的工具: 确保您已经安装了Visual Studio Code和C插件。 检查是否安装了Clang&#xf…...

PostgreSQL源码分析——CREATE CAST

CREATE CAST源码分析 CREATE CAST用法 CREATE CAST —— 定义一个用户自定义的类型转换 用法如下&#xff1a; CREATE CAST (source_type AS target_type)WITH FUNCTION function_name [ (argument_type [, ...]) ][ AS ASSIGNMENT | AS IMPLICIT ]CREATE CAST (source_type…...

解锁5G新营销:视频短信的优势与全方位推广策略

随着5G时代的全面来临&#xff0c;企业的数字化转型步伐日益加快&#xff0c;视频短信作为新兴的数字营销工具&#xff0c;正逐步展现出其巨大的潜力。视频短信群发以其独特的形式和内容&#xff0c;将图片、文字、视频、声音融为一体&#xff0c;为用户带来全新的直观感受&…...

视频监控平台功能:国外的硬盘录像机NVR通过ISUP协议(原ehome协议)接入AS-V1000视频平台

目录 一、背景说明 二、ISUP协议介绍 1、海康ISUP协议概述 2、ISUP协议支持主码流和子码流切换 &#xff08;1&#xff09;灵活配置和个性化 &#xff08;2&#xff09;适应不同网络带宽&#xff0c;提高使用体验 3、海康ehome相关文章 三、ISUP协议接入说明 1、平台侧…...

javaweb可以做网站吗/品牌营销策划方案怎么做

1、打开激活窗口 2、选择 Activate new license with License server &#xff08;用license server 激活&#xff09; 3、在 License sever address 处填入 https://jetlicense.nss.im/ 4、点击 Activate 进行认证 还有一种方法比较麻烦&#xff0c;就不提及了...

搜索网站logo怎么做/优化排名工具

参考 《python machine learning》 代码读的很费劲&#xff0c;应该是没有功底的原因吧然后就挨个的百度不懂的函数&#xff0c;函数记录在了&#xff08;一&#xff09;中&#xff0c; 链接为 http://blog.csdn.net/Amy_mm/article/details/79625288 Iris数据集 以及源码 可…...

wordpress 多说 登陆/搜狗整站优化

题目传送门 开始就想直接正向跑一遍Dij把到各点的最短路加起来即可&#xff0c;后来发现与样例少了些&#xff0c;于是再读题发现需要也求出学生们回来的最短路。 但是注意到本题是有向图&#xff0c;如果是无向图就好说。 那么我们怎么解决&#xff1f;可以建一个反图。于是本…...

做外贸在哪个网站注册/seo全网优化推广

项目管理迁移到gradle已经用了大半年了&#xff0c;对so文件的添加了解的还不清楚&#xff0c;直到今天经过各种试验&#xff0c;总算是得出一些心得。因为项目需要集成喜马拉雅的SDK&#xff0c;他们提供了播放器的so库&#xff0c;按照他们的官方文档一步一步去集成&#xff…...

辽宁发布紧急通知/百度seo泛解析代发排名

1、ClickHouse监控概述 ClickHouse运行时会将一些个自身的运行状态记录到众多系统表中&#xff08;system.*&#xff09;。所以我们对CH自身的一些运行指标的监控数据&#xff0c;也主要来自这些系统表。 但是直接查询这些系统表会有一些不足之处&#xff1a; 这种方式太过底层…...

公司网站用wordpress/b2b平台网站

2013年3月计算机二级考试成绩查询时间和方式2013年3月NCRE考试成绩发布。考试成绩已陆续公布(不同地区公布成绩的时间将有所差异)。查分方法有从教育部考试中心综合查询网查询、各地区官方网站查询、各考点领取成绩单(部分省市)、拨打当地168信息台(部分省市)、短信查分(部分省…...