W25Q64CV SPI Flash Memory

SPI简介

SPI是一种同步串行通信接口规范,用于短距离通信,主要应用于嵌入式系统。SPI通信由一个主设备和一个或多个从设备组成,其中主设备生成时钟信号并控制通信的开始和结束。

SPI通信的基本组成

四个基本信号

SCK (Serial Clock) - 时钟信号,由主设备产生。
MOSI (Master Out Slave In) - 主设备输出,从设备输入的数据线。
MISO (Master In Slave Out) - 主设备输入,从设备输出的数据线。
CS (Chip Select) - 芯片选择信号,用于激活特定的从设备。

SPI操作模式

SPI有四种操作模式,由主设备产生的时钟信号的相位和极性决定:
模式0:CPOL = 0,CPHA = 0
模式1:CPOL = 0,CPHA = 1
模式2:CPOL = 1,CPHA = 0
模式3:CPOL = 1,CPHA = 1
其中,CPOL代表时钟的极性,CPHA代表时钟的相位。不同的模式会影响数据采样和设置的时间点。
1.Mode 0 (CPOL = 0, CPHA = 0)
时钟极性(CPOL):时钟信号的空闲状态为低电平。
时钟相位(CPHA):数据在时钟的上升沿被采样,并在下降沿改变。
特点:这是最常见的SPI模式。数据在第一个时钟脉冲的上升沿读取,之后每个时钟周期的上升沿都会读取新数据。
2. Mode 1 (CPOL = 0, CPHA = 1)
时钟极性(CPOL):时钟信号的空闲状态为低电平。
时钟相位(CPHA):数据在时钟的下降沿被采样,并在上升沿改变。
特点:与Mode 0相比,数据采样发生在时钟的下降沿。
3. Mode 2 (CPOL = 1, CPHA = 0)
时钟极性(CPOL):时钟信号的空闲状态为高电平。
时钟相位(CPHA):数据在时钟的上升沿被采样,并在下降沿改变。
特点:与Mode 0相比,时钟的空闲状态为高电平。
4. Mode 3 (CPOL = 1, CPHA = 1)
时钟极性(CPOL):时钟信号的空闲状态为高电平。
时钟相位(CPHA):数据在时钟的下降沿被采样,并在上升沿改变。
特点:这种模式下,时钟的空闲状态为高电平,数据采样在时钟的下降沿。

通信过程

初始化:主设备通过拉低CS信号来选择特定的从设备。
数据传输:主设备通过MOSI发送数据,并在同一时钟周期内通过MISO接收从设备的数据。
时钟同步:数据在时钟的上升沿或下降沿被采样,这取决于SPI的工作模式。

W25Q64简介

W25Q64CV是一款高性能SPI闪存芯片,具备64M位(8M字节)的存储容量,用于需要高速数据存储和读取的嵌入式系统。操作电压为2.7V至3.6V,提供工业级(-40°C至+85°C)和汽车级(-40°C至+105°C)的温度规格,具备软件和硬件写保护功能,支持安全启动和数据保护。

引脚

在这里插入图片描述
/CS: 芯片选择输入,用于激活或禁用设备
DO (IO1): 主设备输出,从设备输入的串行数据线
/WP (IO2): 写保护输入,可配置为输入/输出2
GND: 地
VCC: 电源
/HOLD (IO3): 保持输入,可配置为输入/输出3。允许系统在Flash设备正在被选中(即/CS为低电平)时,挂起或暂停当前正在进行的操作。当/HOLD引脚被释放(即拉高回到高电平)时,设备可以从之前挂起的地方恢复操作,无需重新开始整个操作流程
DI (IO0): 主设备输出,从设备输入的串行数据线
CLK: 串行时钟输入,控制数据传输的时序

存储

提供8M字节的存储空间,适用于存储大量数据和程序代码,存储阵列被组织成32,768个可编程页,每页256字节。页可以以16(4KB扇区擦除)、128(32KB块擦除)、256(64KB块擦除)或整个芯片(芯片擦除)的组进行擦除

SPI

支持SPI模式0和模式3,支持标准SPI、双SPI和四SPI操作,时钟频率高达80MHz,实现快速数据传输

指令

在这里插入图片描述

主要指令分类

制造商和设备识别指令:
用于读取制造商ID和设备ID,帮助用户确认连接的设备。
读指令:
包括普通读取(Read Data)、快速读取(Fast Read)、快速双输出读取(Fast Read Dual Output)等,用于从Flash中读取数据。
写指令:
包括页编程(Page Program)和四页编程(Quad Page Program),用于向Flash写入数据。
擦除指令:
包括扇区擦除(Sector Erase)、32KB块擦除(32KB Block Erase)、64KB块擦除(64KB Block Erase)和芯片擦除(Chip Erase),用于清除Flash中的存储空间。
状态寄存器指令:
包括读取状态寄存器(Read Status Register)和写状态寄存器(Write Status Register),用于监控和配置设备的状态。
安全和保护指令:
包括擦除安全寄存器(Erase Security Registers)和编程安全寄存器(Program Security Registers),用于管理设备的安全性。
特殊功能指令:
如设置突发(Set Burst with Wrap)、连续读取模式位(Continuous Read Mode Bits)、电源下降(Power-down)等。

指令执行流程

选中设备:通过拉低CS(Chip Select)引脚,选中目标Flash设备。
发送指令:通过DI(Data Input)或IO0(Data Input 0)引脚发送指令的操作码。
提供地址(如需要):某些指令,如读取、写入或擦除操作,需要用户提供24位的地址信息。
数据传输:根据指令的功能,进行数据的读取或写入。
等待完成:某些操作如擦除或编程可能需要一定的时间来完成,此时可以通过检查状态寄存器中的BUSY位来确定操作是否完成。
取消选中:操作完成后,通过拉高CS引脚取消选中设备

擦除

在闪存设备,包括W25Q64CV这样的SPI Flash Memory中,写入操作之前需要进行擦除,因为闪存是一种非易失性存储器,它使用浮栅晶体管来存储数据。每个浮栅晶体管可以表示两种状态:擦除状态和编程状态。擦除状态:在擦除状态下,浮栅中几乎没有电荷,晶体管的阈值电压较高,因此在读取操作时,晶体管不导电,表示数据"1"。编程状态:在编程状态下,浮栅捕获了电荷,降低了晶体管的阈值电压,使得在读取操作时晶体管导电,表示数据"0"。由于浮栅晶体管的设计,它们不能从"0"状态直接改为"1"状态,而是需要先擦除回到"1"状态,然后再编程为"0"。

擦除步骤

初始化:确保SPI接口已正确配置,并且W25Q64CV已选中。
写使能:发送06h指令以使能写操作。
执行擦除指令:根据需要执行扇区擦除、块擦除或芯片擦除的指令。
等待完成:擦除操作需要一定的时间来完成。可以通过检查状态寄存器中的BUSY位来确定擦除是否完成。

// 假设已经有了SPI通信的基础函数库:spi_begin(), spi_end(), spi_write(), spi_read()
// 以及控制CS引脚的函数:cs_select() 和 cs_deselect()// 擦除操作前的写使能函数
void spi_write_enable(void) {cs_select(); // 选中Flash设备spi_write(0x06); // 发送写使能指令cs_deselect(); // 取消选中设备
}// 扇区擦除函数
void spi_sector_erase(uint32_t address) {spi_write_enable(); // 使能写操作cs_select(); // 选中Flash设备spi_write(0x20); // 发送扇区擦除指令spi_write((address >> 16) & 0xFF); // 发送地址的高8位spi_write((address >> 8) & 0xFF);  // 发送地址的中8位spi_write(address & 0xFF);         // 发送地址的低8位cs_deselect(); // 取消选中设备spi_wait_until_ready(); // 等待擦除完成
}// 32KB块擦除函数
void spi_32kb_block_erase(uint32_t address) {spi_write_enable(); // 使能写操作cs_select(); // 选中Flash设备spi_write(0x52); // 发送32KB块擦除指令spi_write((address >> 16) & 0xFF); // 发送地址的高8位spi_write((address >> 8) & 0xFF);  // 发送地址的中8位spi_write(address & 0xFF);         // 发送地址的低8位cs_deselect(); // 取消选中设备spi_wait_until_ready(); // 等待擦除完成
}// 64KB块擦除函数
void spi_64kb_block_erase(uint32_t address) {spi_write_enable(); // 使能写操作cs_select(); // 选中Flash设备spi_write(0xD8); // 发送64KB块擦除指令spi_write((address >> 16) & 0xFF); // 发送地址的高8位spi_write((address >> 8) & 0xFF);  // 发送地址的中8位spi_write(address & 0xFF);         // 发送地址的低8位cs_deselect(); // 取消选中设备spi_wait_until_ready(); // 等待擦除完成
}// 芯片擦除函数
void spi_chip_erase(void) {spi_write_enable(); // 使能写操作cs_select(); // 选中Flash设备spi_write(0xC7); // 发送芯片擦除指令cs_deselect(); // 取消选中设备spi_wait_until_ready(); // 等待擦除完成
}// 等待设备准备就绪的函数
void spi_wait_until_ready(void) {// 这里应实现等待就绪的逻辑,可能通过检查状态寄存器的BUSY位// 例如:uint8_t status;do {cs_select();spi_write(0x05); // 发送读取状态寄存器1的指令status = spi_read(0xFF); // 读取状态寄存器1cs_deselect();} while ((status & 0x01) != 0); // 等待BUSY位清零
}

读写

写入步骤
写使能

选中设备:通过拉低CS(Chip Select)引脚,选中Flash设备
发送写使能指令:通过DI(Data Input)引脚发送06h指令码,使能写操作

页编程 (Page Program)

发送页编程指令:通过DI引脚发送02h指令码
提供地址:发送24位地址信息,指向要编程的起始位置
发送数据:顺序发送要写入的数据。W25Q64CV支持的数据长度从1字节到256字节
等待完成:等待编程操作完成。这可以通过轮询状态寄存器中的BUSY位来实现

// 检查设备是否忙碌的函数
uint8_t spi_check_busy(void) {uint8_t status;cs_select(); // 选中Flash设备spi_write(0x05); // 发送读取状态寄存器1的指令status = spi_read(0xFF); // 读取状态寄存器1cs_deselect(); // 取消选中设备return status;
}// 等待编程完成的函数
void spi_wait_until_ready(void) {while (spi_check_busy() & 0x01); // 检查BUSY位,如果为1则等待
}// 完整的编程函数,包括等待编程完成
void spi_flash_page_program(uint32_t address, const uint8_t *data, uint16_t dataSize) {cs_select(); // 选中Flash设备spi_write(0x06); // 发送写使能指令cs_deselect(); // 取消选中设备cs_select(); // 重新选中设备spi_write(0x02); // 发送页编程指令spi_write((address >> 16) & 0xFF); // 发送地址的高8位spi_write((address >> 8) & 0xFF);  // 发送地址的中8位spi_write(address & 0xFF);         // 发送地址的低8位for (int i = 0; i < dataSize; ++i) {spi_write(data[i]); // 发送数据}cs_deselect(); // 取消选中设备spi_wait_until_ready(); // 等待编程完成
}
读取步骤

选中设备:拉低CS引脚
发送读取数据指令:通过DI引脚发送03h指令码
提供地址:发送24位地址信息,指向要读取的起始位置
读取数据:数据将通过DO(Data Output)引脚顺序输出

void readData(uint32_t address, uint8_t *buffer, uint16_t dataSize) {cs_select();spi_write(0x03); // 发送读取数据指令spi_write(address >> 16); // 发送高8位地址spi_write(address >> 8);  // 发送中8位地址spi_write(address);       // 发送低8位地址for (int i = 0; i < dataSize; ++i) {buffer[i] = spi_read(0xFF); // 读取数据}cs_deselect();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/21140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7下安装MySQL,Oracle数据库

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 操作系统版本为CentOS 7 使⽤ MySQ…

python数据分析——datetime数据类型2

参考资料&#xff1a;活用pandas库 # 导入pandas库 import pandas as pd # 加载数据集 teslapd.read_csv(r"...\data\tesla_stock_yahoo.csv") # 查看数据 print(tesla.head()) 1、基于日期取数据子集 # 将Date数据列转换为datetime类型 tesla[Date]pd.to_datetime…

学习笔记——网络参考模型——TCP/IP模型(传输层)

四、TCP/IP模型-传输层 一、TCP 1、TCP定义 TCP(Transmission Control Protocol&#xff0c;传输控制协议)∶为应用程序提供可靠的面向连接的通信服务。目前&#xff0c;许多流行的应用程序都使用TCP。 连接&#xff1a;正式发送数据之前&#xff0c;提前建立好一种虚拟的&…

ES6-03-模版字符串、对象的简化写法

一、模版字符串 1-1、声明 反引号。 1-2、特性 1、字符串内容可以直接换行 得用号连接 2、变量拼接 现在&#xff1a; 二、对象的简化写法 ES6允许在大括号里面&#xff0c;直接写入变量和函数&#xff0c;作为对象的属性和方法。 let name milk;let chage function(){con…

脚本实现登陆滑块

脚本实现登陆滑块 仅供学习参考&#xff0c;简单操作 你知道吗&#xff0c;滑动验证码居然是为了验证人类比机器人蠢而设计的。 你以为自己快速、准确地滑动拼图、对齐图案&#xff0c;才被允许通过&#xff0c;系统还说你超越了99%的用户&#xff0c;夸你“比闪电还快”&am…

STM32_SPI

1、SPI简介 1.1 什么是SPI SPI&#xff0c;即Serial Peripheral Interface&#xff0c;串行外设接口。SPI是一种高速的、全双工、同步的串行通信总线&#xff1b;SPI采用主从方式工作&#xff0c;一般有一个主设备和一个或多个从设备&#xff1b;SPI需要至少4根线&#xff0c;…

FLINK-窗口算子

参考资料 官方文档- WindowFlink中的时间和窗口之窗口 窗口 在流处理中&#xff0c;我们往往需要面对的是连续不断、无休无止的无界流&#xff0c;不可能等到所有所有数据都到齐了才开始处理。所以聚合计算其实只能针对当前已有的数据——之后再有数据到来&#xff0c;就需要继…

chat4-Server端保存聊天消息到mysql

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程&#xff0c;此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…

JavaWeb_SpringBootWeb基础

先通过一个小练习简单了解以下SpringBootWeb。 小练习&#xff1a; 需求&#xff1a;使用SpringBoot开发一个Web应用&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串"Hello World~"。 步骤&#xff1a; 1.创建SpringBoot项目&#xff0c;勾选We…

epoll模型下的简易版code

epoll模型下的简易版code c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/epoll.h> #include <fcntl.h>#define MAX_EVENTS 10 #define NUM_DESCRIPTORS 5 // 模拟多个文件描述符// …

工具类解决事务和过滤器解决事务

事务的四大特性ACID 原子性&#xff1a;强调事务的不可分割.多条语句要么都成功&#xff0c;要么都失败。 一致性&#xff1a;强调的是事务的执行的前后&#xff0c;数据要保持一致 隔离性&#xff1a;并发访问数据库时,一个事务的执行不应该受到其他事务的干扰. 持久性&#…

测试:ollama加载羊驼版本llama-3中文大模型

找了一个晚上各种模型&#xff0c;像极了当初找各种操作系统的镜像&#xff0c;雨林木风&#xff0c;深蓝、老毛桃…… 主要是官方的默认7B版本回答好多英文&#xff0c;而且回复的很慢&#xff0c;所以我是在ollama上搜索"chinese"找到了这个羊驼版本的&#xff0c…

crossover软件是干什么的 crossover软件安装使用教程 crossover软件如何使用

CrossOver 以其出色的跨平台兼容性&#xff0c;让用户在Mac设备上轻松运行各种Windows软件&#xff0c;无需复杂的设置或额外的配置&#xff0c;支持多种语言&#xff0c;满足不同国家和地区用户的需求。 CrossOver 软件是干嘛的 使用CrossOver 不必购买Windows 授权&#xf…

Winform ListView 嵌入组合框、布尔、图片等复杂控件

一、Winform ListView 显示复杂控件示例 以下展示了两种实现思路方案。最后修改日期 2024-05 surfsky 1.1 方案一&#xff1a;ListView 结合组合框进行模拟编辑 基本思路 在界面上放置一个lisview和一个combobox&#xff0c;combobox平时是隐藏的。点击listview&#xff0c…

521源码-源码论坛-宝塔面板操作日志是存放在哪里的? 如何删除部分日志记录

我们帮别人搭建或者登录了&#xff08;不是自己权属的宝塔面板&#xff09;&#xff0c;会留下登录及操作的日志&#xff0c;我们不想留下这些操作日志&#xff0c;可以通过下面的方法处理掉&#xff0c;以达到无痕迹访问操作的目的&#xff1a; 如图所示的面板操作日志&#…

Python-3.12.0文档解读-内置函数sum()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 sum(iterable, /, start0) 参数&#xff1a; 返回值&#xff1a; 注意事…

排序方法大汇总

以下所有排序方法均以排升序为例 一.插入排序 1.直接插入排序 1>方法介绍&#xff1a;假定前n个数据有序&#xff0c;将第n1个数据依次与前n个数据相比&#xff0c;若比第i个数据小且比第i-1个数据大则插入两者之间 2>时间复杂度&#xff1a;O(N^2) 空间复杂度&#…

BUUCTF中的密码题目解密

BUUCTF 1.MD5 题目名称就是MD5&#xff0c;这个题目肯定和md5密码有关&#xff0c;下载题目&#xff0c;打开后发现这确实是一个md5加密的密文 Md5在线解密网站&#xff1a;md5在线解密破解,md5解密加密 经过MD5在线解密网站解密后&#xff0c;获取到flag为&#xff1a;flag{…

网络编程TCP

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:Java网络编程(下)&#x1f649; &#x1f439;今日诗词: 壮士当唱大风哥, 宵小之徒能几何&#xff1f;&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微…

CentOS7单用户模式,救援模式操作记录

CentOS7单用户模式&#xff0c;救援模式操作记录 1. 单用户模式 单用户模式进入不需要密码&#xff0c;无网络连接&#xff0c;拥有root权限&#xff0c;禁止远程登陆。一般用于用于系统维护&#xff0c;例如忘记root密码后可以通过进入单用户模式进行重置。 开机启动&#…